Commit Graph

371 Commits

Author SHA1 Message Date
e5d42e54fc feat: upgrade Firecrawl to v2 SDK and extract into the lfx-firecrawl extension bundle (#13495)
* Upgrade Firecrawl components to firecrawl-py v2 + add Search component

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

* Upgrade Firecrawl components to firecrawl-py v2 + add Search component

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

* Upgrade Firecrawl components to firecrawl-py v2 + add Search component

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

* Upgrade Firecrawl components to firecrawl-py v2 + add Search component

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

* Upgrade Firecrawl components to firecrawl-py v2 + add Search component

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

* Upgrade Firecrawl components to firecrawl-py v2 + add Search component

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

* Upgrade Firecrawl components to firecrawl-py v2 + add Search component

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

* docs: add Firecrawl Search API to the bundle page

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

* [autofix.ci] apply automated fixes

* fix(firecrawl): D205 docstring + defensive .get('data') in crawl

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

* fix(firecrawl): D205 docstring in scrape

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

* perf(firecrawl): use list.extend in map (PERF401)

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

* test: add unit tests for Firecrawl v2 components

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

* [autofix.ci] apply automated fixes

* test: align Firecrawl component tests with lfx _attributes pattern

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

* [autofix.ci] apply automated fixes

* refactor(firecrawl): remove deprecated extract endpoint component

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

* refactor(firecrawl): remove deprecated extract endpoint component

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

* test: drop extract component test (extract endpoint removed)

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

* docs: remove Firecrawl Extract API section (deprecated)

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

* [autofix.ci] apply automated fixes

* fix(firecrawl): map Search component to Firecrawl icon, drop Extract

The frontend icon map in styleUtils.ts still referenced the removed
FirecrawlExtractApi and lacked the new FirecrawlSearchApi, so the Search
node would not render the Firecrawl logo.

* chore: regenerate component index for Firecrawl v2 (Search added, Extract removed)

* refactor(firecrawl): extract components into the lfx-firecrawl extension bundle

Port the firecrawl provider out of lfx.components into a standalone
Extension Bundle at src/bundles/firecrawl (distribution: lfx-firecrawl),
following src/bundles/PORTING.md:

- Move the v2-SDK components (Scrape, Crawl, Map, Search) to
  src/bundles/firecrawl/src/lfx_firecrawl/components/firecrawl/ and
  remove the in-tree provider + its lfx.components registration.
- Own the firecrawl-py>=4,<5 pin in the bundle; drop it from
  langflow-base.
- Wire the workspace (root pyproject deps/sources/members) and uv.lock.
- Append migration-table entries (bare name, both import paths, pre-a
  slot) for the four classes; FirecrawlExtractApi gets no entries since
  the v2 SDK removed the extract endpoint and the component was dropped.
- Regenerate the component index (firecrawl category removed) and
  locales/en.json (54 firecrawl keys move out of core).
- Bundle-local unit tests + test_pilot_firecrawl_upgrade integration
  test; update Dockerfile bundle enumeration comments.

* fix(lfx): repair migration table entry fused during release-1.11.0 merge

The release-1.11.0 back-merge collided the FirecrawlSearchApi legacy_slot
entry with the NextPlaidVectorStoreComponent bare_class_name entry, mashing
both into a single object with duplicate 'target' keys, populating two of
{bare_class_name, import_path, legacy_slot}. That fails the MigrationTable
validator (entries.51) and broke the lfx loader tests.

Split it into the two intended entries so each populates exactly one
key-field. Restores the FirecrawlSearchApi and NextPlaidVectorStoreComponent
quads (60 entries total, +16 vs base). Append-only and bare-name guards pass.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
2026-06-17 12:55:01 +00:00
40d7814739 feat: New Bundle support for Multi-vector NextPLAID vector store (#13553)
* nextplaid integrate

* doc ids fix

* multivec fixes

* type check

* refactor: ship NextPlaid as the lfx-nextplaid extension bundle

Convert the in-tree NextPlaid vector store and its companion vLLM
multivector embeddings into a standalone `lfx-nextplaid` Extension Bundle,
following src/bundles/PORTING.md (cf. lfx-arxiv, lfx-ibm). The whole
feature now ships as an additive bundle with no core modifications.

- Move both components into src/bundles/nextplaid (components/nextplaid),
  dropping src/lfx/.../components/nextplaid and reverting the core vllm
  __init__ multivector additions.
- Bundle declares its own runtime deps (langchain-plaid, pillow) and ships
  extension.json + the langflow.extensions entry point.
- Add migration_table entries mapping the legacy class names / import
  paths to ext:nextplaid:*@official; wire the workspace (root pyproject,
  uv.lock).
- Add the pilot upgrade integration test and bundle-local unit tests.
- Declare explicit outputs on NextPlaidVectorStoreComponent so the
  extension validator can resolve its output methods.

* fix: address CodeRabbit review on NextPlaid bundle

- nextplaid: derive stable text IDs from source/page+content (not content
  alone) and fingerprint raw PIL images by bytes (not batch position) so
  ingests upsert instead of colliding/overwriting unrelated vectors
- vllm impl: validate the /pooling response envelope before nested indexing,
  raising a clear RuntimeError on malformed text/image responses
- icon: use the isDark boolean prop contract instead of the isdark string
- test: gate the distribution check on package presence (PackageNotFoundError)
  so genuine import failures surface instead of being skipped

---------

Co-authored-by: Meet <meet@dhcp-9-127-22-227.c4p-in.ibm.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
2026-06-16 16:00:26 +00:00
fb64e45e75 chore: bump version to 1.11.0 2026-06-09 13:29:01 -07:00
6610091697 fix(bundles): republish lfx-* at 0.1.1 with corrected pin + relax lfx floor for RC builds (#13542)
* fix(bundles): bump lfx-* bundles to 0.1.1 to republish with corrected lfx pin

The published 0.1.0 artifacts on PyPI carry stale lfx pins from before the lfx 0.5.0->1.10.0 version realignment:

- lfx-arxiv, lfx-duckduckgo: lfx>=0.5.0,<0.6.0 (hard-broken; the <0.6.0 cap can never resolve lfx 1.10.0)
- lfx-docling, lfx-ibm: lfx>=0.5.0 (uncapped floor/cap mismatch)

The source pin was already corrected to lfx>=1.10.0,<2.0.0 in #13516, but the bundles were never re-published. PyPI versions are immutable, so shipping the fix requires a version bump. Bump all four to 0.1.1 so the Release Bundles workflow cuts fresh wheels carrying the correct pin. Root pyproject keeps its >=0.1.0 floors (satisfied by 0.1.1); only the bundle dist versions and their uv.lock stamps change.

* fix(release): relax bundle lfx floor for pre-release builds + idempotent bundle publish

The RC pre-release run builds lfx as 1.10.0rc0, but bundles floor lfx at >=1.10.0. Under PEP 440 a pre-release sorts below the final, so 1.10.0rc0 fails >=1.10.0 and the cross-platform install test cannot resolve the bundle wheels against the RC lfx wheel.

build-base/build-main/build-lfx already rewrite their inter-package deps to the pre-release version when pre_release=true; build-bundles was the only release artifact missing that step. Add it: when pre_release=true, rewrite each bundle's lfx floor to the exact pre-release version, keeping the wide <2.0.0 BUNDLE_API cap. Stable source stays at >=1.10.0 -- only RC wheels are relaxed, at build time, so no source churn or re-tag.

Also make publish-bundles tolerate 'already exists' duplicate wheels on rerun, matching release_bundles.yml.
2026-06-08 13:18:56 -07:00
1ab6251164 feat: sync langflow and lfx versions (#13176)
* feat(lfx): synchronize LFX onto Langflow major.minor version line (Phase 1)

- Bump src/lfx/pyproject.toml from 0.5.0 to 1.10.0
- Tighten langflow-base lfx pin: ~=0.5.0 → ~=1.10.0
- Fix release.yml pre-release boundary from next-major to next-minor (<X.(Y+1).dev0)
- Add minor-parity soft check to scripts/release-lfx.sh
- Extend make patch to sync lfx version alongside langflow/base/frontend
- Document LFX compatibility contract in RELEASE.md

Contract: LFX X.Y.N is compatible with any Flow from Langflow X.Y.M.

* feat(lfx/upgrade): add compatibility checker (Phase 2)

* fix(lfx/upgrade): fix registry_code guard and types order-sensitivity in checker

* feat(lfx/upgrade): implement safe-upgrade applier (Phase 2)

* feat(lfx): add lfx upgrade command (Phase 2)

* feat(lfx/run): add --upgrade-flow option (Phase 2)

* feat(lfx/serve): add --upgrade-flow option (Phase 2)

* update lfx pyproject version

* [autofix.ci] apply automated fixes

* test(lfx/upgrade): add v1.9.0 starter flow fixtures for upgrade integration tests

* test(lfx/upgrade): add v1.9.0 starter flow fixtures and real-flow integration tests

* [autofix.ci] apply automated fixes

* fix(lfx/upgrade): use alias-aware registry lookup so renamed components are not falsely blocked

* fix(lfx/upgrade): handle outer flow envelope and file-path inputs in upgrade checks

* fix(lfx/upgrade): fail-fast on upgrade_flow errors; add regression tests for Bugs 1-3

* chore(tests): remove bug-number labels from test comments

* [autofix.ci] apply automated fixes

* fix(lfx/upgrade): address PR review comments

- Reject .py files early in serve --upgrade-flow with a clear error message
- Preserve outer flow envelope metadata (name, description, etc.) when lfx upgrade --write rewrites a file
- Move Mapping import under TYPE_CHECKING to satisfy Ruff TC003
- Assert fixture flows and registry are non-empty so parametrized tests cannot pass vacuously
- Remove unused capsys arg and replace print with sys.stderr.write (Ruff T201/ARG001)
- Add upgrade_flow param to run command docstring

* fix(lfx/upgrade): preserve envelope on run, apply nested upgrades (#13200)

* fix(lfx/upgrade): preserve envelope on run, apply nested upgrades

Three follow-ups on top of the upgrade tooling:

- run --upgrade-flow: re-attach the inner graph to the outer envelope before handing the flow to aload_flow_from_json. Previously the upgrade path unwrapped {"data": ...} and passed the inner dict to the loader, which raised KeyError: 'data'. Adds happy-path tests for envelope and flat file inputs.
- applier: recurse into one level of nested flow nodes (node.data.node.flow.data.nodes), matching the checker. Without this, outdated_safe nodes inside grouped components were reported but never written. Adds a regression test.
- upgrade --write test: assert the envelope is preserved (name, description, endpoint_name, etc.) instead of the previous unwrapped-output expectation, so the test matches the actual fix in this PR.
- Drive-by ruff cleanup: D417 docstring, SIM103, SIM108, E501, RUF059.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix(lfx/upgrade): fix loader KeyError, outer-envelope checker gap, and nested-node applier

Three bugs from ogabrielluiz's PR review:

1. run/base.py loader KeyError: file-path branch unwrapped the outer envelope
   for the checker but passed the inner dict to aload_flow_from_json, which does
   flow_graph["data"] unconditionally. Re-wrap as {"data": flow_dict} before the
   loader call. Applied consistently to all three input paths (--flow-json,
   --stdin, file-path).

2. run/base.py zero-node checker for --flow-json/--stdin: those paths stored the
   raw parsed JSON without unwrapping, so a caller passing an exported flow
   {"name":..., "data":{...}} caused the checker to see zero nodes and silently
   pass. Now unwrap with raw.get("data", raw) matching the file-path branch.

3. applier.py nested flows never upgraded: the early `continue` on top-level
   nodes not in safe_ids prevented the nested-node loop from running. Restructured
   so the nested check fires unconditionally for every top-level node, mirroring
   checker.py:160-165.

* fix(lfx/run): unify outer-envelope unwrap across all --upgrade-flow input paths

File-path reads now call raw.get("data", raw) matching --flow-json and
--stdin, so the upgrade checker always sees the inner graph. This also
removes the has_envelope/re-wrap machinery that was double-wrapping
outer-envelope files when passing to aload_flow_from_json.

Fix two test assertions that described the old double-wrapped shape.

* fix(lfx/upgrade): inject registry into upgrade_command; fix Makefile lfx pin regex

- upgrade_command now accepts an optional registry parameter so tests
  can pass the dict directly instead of mocking load_registry_from_index
- Makefile sed regex broadened from \"lfx~=.*\" to match both ~= and >=
  forms so make patch works after release.yml rewrites the pin
- Echo label changed to LFX (synced) to clarify the variable is the
  shared Langflow version, not a separate LFX-specific value

* fix(make/patch): fix langflow-base sed regex and validation grep

The dependency in pyproject.toml is "langflow-base[complete]>=X.Y.Z",
not the "langflow-base==X" form the original regex expected, so make
patch silently left the pin unchanged and the validation step always
failed. The sed pattern now matches any extras/operator combination and
rewrites to the canonical [complete]>= form; the grep uses -F so the
[complete] brackets are treated literally.

* test(lfx): add patch regex tests and symmetric safe-mode envelope tests

test_patch_regexes.py — 15 tests covering the Python regexes embedded in
the Makefile patch target. Exercises all three substitutions (langflow-base
pin, lfx pin, version field) against every realistic pin format including
the >=X.Y.Z,<dev0 form that release.yml writes. Would have caught the
langflow-base==.* vs [complete]>= mismatch before manual testing.

test_base.py — two new TestUpgradeFlowOption tests:
  test_upgrade_flow_safe_envelope_inline_json_loads_successfully
  test_upgrade_flow_safe_envelope_stdin_loads_successfully
Symmetric to the existing file-path envelope test; verifies that --flow-json
and --stdin with an outer-envelope flow also pass {"data": inner} to the
loader after safe upgrades, not a double-wrapped {"data": outer_envelope}.

* fix(lfx/upgrade): address review: compat checker, shared gate, fail-fast registry

Checker correctness:
- _outputs_are_compatible: drop cosmetic display_name from the breaking check;
  treat widened output types as safe (flow types must be a subset of registry
  types), only narrowing breaks downstream edges.
- _input_types_contained: stop flagging widened input_types as breaking; keep
  narrowing as the only breaking case; fix misleading comments.
- check_flow_compatibility now recurses fully into nested grouped components
  (symmetric with the applier) and accepts a pre-built registry lookup.

CLI/run/serve:
- New lfx.upgrade.cli_gate (UpgradeFlowMode enum, UpgradeFlowError,
  apply_upgrade_gate) shared by run_flow and serve_command so the two
  --upgrade-flow paths can't diverge.
- run_flow: extract _materialize_flow_dict and route gating through the shared
  helper.
- run/serve --upgrade-flow options typed as UpgradeFlowMode (check|safe choices).
- lfx upgrade: load_registry_from_index fails fast when the bundled registry is
  empty/missing instead of silently marking every node blocked; ASCII-only report
  output; new --strict flag; build the registry lookup once and reuse it.

Docs/tests:
- RELEASE.md: migration note for the lfx 0.5.0 -> 1.10.0 version jump.
- Regression tests for the checker fixes, the shared gate, fail-fast registry,
  --strict, and serve --upgrade-flow parity.

* [autofix.ci] apply automated fixes

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

* fix(lfx): consolidate flow-envelope handling and fix version-ceiling regex

Extract the outer-envelope unwrap/rewrap logic (previously hand-rolled as
raw.get("data", raw) with subtly different rules across serve, run, and
upgrade) into a single lfx.utils.flow_envelope module with split/merge
helpers. This fixes a serve bug where an enveloped flow had its inner graph
written bare to the temp file, making the loader's flow_graph["data"] raise
KeyError.

Also fix release.yml's major.minor extraction: the greedy sed grabbed the
upper bound from a range pin (>=1.10.0,<1.11.dev0), drifting the version
ceiling up one minor each release cycle. Anchor to the first version instead.

* fix(lfx): upgrade-flow gate reads bundled component index, not empty cache

The --upgrade-flow=check|safe gate on lfx run and lfx serve rejected every
flow as 'blocked'. Both call sites passed component_cache.all_types_dict to
apply_upgrade_gate, but that cache is populated lazily after services start,
so at gate time it is empty -- an empty registry classifies every node as
blocked. The standalone lfx upgrade command was unaffected because it reads
the bundled _assets/component_index.json instead.

Make the gate own registry loading: apply_upgrade_gate now defaults
all_types_dict to None and loads the bundled index (the same source lfx
upgrade uses) via a new _load_bundled_registry helper, raising
UpgradeFlowError on a missing/empty index so a broken install fails loudly
instead of silently blocking every component. Both call sites pass mode=
and let the gate load the registry.

Existing gate tests mocked component_cache with a populated registry, which
is exactly what hid the bug; repoint them at the new _load_bundled_registry
seam and add regression tests that do not mock the registry, including an
end-to-end run_flow check against a real clean v1.9.0 starter flow.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@logspace.ai>
2026-06-05 01:30:59 +00:00
3d685dab14 fix: enable agent-lifecycle-toolkit (altk) on Python 3.14 (#13513)
* fix: enable agent-lifecycle-toolkit (altk) on Python 3.14

agent-lifecycle-toolkit 0.10.x dropped its own requires-python <3.14
cap (now >=3.10) and does not depend on OpenDsStar, so the
`python_version < '3.14'` gate on the altk extra is stale.

- Remove the python_version < '3.14' marker from the altk extra in
  langflow-base, keeping the macOS x86_64 platform exclusion.
- Regenerate uv.lock: agent-lifecycle-toolkit resolves on 3.14 and
  coexists with the onnxruntime>=1.26 langflow forces there
  (verified agent-lifecycle-toolkit 0.10.1 + onnxruntime 1.26.0).

OpenDsStar (the separate OpenDsStarAgent component) stays gated: all
its releases still cap requires-python at <3.14 upstream.

* test: correct stale <3.14 comment in ALTK test import guards

The module-level import skips in the ALTK agent tests carried an
outdated comment claiming "agent-lifecycle-toolkit is gated to
python_version<'3.14' upstream". That is no longer accurate:
agent-lifecycle-toolkit 0.10.1 dropped the <3.14 cap (now requires
>=3.10), and this PR removes the langflow <3.14 marker on the altk extra.

The skip itself is preserved -- altk is an optional extra
(langflow-base[altk]) that may be absent from a given environment, so
the ImportError guard is still required. Only the comment is corrected,
to state the real reason for the skip plus the upstream change. Applied
to all four files carrying the identical comment (test_altk_agent,
test_altk_agent_logic, test_altk_agent_tool_conversion,
test_conversation_context_ordering).

Also tag a pre-existing fake test key (api_key="sk-test") with
`# pragma: allowlist secret`; the comment shift re-staged the file and
surfaced it to detect-secrets.

Validated (Python 3.13, altk installed): ruff clean; the three logic
modules run (64 passed, 4 skipped) and test_altk_agent collects (13).
2026-06-04 16:50:29 -07:00
09ae9cf0f2 fix: enable IBM watsonx.ai bundle on Python 3.14 (#13512)
* fix: enable IBM watsonx.ai bundle on Python 3.14

ibm-watsonx-ai (1.5.13) and langchain-ibm (1.1.0) added Python 3.14
support upstream on 2026-06-03, so the official 3.14 Docker image no
longer needs to silently drop the IBM integration.

- Lift the `python_version < '3.14'` markers on ibm-watsonx-ai and
  langchain-ibm in both the lfx-ibm bundle and langflow-base.
- Bump langchain-ibm from `~=1.0.2` to `~=1.1.0`; the 3.14-capable
  release is 1.1.0, which the old `~=1.0.2` pin excluded.
- Regenerate uv.lock: the resolver now forks ibm-watsonx-ai into
  1.5.13 for py>=3.11 (incl. 3.14) and 1.3.42 for py<3.11, so 3.10
  keeps working while 3.14 gains the integration.

watsonx-orchestrate (ibm-watsonx-orchestrate-core/clients) stays gated
at <3.14 since upstream 2.10.0 still caps there.

* test: stop import-skipping IBM watsonx tests on Python 3.14

The watsonx test modules skipped at module load (pytest.skip with
allow_module_level=True) when langchain-ibm / ibm-watsonx-ai failed to
import, with comments tying the skip to the upstream <3.14 cap. Now that
those deps are importable on 3.14 (this PR's dep bump), the import-based
skip can hide real import regressions instead of surfacing them.

- test_model_utils.py, test_watsonx.py, test_watsonx_embeddings.py:
  replace the try/except pytest.skip(allow_module_level=True) guards with
  direct top-level imports so a missing or broken IBM SDK fails loudly.
  Drop the now-unused `import pytest` in test_model_utils.py.
- src/bundles/ibm/README.md: update the platform note to reflect that the
  watsonx components are now importable on Python 3.10-3.14.

The Db2 tests (test_db2*, test_optional_dependency) are left untouched --
they gate on ibm-db's linux/aarch64 platform exclusion, not the Python
version, which is still valid.

Validated locally (Python 3.13): 63 tests pass (13 + 50), ruff clean.
2026-06-04 15:47:28 -07:00
f76d3e22dd feat: Add IP-based rate limiting to login endpoint (#13469)
* feat(security): add failed login logging with IP tracking and comprehensive tests

* fix: remove PII from login logs and fix structlog format

* docs: agent improvements (#13269)

* docs: add structured output for agents

* docs: add structured output note

* docs: clarify both agent outputs and add release notes

* docs: when langflow sends events to the playground and chat history

* fix(playground): expand session checkbox click target to full row height (#13349)

* fix(playground): expand session checkbox click target to full row height

The selectable-row checkbox wrapper was ``w-4 h-4`` (16x16 px) but the
row is ``h-8`` (32 px). The 8 px band above and the 8 px band below
the visible icon were dead zones that bubbled to the row's
``toggleVisibility`` and navigated to the session instead of toggling
selection — exactly the accidental-navigation UX the bug ticket
describes.

Grow the wrapper to ``w-4 h-8`` so the click target captures the full
row height. Width stays narrow so the text alignment is unchanged; the
icon itself stays ``h-4 w-4``, centered via the existing
``flex items-center justify-center``. Visual position is identical.

Adds ``__tests__/session-selector-checkbox-click-target.test.tsx``
(3 cases): wrapper className guard (h-8 + w-4, not h-4), click on the
wrapper outside the icon triggers selection without bubbling to
toggleVisibility, and click on the inner icon still toggles selection.

* test(playground): drop checkbox-click-target test file (not needed per review)

* [autofix.ci] apply automated fixes

* test: align session-selector checkbox assertions with full-height click target

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: improve trace search functionality (#13383)

* improve trace search functionality

* [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>

* test: fix test_login_logs_real_output_format to use mocking

- Updated test to use patch() instead of capsys for consistency
- Verifies structlog kwargs format (not nested extra dict)
- All 7 login logging tests now passing

* feat: Add IP-based rate limiting to login endpoint

- Add slowapi dependency for rate limiting functionality
- Implement rate limiting service with configurable limits
- Apply rate limiter to /login endpoint (default: 5 attempts/minute per IP)
- Add custom exception handler for rate limit exceeded (HTTP 429)
- Support both in-memory (default) and Redis storage backends
- Add comprehensive test suite with 100% coverage
- Document configuration in .env.example

Security improvements:
- Prevents brute force attacks on login endpoint
- Structured logging without PII (logs client_ip, not user data)
- Graceful degradation with swallow_errors=True
- Proper X-Forwarded-For header handling for proxied requests

Configuration:
- LANGFLOW_RATE_LIMIT_PER_MINUTE: requests per minute (default: 5)
- LANGFLOW_RATE_LIMIT_STORAGE: storage backend (default: memory://)
- LANGFLOW_RATE_LIMIT_HEADERS_ENABLED: enable rate limit headers (default: false)

* security: add proxy-aware IP extraction for rate limiting

- Add LANGFLOW_RATE_LIMIT_TRUST_PROXY configuration
- Default to secure get_remote_address (prevents header spoofing)
- Enable get_client_ip when behind trusted proxies
- Add comprehensive tests for both configurations
- Maintain 100% test coverage (15 tests passing)

* refactor(rate-limit): address PR review feedback - migrate to Settings model, fix IP security, add test coverage

* fix: disable rate limiting in tests to prevent 429 errors

- Add LANGFLOW_RATE_LIMIT_ENABLED environment variable control
- Disable rate limiting by default in tests via session-scoped fixture
- Rate limit tests explicitly enable it via function-scoped fixture
- Fixes test failures caused by sequential login attempts hitting 5/min limit

* fix: refactor login rate limiting to avoid settings initialization race condition

---------

Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
Co-authored-by: keval shah <kevalvirat@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: olayinkaadelakun <olayinka.adelakun@ibm.com>
Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
2026-06-04 12:42:34 +00:00
ec0b11d721 chore: update lock files (#13483)
* chore: update lock files

update lock files

* fix: migrate Mongo/Weaviate/Perplexity components off removed langchain-community classes

langchain-community 0.4.2 (pulled in by the lock update) removed the
MongoDBAtlasVectorSearch and Weaviate vector stores and the ChatPerplexity
chat model. The MongoDB import failed at test collection, aborting both
backend unit-test groups with an ImportError.

Migrate to the standalone packages, all already declared dependencies:
- mongodb: langchain_mongodb.MongoDBAtlasVectorSearch (drop-in)
- perplexity: langchain_perplexity.ChatPerplexity (drop-in)
- weaviate: rewrite for weaviate-client v4 (connect_to_weaviate_cloud /
  connect_to_custom) + langchain_weaviate.WeaviateVectorStore, adding
  advanced gRPC host/port inputs. The component was already broken on
  weaviate-client v4, which removed the v3 weaviate.Client(url=...) API.

Component class names and identifiers are unchanged, so existing flows are
preserved. The component index is left for the autofix CI job to regenerate.

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

* ci: wake up CI

Co-Authored-By: Oz <oz-agent@warp.dev>

* test: fix concurrent-import deadlock in test_all_modules_importable

test_all_lfx_component_modules_directly_importable imports ~488 modules
concurrently via asyncio.gather over asyncio.to_thread(importlib.import_module).
It flaked ~50% with:

  _DeadlockError: deadlock detected by _ModuleLock('toolguard.runtime.runtime')
  on lfx.components.models_and_agents.policies.tool_invoker

toolguard has an internal circular import: toolguard/runtime/__init__.py does
`from .runtime import ...` while runtime.py does `from toolguard.runtime import
IToolInvoker`. It resolves fine single-threaded, but the lfx policy modules reach
the cycle from two entry points at once -- policies.tool_invoker enters at the
toolguard.runtime package while policies.guard_sync_utils enters at the
toolguard.runtime.runtime submodule. On separate worker threads one holds the
package lock waiting on the submodule lock while the other does the reverse, so
CPython's import machinery raises _DeadlockError.

Pre-import both entry points single-threaded before the fan-out so sys.modules is
warm and the threaded imports only hit the cache. Keeps full parallelism and
coverage (every module is still imported; no skip-list entry).

Verified 24/24 green vs a 4/8 baseline.

* add tests

* pragma

* Update component_index.json

* [autofix.ci] apply automated fixes

* test: fix dropdownComponent fixture import for langchain-community 0.4.2

The dropdownComponent Playwright test pastes component code into the code editor and clicks "Check & Save", which validates the code by importing it. langchain-community 0.4.2 (this branch's lock bump) removed `langchain_community.chat_models.bedrock`, so the import threw, the code modal stayed open, and enableInspectPanel timed out clicking `canvas_controls_dropdown_help` through the open dialog. Failed deterministically (all retries + GHA re-run), only on this branch.

Swap the fixture to `langchain_aws.ChatBedrock`, matching the real Amazon Bedrock component which already migrated, and upstream guidance (BedrockChat deprecated since lc 0.0.34).

Also move the 0.4.2-removed `langchain_community.chat_models.litellm` import off the top level of the deactivated ChatLiteLLM component into build_model so the module imports cleanly. No loaded/product components affected.

* [autofix.ci] apply automated fixes

* chore: update pandas and numexpr

* Update component_index.json

* chore: update templates

---------

Co-authored-by: Eric Hare <ericrhare@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Oz <oz-agent@warp.dev>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-03 17:07:34 -04:00
f2d49e5098 fix: tidy up docling extra reqs 2026-06-02 18:20:14 -07:00
5120b7705a fix: Move Docling components into bundle (#13442)
* feat: move docling components to bundle

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

* chore: wake CI

* fix: trim docling chunking extra

* Update test_endpoints.py

* Update test_pilot_docling_upgrade.py

* fix: show friendly component label in build banner for bundle nodes

Extension-bundle components have namespaced node ids of the form ext:<bundle>:<ClassName>@<slot>-<uuid>. The flow-build status banner rendered that raw id, which overflowed the fixed-width (530px) container and collided with the elapsed-time counter.

Collapse namespaced ids to <ComponentName>-<uuid> (matching the built-in ComponentName-UUID label) via a new getRunningNodeLabel helper; built-in node ids are returned unchanged. Covered by unit tests.

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-06-02 12:33:38 -07:00
aa931407da Update uv.lock 2026-06-02 10:03:04 -07:00
f8ada15e2a feat(components): Add IBM DB2 Vector Store component (#13237)
* feat(ibm): add DB2 Vector Store component

Add comprehensive IBM DB2 Vector Store integration for Langflow.

Components Added:
- DB2VectorStoreComponent: Main vector store component
- DB2VS: LangChain-compatible vector store implementation
- DB2 security validators: Input validation and sanitization

Features:
- Vector similarity search (Similarity, MMR, Similarity Score Threshold)
- Secure connection handling with input validation
- Metadata filtering for complex data types
- Duplicate detection support
- Batch document ingestion

Test Coverage:
- 41 unit tests (38 passing, 3 skipped)
- Component integration tests
- Security validation tests
- DB2VS class tests

Documentation:
- Comprehensive developer guidelines

* refactor(db2): simplify component to match Chroma patterns

- Remove complex data ingestion (CSV, DataFrame, dict, Message handling)
- Add _add_documents_to_vector_store() method matching Chroma
- Add similarity_score_threshold search type
- Simplify data ingestion from 220 to 45 lines (80% reduction)
- Add 5 new tests (similarity_search, mmr_search, search_with_different_types, duplicate_handling, metadata_filtering)
- All 41 tests passing (38 passed, 3 skipped)

BREAKING CHANGE: Component now only accepts Data objects for ingestion.

* ci: fix CI failures - update component index and starter projects

- Regenerate component_index.json with DB2 component
- Update all starter projects with new component registry
- Fix ruff formatting issues

* ci: trigger CI re-run to fix merge issue

* ci: add merge conflict resolution for component_index.json in autofix workflow

Handle merge conflicts in the Update Component Index job by:
- Automatically resolving component_index.json conflicts using --theirs strategy
- Failing if non-generated files have conflicts (requires manual resolution)
- Completing the merge after resolving generated file conflicts

This prevents the workflow from failing when component_index.json has conflicts
during PR updates, as this file is auto-generated and can be safely regenerated.

* fix: Remove DB2SQLComponent reference from IBM components

- Removed DB2SQLComponent from __init__.py as the db2_sql.py module doesn't exist
- This fixes the test_all_modules_importable test failure
- Fixes CI failure in Unit Tests - Python 3.14 - Group 5

* revert: Remove unrelated starter project JSON changes

* revert: Remove unrelated CI workflow and formatting changes

* docs: add DB2 Vector Store .mdx documentation following Chroma DB structure

* fix: address CodeRabbit review comments - add __init__.py docstring and implement score threshold filtering

- Added docstring to src/backend/tests/unit/components/__init__.py to fix Ruff INP001 error
- Added FloatInput score_threshold parameter (default 0.5) to DB2 Vector Store component
- Implemented threshold filtering in similarity_score_threshold search mode
- Filters results to only include documents with relevance scores >= threshold

* chore: remove auto-generated and unnecessary files from PR

- Remove uv.lock (dependency lock file - auto-generated)
- Remove src/frontend/package-lock.json (frontend lock file - auto-generated)
- Remove src/lfx/src/lfx/_assets/component_index.json (auto-generated by CI)
- Remove .secrets.baseline (security baseline - auto-generated)
- Remove starter_projects JSON (auto-generated example)
- Remove tweaks_builder.py (unrelated test helper)

Per DEVELOPMENT.md guidelines, these files should not be committed by contributors.

* chore: restore auto-generated files to keep PR focused on DB2 component

* fix(ci): update auto-generated files and fix docs build

- Update component index with new IBM DB2 components (363 components, 97 modules)
- Update frontend package-lock.json
- Fix docs build by removing reference to missing image in bundles-db2.mdx

Fixes CI failures:
- Update Component Index
- Update Starter Projects
- Test Docs Build

* feat(db2): add SSL/TLS support to DB2 Vector Store component

- Add SSL/TLS encryption support for DB2 database connections
- Add SSL certificate validation and download functionality
- Support local certificate files (.crt, .pem, .cer) and URLs
- Add optional certificate password support for encrypted keystores
- Implement automatic cleanup of temporary downloaded certificates
- Add comprehensive error handling and logging for SSL connections
- Update component_index.json with new SSL configuration inputs
- Update package-lock.json dependencies

Security improvements:
- Validate certificate paths and file permissions
- Support system default CA certificates (recommended for IBM Cloud DB2)
- Redact sensitive information in error messages
- Clean up temporary files on connection failure

This enhancement enables secure encrypted connections to DB2 databases,
which is recommended for production environments.

* [autofix.ci] apply automated fixes

* refactor(db2): minimize metadata storage in DB2 vector store

- Clear metadata before storage to reduce unnecessary data (file_path, filename, etc.)
- Return only text content during retrieval for cleaner results
- Optimize list comprehension for better performance (PERF401, RET504)

* test: remove skipped tests from DB2 vector store test suite

- Removed version compatibility tests for versions where component didn't exist
- Changed file_names_mapping to return empty list for new component
- Overrode base class version tests to prevent skips
- Fixed linting issues (hardcoded passwords, nested with statements)
- All 40 tests now pass with 0 skipped tests

* fix(tests): update DB2 vector store test description format

Fixes test_component_metadata assertion to match the actual component
description format. The test was failing due to line wrapping differences
in the multi-line description string.

Fixes CI failure in PR #13163

* [autofix.ci] apply automated fixes

* chore: trigger CI re-run to resolve flaky test failures

* fix(tests): mark OpenAI-dependent test as api_key_required to prevent CI failures

* restructure as new bundle package

* [autofix.ci] apply automated fixes

* fix(ibm): improve DB2 Vector Store component reliability and validation

* fix: implement SSL/TLS toggle functionality for DB2 Vector Store

- Add update_build_config method to dynamically show/hide SSL certificate fields
- SSL certificate path and password fields now only visible when use_ssl is enabled
- Improves UX by hiding irrelevant fields when SSL is disabled
- Update component_index.json with new component configuration
- All 38 existing tests pass

---------

Co-authored-by: Dhruv Chaturvedi <dhruv_insights@mac.lkw-in.ibm.com>
Co-authored-by: Dhruv Chaturvedi <dhruv_insights@Dhruvs-MacBook-Pro.local>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: priyanshu-krishnan1 <priyanshu.krishnan1@ibm.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
2026-05-29 02:58:30 +00:00
6b2ca4bcd8 fix: restore qdrant deps and migration workflow 2026-05-27 20:09:57 -07:00
b95d309c46 fix(tracing): surface Langfuse setup failures, pin pydantic>=2.13 (Py3.14) (#13341)
* fix(tracing): surface Langfuse setup failures and pin pydantic>=2.13 for Py3.14

Docker v1.9.3 silently dropped Langfuse traces because the Docker image
was bumped to Python 3.14 while the lockfile still resolved pydantic
2.12.x. Langfuse v3 imports `pydantic.v1.BaseModel`, which only gained
Python 3.14 support in pydantic 2.13. On the user's Docker container,
`from langfuse import Langfuse` raised `pydantic.v1.errors.ConfigError`,
the broad `except Exception` in `_setup_langfuse` logged at debug level,
and the tracer initialized with `_ready = False` — no error in default
logs, no traces in Langfuse. PyPI installs worked because users tend to
run Python 3.10-3.13 where pydantic.v1 is still happy.

Two changes:

- Replace `logger.debug` with `logger.warning`/`logger.exception` in
  `_setup_langfuse` so future failures (network, auth, dependency
  conflicts) surface in logs by default instead of vanishing silently.
- Add `pydantic>=2.13.0` to the `langfuse` extra in
  `src/backend/base/pyproject.toml` so the Python 3.14 import path is
  guaranteed to work whenever the extra is installed, regardless of
  what other deps resolve transitively.

Adds regression tests asserting `_setup_langfuse` calls
`logger.warning`/`logger.exception` on the three failure modes
(auth check returning False, auth check raising, post-auth setup
exception).

Fixes #13317

* [autofix.ci] apply automated fixes

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

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-26 20:31:44 +00:00
68d4e8488e fix: update mem0 and qdrant dependencies (#13292)
* fix: update mem0 and qdrant dependencies

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-22 18:06:03 +00:00
81672ef849 fix: upgrade litellm to 1.85.1 (#13272) 2026-05-21 20:26:49 +00:00
23f2edf327 chore: Clean up the startup warnings for Python 3.14 (#13156)
* fix: backport policies ToolGuard lazy imports (#13144)

fix: backport policies toolguard lazy imports

* chore: Clean up the startup warnings for Python 3.14

* Update base.py

* Update component_index.json

* [autofix.ci] apply automated fixes

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

* Update component_index.json

* [autofix.ci] apply automated fixes

* Update Structured Data Analysis Agent.json

* [autofix.ci] apply automated fixes

* Update component_index.json

* [autofix.ci] apply automated fixes

* Update component_index.json

* Update starter projects

* Update .secrets.baseline

* [autofix.ci] apply automated fixes

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

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-18 16:52:13 -07:00
e08080507b feat: Add langflow-stepflow package (#12015)
* feat: Add langflow-stepflow package

Introduces a new workspace package `src/langflow-stepflow/` that ports
the Stepflow integration from the Stepflow repository into the Langflow
codebase.

The package has two submodules:
- `translation/`: translates Langflow flow JSON to Stepflow flow
  definitions (ported from integrations/langflow/converter/)
- `worker/`: a Stepflow worker that executes individual Langflow
  components via lfx (ported from integrations/langflow/executor/)

Entry point: `python -m langflow_stepflow.worker` starts the HTTP worker
server for use by a Stepflow orchestrator.

No changes to existing Langflow code in this commit.

* fix: Address review feedback on langflow-stepflow package

- Widen Python version to >=3.10,<3.14 to match langflow-base
- Fix import sorting (ruff I001) and unused variable (ruff F841)
- Replace sk- prefixed test strings to avoid Gitleaks false positives
- Remove placeholder step reference resolution in component_tool
  (orchestrator resolves these before reaching the worker)
- Let exceptions propagate from component_tool_executor instead of
  returning error dicts that look like successful results
- Skip secret/password field defaults in tool input schemas
- Use LRU-style bounded cache (128) for compiled components
- Use asyncio.to_thread for sync component methods to avoid blocking
- Fix mutable NamedTuple default (list→tuple) in PlaceholderGraph
- Warn and skip deps with missing field mappings instead of silently
  falling back to "input" (which overwrites on multiple deps)
- Tighten _is_data_list to check __class_name__ == "Data" specifically
- Add comment explaining intentional teardown-before-init sequence
- Add integration test for example flows

* chore: Upgrade to Stepflow SDK 0.12.0 and adapt to lfx 0.3+ renames

- Bump stepflow-py and stepflow-orchestrator from >=0.10.0 to >=0.12.0
- Remove Python 3.11 environment markers (SDK now supports 3.10+)
- Replace server.run() with gRPC pull transport (run_grpc_worker)
  matching the upstream stepflow-langflow integration pattern
- Update Flow serialization from Pydantic model_dump to msgspec.to_builtins
- Remove Pydantic ValueExpr/actual_instance unwrapping (now plain dicts)
- Add _langflow_type_name() to map lfx 0.3+ class renames (JSON→Data,
  Table→DataFrame) back to canonical Langflow type names
- Fix DataFrame isinstance checks for lfx Table subclass
- Add missing README.md, tests/__init__.py, helpers package
- Add skip conditions for missing fixture files

* change to lfx schema

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* chore: Align langflow-stepflow ruff config with repo and format

- Set line-length = 120 to match root pyproject.toml (was 88, causing
  conflicts between pre-commit format hook and check hook)
- Run ruff format across all source and test files
- Add pragma: allowlist secret on test fixtures with fake API keys

* [autofix.ci] apply automated fixes

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

* chore: Rebuild component index

* [autofix.ci] apply automated fixes

* fix(langflow-stepflow): allow Python 3.14 in requires-python

Lift requires-python from <3.14 to <3.15 to match the rest of the
workspace and the lockfile. Without this, uv sync on Python 3.14
fails the Unit/LFX/Integration test jobs and the Docker build.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: ogabrielluiz <gabriel@langflow.org>
Co-authored-by: Jordan Frazier <jordan.frazier@datastax.com>
2026-05-18 21:47:20 +00:00
cc009c9133 feat(lfx): Bundle Separation and LFX Extension Framework (#13043)
* feat(lfx): installed-package + seed-directory discovery for production install (LE-1022)

Adds the read-only production install path for Modes A, B, and C of the
Bundle Separation iteration. Manifest-shipping pip-installed
distributions and seed-directory subdirectories are discovered at server
startup and registered as Extensions at @official.

* discovery.py: walks importlib.metadata.distributions() + the
  $LANGFLOW_SEED_DIR / /opt/langflow/bundles seed root; produces
  DiscoveredExtension records and typed errors for malformed manifests
  / configured-but-missing seed dirs.
* registry.py: ExtensionRegistry service with the immutability
  invariant for installed and seed entries. Mutation verbs (uninstall,
  disable, enable, install, update_entry) all raise
  ExtensionImmutableError carrying the typed
  installed-extension-immutable / seed-directory-immutable code so the
  invariant is testable today; the CLI uninstall surface ships in B4.
* lfx extension list: read-only inspector with text and JSON output
  for operators inspecting Mode B/C images.
* Errors: four new typed codes
  (installed-extension-immutable, seed-directory-immutable,
  seed-directory-not-found, duplicate-extension-id) plus snapshot
  coverage in tests/unit/extension/test_errors.py.
* Tests: 165 extension tests pass, including the LE-1022 acceptance
  cases -- three pip-installed wheels visible at @official, three seed
  bundles visible at @official, and the parametrized service-layer
  immutability check across every mutation verb.
* Docs: docs/Deployment/deployment-extensions-production.mdx covers
  the Dockerfile template, k8s deployment notes, the bundle packaging
  convention (extension.json shipped via package-data), and
  troubleshooting for the typed error codes.

* feat(lfx): add single-Bundle loader and LANGFLOW_COMPONENTS_PATH discovery (#12967)

* 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>

* feat(lfx): add single-Bundle loader and LANGFLOW_COMPONENTS_PATH discovery (LE-1015)

Introduces lfx.extension.loader: the runtime that turns an Extension on disk
into LoadedComponent records keyed by ext:<bundle>:<Class>@<slot>. Two paths in:

  - load_extension(root): one manifest, one Bundle, registered at @official.
    Re-checks multi-bundle at runtime (defense-in-depth vs. the schema).
  - discover_inline_bundles(paths): each subfolder of LANGFLOW_COMPONENTS_PATH
    is a Bundle at @extra. Walk order is platform-independent (sorted dirs,
    user-declared path order). First-wins on duplicate names; second emits
    duplicate-inline-bundle warning that names both paths.

Manifest-first precedence helpers (installed_extension_roots,
manifest_owning_distributions, filter_plugin_entry_points) let callers of
the legacy langflow.plugins entry-point loader skip distributions that ship
a manifest, so component entry-points are not double-registered.

New typed error codes: module-import-failed, duplicate-component-name,
duplicate-distribution, duplicate-inline-bundle, inline-bundle-name-invalid.
Each ships with a format branch and a snapshot test.

Tests cover the AC: single-bundle happy path, multi-bundle rejection,
missing/empty/no-Component bundle, duplicate class names, deterministic
walk order, recursive discovery, inline-bundle first-wins + dot-dir skip
+ bundle.json metadata, manifest-first precedence partition, PEP-503
distribution-name canonicalization.

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

* fix(lfx): address LE-1015 review feedback

- Drop the unproduced duplicate-distribution error code; LE-1022 will add
  it once startup-time discovery has a place to surface it.  Restores the
  invariant that every code in ERROR_CODES has a producer.
- Clarify that intra-bundle relative imports are NOT supported in v0; only
  absolute references between bundle modules work in this milestone.
- Use strict=False when re-resolving bundle_root in the walker; the path
  was already existence-checked, and a concurrent removal in the narrow
  window should not raise across the loader's public boundary.
- Hoist the json import out of _read_inline_bundle_json's body.

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

* refactor(lfx): split extension loader into a small subpackage (LE-1015)

Addresses the file-size feedback from the LE-1015 review.  The single
870-line loader.py becomes a flat package keyed off the four section
banners that already existed inline:

    loader/
      __init__.py     # re-exports the public surface
      _types.py       # SLOT constants, LoadedComponent, LoadResult
      _discovery.py   # filesystem walk + importlib.util orchestration
      _detection.py   # Component subclass identification (MRO heuristic)
      _orchestrator.py # load_extension, discover_inline_bundles
      _plugins.py     # manifest-first precedence over langflow.plugins

Largest file is now _orchestrator.py at 440 LOC (was 870); every file is
well under the 800-LOC project guideline.  No behavior change: the public
import paths from lfx.extension are unchanged, all 38 loader tests still
pass.  ``_canonicalize_distribution`` is now exported as
``canonicalize_distribution`` from ``loader._plugins`` (it's a stable
PEP-503 helper that downstream modules will reach for, so it loses the
private underscore).

The test suite is split to mirror the package:

    tests/unit/extension/loader/
      conftest.py             # shared fixtures, FakeDist, autouse scrub
      test_load_extension.py  # @official slot, identity, failure modes
      test_inline_bundles.py  # LANGFLOW_COMPONENTS_PATH, @extra slot
      test_plugins.py         # manifest-first precedence helpers
      test_types.py           # LoadedComponent, LoadResult, code parity

Each test file imports its own slice of the public API and pulls fixtures
from conftest, so a reader looking at one banner can read it in isolation.

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

* fix: LangflowCompat -> LfxCompat

* fix: Remove references to ticket

* fix: encode maxItems constraint in schema

* fix: deferred fields and schema version

* Fix ruff errors

* fix: align loader tests with renamed manifest API and strip ticket refs

The merge of feat/extension-validate brought in the LfxCompat / compat
rename, but the loader test fixtures still used LangflowCompat / bundle_api
and failed at the manifest layer. Update conftest.py + test_load_extension.py
to the post-rename API.

Strip 17 LE-XXXX ticket references from loader source files, errors.py
loader-specific comments, and the four loader test docstrings, matching the
convention applied to LE-1014. Descriptive prose preserved.

Promote _BUNDLE_NAME_RE to BUNDLE_NAME_RE on the manifest module so the
loader's orchestrator no longer reaches across modules into a private name.

* refactor(lfx): clarify broad except, log malformed bundle.json, expand test docstring

- Document why _discovery.import_bundle_module catches BaseException (startup-time loader, must surface bad bundles as typed errors rather than abort).
- Add debug-level logging when bundle.json is malformed or non-object so a stale-cache footgun is at least observable.
- Expand test_skips_re_imported_class docstring so future maintainers don't accidentally weaken the __module__-equality guard if package-style relative imports get added later.

Also drops the stale duplicate-distribution claim from the PR description; that code is correctly deferred to LE-1022 along with /all integration.

* feat(lfx): wire Extension System into /all, pathsep-split LANGFLOW_COMPONENTS_PATH, emit duplicate-distribution

Closes the four AC gaps the previous reviewer flagged on PR #12967:

1. /all integration: get_and_cache_all_types_dict now also calls a new
   import_extension_components() that loads installed Extensions via
   load_installed_extensions, loads inline bundles via discover_inline_bundles,
   and builds frontend-node templates with extension/bundle/extension_version
   fields stamped on. Failures are logged and skipped per bundle.

2. LANGFLOW_COMPONENTS_PATH is now split on os.pathsep so multi-entry env vars
   (e.g. /a:/b on POSIX) produce multiple components-path entries instead of
   one literal non-existent path. Empty segments and missing paths are skipped.

3. duplicate-distribution is a real producer: load_installed_extensions
   surfaces a typed warning on the winner LoadResult when two distributions
   share a canonical name, naming every involved manifest path.

4. Manifest-first precedence runtime wiring: new filter_component_entry_points
   loads each entry-point and only skips ones that resolve to a Component
   subclass on a manifest-shipping distribution. plugin_routes.load_plugin_routes
   now applies it so non-component entry-points (route registrars) keep
   loading per the AC's 'unaffected' promise. Added the previously-missing
   AC test for same-distribution component+non-component partition.

Also makes _distribution_canonical_name defensive against MagicMock test seams.

* fix(lfx): register extension components under namespaced ID; promote duplicate-distribution to error

Addresses the latest review of PR #12967:

P1: /all integration now keys the cache inner dict by LoadedComponent.namespaced_id
(ext:<bundle>:<Class>@<slot>) rather than the bare class name. Templates also carry
the namespaced_id as an explicit field so consumers that look at the value (not the
key) still see the canonical address. This is the form the LE-1020 migration table
will rewrite legacy class-name references to.

P2: load_installed_extensions now appends duplicate-distribution to result.errors
instead of result.warnings, so LoadResult.ok=False when two distributions share a
canonical name. The winner's components still appear in result.components so flows
already pinned to them keep working; only the conflict status changes. Updated test
to assert errors + ok=False; added explicit assertion that the winner's components
are still present.

* fix(lfx): installed-distribution discovery accepts pyproject.toml manifest form

Closes the latest review finding on PR #12967: the installed-distribution
scan only looked for extension.json, ignoring distributions whose manifest
lives in [tool.langflow.extension] inside pyproject.toml. The AC explicitly
treats both as valid manifest forms.

_distribution_manifest_path now:
- Returns extension.json immediately when present (preserves precedence
  matching load_manifest's discovery order).
- Falls back to pyproject.toml only when extension.json is absent AND the
  pyproject's [tool.langflow.extension] section is parseable.

Validation reuses load_manifest itself so the rule lives in exactly one
place; a stray pyproject.toml without the section is correctly ignored.

Tests cover: pyproject-only discovery, pyproject-without-section ignored,
extension.json wins on collision, end-to-end pyproject load at @official,
and pyproject-form manifest-first entry-point suppression.

* refactor(lfx): tighten loader invariants, surface silent skips, harden tests

Addresses the latest review feedback on PR #12967:

Type-level invariants (_types.py):
- LoadedComponent.__post_init__ enforces that @extra components must NOT
  carry a distribution. The reverse (@official without distribution) is
  permitted because load_extension is also used for dev-mode loads
  against a working tree before pip install.
- LoadResult docstring documents the partial-success contract: components
  may be non-empty when errors is non-empty (some files imported, others
  failed). Callers branching on ok get strict success.

Silent-failure fixes (_orchestrator.py + settings/base.py):
- inline-path-missing: a non-existent / non-dir LANGFLOW_COMPONENTS_PATH
  entry now produces a typed warning per skipped path so a typo no
  longer yields zero diagnostics. Settings-layer skip bumped from debug
  to warning for the same reason.
- bundle-json-invalid: a malformed or non-object bundle.json now surfaces
  a typed warning instead of silently rewriting the user-declared
  id/version to derived values under the same bundle name.
- no-component-subclass gating uses a call-local counter instead of
  result.errors so the diagnostic stays accurate when a future caller
  reuses a LoadResult (multi-bundle / batch wrapper scenarios).

Test hardening:
- test_re_imported_class_is_skipped_via_module_filter rewritten to
  actually exercise the __module__-equality check via sys.modules
  injection; previously passed via module-import-failed (relative-import
  failure), which would silently weaken if package registration changes.
- test_user_declared_path_order_is_preserved: AC #8's multi-path order
  case (distinct bundles in [path_b, path_a]) was unasserted; added.
- test_inline_module_import_failure_attributes_identity: AC #10's
  identity-on-partial-failure was covered for @official but not @extra;
  added.
- test_uses_real_distributions_by_default tightened to assert ep
  placement (in kept, not in skipped) instead of exact-list equality, so
  a future Langflow-shipped manifest doesn't silently flip the assertion.

bumped 64 -> 175 passing extension tests; 20 backend integration tests
still pass.

* fix(lfx): malformed pyproject manifests surface manifest-invalid instead of disappearing

Closes the latest review finding on PR #12967: a pyproject.toml with a
[tool.langflow.extension] section that has missing/invalid required
fields was silently dropped because _pyproject_has_extension_section
ran full schema validation via load_manifest and returned False on
ValueError/TypeError. That conflated 'no section' with 'section
malformed'.

Fix: detect section presence only. _pyproject_has_extension_section now
calls _read_pyproject_extension (TOML parse + key lookup, no schema
check). Behavior:
- Section absent or pyproject TOML unparseable -> False (treat as
  regular non-manifest package).
- Section present and is a table (valid OR schema-invalid) -> True.
- Section present but is not a table -> True; the author intended to
  declare an extension and load_extension will surface the typed error.

This way a typo'd pyproject Extension produces a typed manifest-invalid
LoadResult with extension_id attribution, and manifest-first precedence
still suppresses its legacy component entry-points -- matching the
'typed load results on success/failure' contract for the supported
pyproject manifest form.

Tests: two new cases pin the behavior. test_malformed_pyproject_section_
surfaces_manifest_invalid asserts a typed load-failure result with
distribution attribution; the second test pins manifest-first
suppression for malformed pyproject distributions.

* refactor(lfx): emit inline-path-unreadable, document reload contract, trim rot

Closes the remaining nits on PR #12967:

- inline-path-unreadable (new typed error code): a configured
  LANGFLOW_COMPONENTS_PATH entry that raises OSError on iterdir
  (typically permission-denied) now produces a typed LoadResult error
  carrying str(exc) instead of silently swallowing the message.
- duplicate-inline-bundle hint trimmed: removed forward promise about
  hard-error-in-a-later-release; same actionability, no expiration.
- discover_inline_bundles docstring trimmed from three paragraphs to
  two sentences (per CLAUDE.md anti-multi-paragraph rule).
- _distribution_manifest_path docstring trimmed to one-liner.
- installed_extension_roots dropped Used-by caller-narration list;
  manifest_owning_distributions docstring rewritten to call out the
  shadow-load risk for direct callers and point to load_installed_
  extensions for the typed warning surface.
- _discovery.import_bundle_module: replaced 'until that lands in a
  later milestone' rot with a single line ('Absolute imports only
  between bundle modules; relative imports unsupported.') AND added
  the single-load-per-process contract note documenting why LE-1018
  reload must scrub registry/sys.modules before re-invoking the loader.
- load_extension docstring grew a 'Single-load-per-process contract'
  block telling direct callers not to rely on this function for refresh.

Tests: new test_unreadable_path_emits_inline_path_unreadable pins the
OSError -> typed-error path.

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(lfx): atomic-swap Bundle reload pipeline + endpoint + CLI (LE-1018) (#12979)

* feat(lfx): add single-Bundle loader and LANGFLOW_COMPONENTS_PATH discovery (LE-1015)

Introduces lfx.extension.loader: the runtime that turns an Extension on disk
into LoadedComponent records keyed by ext:<bundle>:<Class>@<slot>. Two paths in:

  - load_extension(root): one manifest, one Bundle, registered at @official.
    Re-checks multi-bundle at runtime (defense-in-depth vs. the schema).
  - discover_inline_bundles(paths): each subfolder of LANGFLOW_COMPONENTS_PATH
    is a Bundle at @extra. Walk order is platform-independent (sorted dirs,
    user-declared path order). First-wins on duplicate names; second emits
    duplicate-inline-bundle warning that names both paths.

Manifest-first precedence helpers (installed_extension_roots,
manifest_owning_distributions, filter_plugin_entry_points) let callers of
the legacy langflow.plugins entry-point loader skip distributions that ship
a manifest, so component entry-points are not double-registered.

New typed error codes: module-import-failed, duplicate-component-name,
duplicate-distribution, duplicate-inline-bundle, inline-bundle-name-invalid.
Each ships with a format branch and a snapshot test.

Tests cover the AC: single-bundle happy path, multi-bundle rejection,
missing/empty/no-Component bundle, duplicate class names, deterministic
walk order, recursive discovery, inline-bundle first-wins + dot-dir skip
+ bundle.json metadata, manifest-first precedence partition, PEP-503
distribution-name canonicalization.

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

* fix(lfx): address LE-1015 review feedback

- Drop the unproduced duplicate-distribution error code; LE-1022 will add
  it once startup-time discovery has a place to surface it.  Restores the
  invariant that every code in ERROR_CODES has a producer.
- Clarify that intra-bundle relative imports are NOT supported in v0; only
  absolute references between bundle modules work in this milestone.
- Use strict=False when re-resolving bundle_root in the walker; the path
  was already existence-checked, and a concurrent removal in the narrow
  window should not raise across the loader's public boundary.
- Hoist the json import out of _read_inline_bundle_json's body.

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

* refactor(lfx): split extension loader into a small subpackage (LE-1015)

Addresses the file-size feedback from the LE-1015 review.  The single
870-line loader.py becomes a flat package keyed off the four section
banners that already existed inline:

    loader/
      __init__.py     # re-exports the public surface
      _types.py       # SLOT constants, LoadedComponent, LoadResult
      _discovery.py   # filesystem walk + importlib.util orchestration
      _detection.py   # Component subclass identification (MRO heuristic)
      _orchestrator.py # load_extension, discover_inline_bundles
      _plugins.py     # manifest-first precedence over langflow.plugins

Largest file is now _orchestrator.py at 440 LOC (was 870); every file is
well under the 800-LOC project guideline.  No behavior change: the public
import paths from lfx.extension are unchanged, all 38 loader tests still
pass.  ``_canonicalize_distribution`` is now exported as
``canonicalize_distribution`` from ``loader._plugins`` (it's a stable
PEP-503 helper that downstream modules will reach for, so it loses the
private underscore).

The test suite is split to mirror the package:

    tests/unit/extension/loader/
      conftest.py             # shared fixtures, FakeDist, autouse scrub
      test_load_extension.py  # @official slot, identity, failure modes
      test_inline_bundles.py  # LANGFLOW_COMPONENTS_PATH, @extra slot
      test_plugins.py         # manifest-first precedence helpers
      test_types.py           # LoadedComponent, LoadResult, code parity

Each test file imports its own slice of the public API and pulls fixtures
from conftest, so a reader looking at one banner can read it in isolation.

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

* feat(lfx): atomic-swap Bundle reload pipeline + endpoint + CLI (LE-1018)

Five-stage reload (parallel staging load -> validate -> swap under write
lock -> cleanup -> emit) for installed Bundles in Mode A.  In-flight
flows keep the pre-swap class via existing references; new flows pick up
the post-swap class atomically; concurrent reloads on the same Bundle
are rejected with reload-in-progress.

Adds:

* lfx/extension/registry.py -- BundleRegistry with per-bundle
  reload-in-progress guard and components_index.json writer
* lfx/extension/reload.py -- the five-stage pipeline; events emission
  is stubbed (TODO LE-1017) so the swap mechanics can ship before the
  events service lands
* loader: optional module_namespace param so Stage 1 lands in
  __reload_staging__.<id> instead of the live _lfx_ext.* namespace
* errors: four new typed reload codes (reload-in-progress,
  reload-bundle-not-installed, reload-bundle-name-mismatch,
  reload-source-missing) with branch templates and snapshot tests
* HTTP: POST /api/v1/extensions/{id}/bundles/{name}/reload, gated by
  the existing get_current_active_user dependency, returns 409 with a
  typed body for the in-progress collision case
* CLI: lfx extension reload <id> [--bundle <name>] -- HTTP client
  against the dev server with text/json output and proper exit codes
  (--all is gated until LE-1019 lands the list endpoint)
* tests: 16 reload-pipeline tests covering the AC matrix (rename
  round-trip, broken-bundle isolation, concurrent readers, in-flight
  flow, double-reload guard, bundle-name mismatch) plus 9 CLI client
  tests

Mode A only.  In Mode B/C bundle changes require a Docker image rebuild
and the reload path is not exercised.

The events emission in Stage 5 is intentionally stubbed -- the LE-1017
ticket will swap the body of _emit_bundle_reload_event in one place
without touching the pipeline core.

---------

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

* [autofix.ci] apply automated fixes

* feat(lfx): add `extension init` and `extension dev` CLIs (LE-1016) (#12968)

* 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>

* feat(lfx): add single-Bundle loader and LANGFLOW_COMPONENTS_PATH discovery (LE-1015)

Introduces lfx.extension.loader: the runtime that turns an Extension on disk
into LoadedComponent records keyed by ext:<bundle>:<Class>@<slot>. Two paths in:

  - load_extension(root): one manifest, one Bundle, registered at @official.
    Re-checks multi-bundle at runtime (defense-in-depth vs. the schema).
  - discover_inline_bundles(paths): each subfolder of LANGFLOW_COMPONENTS_PATH
    is a Bundle at @extra. Walk order is platform-independent (sorted dirs,
    user-declared path order). First-wins on duplicate names; second emits
    duplicate-inline-bundle warning that names both paths.

Manifest-first precedence helpers (installed_extension_roots,
manifest_owning_distributions, filter_plugin_entry_points) let callers of
the legacy langflow.plugins entry-point loader skip distributions that ship
a manifest, so component entry-points are not double-registered.

New typed error codes: module-import-failed, duplicate-component-name,
duplicate-distribution, duplicate-inline-bundle, inline-bundle-name-invalid.
Each ships with a format branch and a snapshot test.

Tests cover the AC: single-bundle happy path, multi-bundle rejection,
missing/empty/no-Component bundle, duplicate class names, deterministic
walk order, recursive discovery, inline-bundle first-wins + dot-dir skip
+ bundle.json metadata, manifest-first precedence partition, PEP-503
distribution-name canonicalization.

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

* fix(lfx): address LE-1015 review feedback

- Drop the unproduced duplicate-distribution error code; LE-1022 will add
  it once startup-time discovery has a place to surface it.  Restores the
  invariant that every code in ERROR_CODES has a producer.
- Clarify that intra-bundle relative imports are NOT supported in v0; only
  absolute references between bundle modules work in this milestone.
- Use strict=False when re-resolving bundle_root in the walker; the path
  was already existence-checked, and a concurrent removal in the narrow
  window should not raise across the loader's public boundary.
- Hoist the json import out of _read_inline_bundle_json's body.

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

* refactor(lfx): split extension loader into a small subpackage (LE-1015)

Addresses the file-size feedback from the LE-1015 review.  The single
870-line loader.py becomes a flat package keyed off the four section
banners that already existed inline:

    loader/
      __init__.py     # re-exports the public surface
      _types.py       # SLOT constants, LoadedComponent, LoadResult
      _discovery.py   # filesystem walk + importlib.util orchestration
      _detection.py   # Component subclass identification (MRO heuristic)
      _orchestrator.py # load_extension, discover_inline_bundles
      _plugins.py     # manifest-first precedence over langflow.plugins

Largest file is now _orchestrator.py at 440 LOC (was 870); every file is
well under the 800-LOC project guideline.  No behavior change: the public
import paths from lfx.extension are unchanged, all 38 loader tests still
pass.  ``_canonicalize_distribution`` is now exported as
``canonicalize_distribution`` from ``loader._plugins`` (it's a stable
PEP-503 helper that downstream modules will reach for, so it loses the
private underscore).

The test suite is split to mirror the package:

    tests/unit/extension/loader/
      conftest.py             # shared fixtures, FakeDist, autouse scrub
      test_load_extension.py  # @official slot, identity, failure modes
      test_inline_bundles.py  # LANGFLOW_COMPONENTS_PATH, @extra slot
      test_plugins.py         # manifest-first precedence helpers
      test_types.py           # LoadedComponent, LoadResult, code parity

Each test file imports its own slice of the public API and pulls fixtures
from conftest, so a reader looking at one banner can read it in isolation.

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

* feat(lfx): add `extension init` and `extension dev` CLIs (LE-1016)

The two scaffolding CLIs an Extension author types:

  - `lfx extension init <target>` writes the basic single-Bundle
    template (manifest with $schema, README, .gitignore, one Component
    subclass + a pytest smoke test).  AC #1: the generated extension
    validates clean against LE-1014.  AC #2: the generated test file is
    a valid pytest module that exercises the component's build() method.
    AC #3: any --template other than 'basic' fails with a typed
    template-deferred-in-this-milestone error and a non-zero exit.
    Refuses to scaffold over a non-empty target dir.

  - `lfx extension dev <target>` validates the local extension, records
    its absolute path in <config_dir>/extensions/dev_extensions.json,
    prints reload instructions, and execs `langflow run` (or
    `python -m langflow` when langflow isn't on PATH).  --skip-launch
    registers without launching (used by tests + external dev-server
    scripts); --skip-validate lets authors register a known-broken
    manifest to debug it under the loader.

Stack:
  - Wave 0: error codes (extension-target-exists,
    extension-target-invalid, local-extension-missing) with format
    branches and snapshot tests.
  - Wave 1: lfx.extension.init_template -- pure-data scaffolder, no
    Typer dependency so the CLI is a thin shell over it.
  - Wave 1: lfx.extension.dev_registry -- atomic JSON state file under
    the langflow user-cache dir; helpers for register / list /
    unregister / load_dev_extensions / dev_extension_component_paths.
  - Wave 2: lfx.cli._extension_commands gains init/dev subcommands.
  - Wave 2: langflow.main lifespan hook reads the dev registry after
    bundle loading and extends components_path with each registered
    bundle dir, so the existing palette discovery picks up dev
    extensions.  Missing paths surface as local-extension-missing
    warnings (AC #5) without aborting startup.

Tests (84 new, 197 total in tests/unit/extension/):
  - test_init_template.py: AC scenarios + identifier derivation +
    deterministic file shape.
  - test_dev_registry.py: register/list/unregister round-trip,
    idempotent re-register refreshes timestamp, malformed state file
    treated as empty, missing-path warning, recovery when path
    reappears, env-var override precedence.
  - test_cli.py: AC #1 init->validate, AC #3 deferred templates,
    --skip-launch registers without launching, --skip-validate
    short-circuits the pre-flight pass.
  - test_errors.py: snapshot rows for all three new codes; the
    every-known-code-has-a-snapshot test enforces parity.

LE-1018 (reload) reuses load_dev_extensions; LE-1022 (installed-pkg
discovery) shares the components_path extension pattern.  AC #4 ("boots
Langflow with the extension visible in the palette within 5s") is
delivered jointly by `extension dev` (registers + execs) and the
lifespan hook (loads on startup).

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

* fix(lfx): address LE-1016 review feedback

Fixes the four HIGH issues + the elevated LOW from the review pass:

1. dev_extension_component_paths now forwards EVERY warning, not just
   local-extension-missing.  Previously a duplicate-component-name (or
   any future warning code) was silently dropped, hiding real signal
   from the lifespan hook's logs.

2. Defensive emit when a LoadResult has components but source_path is
   None.  The current loader always sets source_path, but a future
   hand-built LoadResult could violate that contract; we now surface a
   typed local-extension-missing error rather than dropping the
   extension silently.

3. Replaced the fragile ``min(len(parts))`` bundle-root selection with
   a relative-to-source-path measurement.  Handles deep-vs-shallow
   sibling extensions correctly without depending on absolute path
   depth.

4. Generated README now documents the langflow/lfx prerequisite under
   the Develop section so authors know `pytest` requires the lfx
   environment, not just Python.

5. Forced LANGFLOW_LAZY_LOAD_COMPONENTS=false unconditionally in the
   `extension dev` exec env (was setdefault, which let a developer's
   global lazy-loading export silently hide their dev components from
   the palette and miss AC #4's 5s budget).

Plus three MEDIUMs:

  - sys.modules cleanup in test_generated_test_file_runs_against_generated_component
    so a later test importing the same dotted path doesn't pick up a
    stale module from a deleted tmp_path.  Component instantiation
    moved inside the try block because Component.__init__ uses
    inspect.getsourcefile against self.__class__'s still-live module.
  - Added regex-drift test that pins the init_template patterns to
    match manifest.py's so a schema regex change can't quietly produce
    invalid scaffolded manifests.
  - Added two new dev_registry tests covering the forward-all-warnings
    contract and the source_path=None defense.

Tests: 201 passing (4 new); ruff check + format clean.

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

* fix: LangflowCompat -> LfxCompat

* fix: Remove references to ticket

* fix: encode maxItems constraint in schema

* fix: deferred fields and schema version

* Fix ruff errors

* fix: align loader tests with renamed manifest API and strip ticket refs

The merge of feat/extension-validate brought in the LfxCompat / compat
rename, but the loader test fixtures still used LangflowCompat / bundle_api
and failed at the manifest layer. Update conftest.py + test_load_extension.py
to the post-rename API.

Strip 17 LE-XXXX ticket references from loader source files, errors.py
loader-specific comments, and the four loader test docstrings, matching the
convention applied to LE-1014. Descriptive prose preserved.

Promote _BUNDLE_NAME_RE to BUNDLE_NAME_RE on the manifest module so the
loader's orchestrator no longer reaches across modules into a private name.

* fix(lfx): align init template with renamed manifest API

After merging feat/extension-loader into this branch, two surfaces
fell out of sync with the renamed manifest schema:

- init_template generates extension.json with `lfx: {bundle_api: [1]}`,
  but the validator now requires `lfx: {compat: ["1"]}` per LfxCompat.
  This made `test_basic_template_validates_clean` fail with
  manifest-invalid (`lfx.compat: Field required; lfx.bundle_api: Extra
  inputs are not permitted`).
- test_init_template_regexes_match_manifest_schema reads
  `manifest_mod._BUNDLE_NAME_RE`, but that symbol was promoted to public
  `BUNDLE_NAME_RE` in c63f84a591. Update the test to reference the
  public name; init_template's local copy is still private since it
  also covers `_EXTENSION_ID_RE`, which remains private upstream.

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(lfx): append-only migration table + flow deserializer rewrite hook (#13024)

* 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>

* feat(lfx): add single-Bundle loader and LANGFLOW_COMPONENTS_PATH discovery (LE-1015)

Introduces lfx.extension.loader: the runtime that turns an Extension on disk
into LoadedComponent records keyed by ext:<bundle>:<Class>@<slot>. Two paths in:

  - load_extension(root): one manifest, one Bundle, registered at @official.
    Re-checks multi-bundle at runtime (defense-in-depth vs. the schema).
  - discover_inline_bundles(paths): each subfolder of LANGFLOW_COMPONENTS_PATH
    is a Bundle at @extra. Walk order is platform-independent (sorted dirs,
    user-declared path order). First-wins on duplicate names; second emits
    duplicate-inline-bundle warning that names both paths.

Manifest-first precedence helpers (installed_extension_roots,
manifest_owning_distributions, filter_plugin_entry_points) let callers of
the legacy langflow.plugins entry-point loader skip distributions that ship
a manifest, so component entry-points are not double-registered.

New typed error codes: module-import-failed, duplicate-component-name,
duplicate-distribution, duplicate-inline-bundle, inline-bundle-name-invalid.
Each ships with a format branch and a snapshot test.

Tests cover the AC: single-bundle happy path, multi-bundle rejection,
missing/empty/no-Component bundle, duplicate class names, deterministic
walk order, recursive discovery, inline-bundle first-wins + dot-dir skip
+ bundle.json metadata, manifest-first precedence partition, PEP-503
distribution-name canonicalization.

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

* fix(lfx): address LE-1015 review feedback

- Drop the unproduced duplicate-distribution error code; LE-1022 will add
  it once startup-time discovery has a place to surface it.  Restores the
  invariant that every code in ERROR_CODES has a producer.
- Clarify that intra-bundle relative imports are NOT supported in v0; only
  absolute references between bundle modules work in this milestone.
- Use strict=False when re-resolving bundle_root in the walker; the path
  was already existence-checked, and a concurrent removal in the narrow
  window should not raise across the loader's public boundary.
- Hoist the json import out of _read_inline_bundle_json's body.

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

* refactor(lfx): split extension loader into a small subpackage (LE-1015)

Addresses the file-size feedback from the LE-1015 review.  The single
870-line loader.py becomes a flat package keyed off the four section
banners that already existed inline:

    loader/
      __init__.py     # re-exports the public surface
      _types.py       # SLOT constants, LoadedComponent, LoadResult
      _discovery.py   # filesystem walk + importlib.util orchestration
      _detection.py   # Component subclass identification (MRO heuristic)
      _orchestrator.py # load_extension, discover_inline_bundles
      _plugins.py     # manifest-first precedence over langflow.plugins

Largest file is now _orchestrator.py at 440 LOC (was 870); every file is
well under the 800-LOC project guideline.  No behavior change: the public
import paths from lfx.extension are unchanged, all 38 loader tests still
pass.  ``_canonicalize_distribution`` is now exported as
``canonicalize_distribution`` from ``loader._plugins`` (it's a stable
PEP-503 helper that downstream modules will reach for, so it loses the
private underscore).

The test suite is split to mirror the package:

    tests/unit/extension/loader/
      conftest.py             # shared fixtures, FakeDist, autouse scrub
      test_load_extension.py  # @official slot, identity, failure modes
      test_inline_bundles.py  # LANGFLOW_COMPONENTS_PATH, @extra slot
      test_plugins.py         # manifest-first precedence helpers
      test_types.py           # LoadedComponent, LoadResult, code parity

Each test file imports its own slice of the public API and pulls fixtures
from conftest, so a reader looking at one banner can read it in isolation.

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

* fix: LangflowCompat -> LfxCompat

* fix: Remove references to ticket

* fix: encode maxItems constraint in schema

* fix: deferred fields and schema version

* Fix ruff errors

* fix: align loader tests with renamed manifest API and strip ticket refs

The merge of feat/extension-validate brought in the LfxCompat / compat
rename, but the loader test fixtures still used LangflowCompat / bundle_api
and failed at the manifest layer. Update conftest.py + test_load_extension.py
to the post-rename API.

Strip 17 LE-XXXX ticket references from loader source files, errors.py
loader-specific comments, and the four loader test docstrings, matching the
convention applied to LE-1014. Descriptive prose preserved.

Promote _BUNDLE_NAME_RE to BUNDLE_NAME_RE on the manifest module so the
loader's orchestrator no longer reaches across modules into a private name.

* feat(lfx): append-only migration table + flow deserializer rewrite hook

Adds the migration layer of the Extension System: an append-only JSON table
that maps three legacy component reference shapes (bare class name, old
import path, pre-Phase-A namespaced slot) to the post-Phase-A canonical
ext:<bundle>:<Class>@<slot> identifier, plus a deserializer hook that
rewrites a saved-flow payload in place against that table on load.

What landed:

  * lfx.extension.migration.schema -- Pydantic models for MigrationEntry +
    MigrationTable with per-entry validators (exactly one of bare/import/slot
    populated; canonical target shape) and table-level uniqueness check.
  * lfx.extension.migration.loader -- canonical in-repo path, threadsafe
    process-lifetime cache, typed errors on every failure mode.
  * lfx.extension.migration.rewrite -- node-by-node rewrite, idempotent on
    canonical refs, difflib-backed closest-match suggestion for unmapped
    references, cross-bucket ambiguity surfaces component-name-ambiguous
    instead of silently loading into the wrong bundle.
  * Wired into Graph.from_payload before validate_flow_for_current_settings
    so every saved-flow load goes through migration first.
  * scripts/migrate/check_migration_append_only.py -- CI guard that diffs
    the working-tree table against origin/main and rejects removals or
    target mutations; reordering and additions are allowed.
  * 34 new unit tests covering rewrite paths, loader failure modes, schema
    invariants, and the CI script behavior.

What is deliberately deferred:

  * flow-migrated event emission. The events pipeline is unavailable in this
    iteration; the wiring point in Graph.from_payload is marked TODO and the
    MigrationReport already carries every field a future emitter needs.

The shipped migration_table.json starts empty; entries land alongside the
pilot bundle extraction in a follow-up.

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

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(frontend): palette Bundle reload action + loading + toasts (#13025)

* 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>

* feat(lfx): add single-Bundle loader and LANGFLOW_COMPONENTS_PATH discovery (LE-1015)

Introduces lfx.extension.loader: the runtime that turns an Extension on disk
into LoadedComponent records keyed by ext:<bundle>:<Class>@<slot>. Two paths in:

  - load_extension(root): one manifest, one Bundle, registered at @official.
    Re-checks multi-bundle at runtime (defense-in-depth vs. the schema).
  - discover_inline_bundles(paths): each subfolder of LANGFLOW_COMPONENTS_PATH
    is a Bundle at @extra. Walk order is platform-independent (sorted dirs,
    user-declared path order). First-wins on duplicate names; second emits
    duplicate-inline-bundle warning that names both paths.

Manifest-first precedence helpers (installed_extension_roots,
manifest_owning_distributions, filter_plugin_entry_points) let callers of
the legacy langflow.plugins entry-point loader skip distributions that ship
a manifest, so component entry-points are not double-registered.

New typed error codes: module-import-failed, duplicate-component-name,
duplicate-distribution, duplicate-inline-bundle, inline-bundle-name-invalid.
Each ships with a format branch and a snapshot test.

Tests cover the AC: single-bundle happy path, multi-bundle rejection,
missing/empty/no-Component bundle, duplicate class names, deterministic
walk order, recursive discovery, inline-bundle first-wins + dot-dir skip
+ bundle.json metadata, manifest-first precedence partition, PEP-503
distribution-name canonicalization.

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

* fix(lfx): address LE-1015 review feedback

- Drop the unproduced duplicate-distribution error code; LE-1022 will add
  it once startup-time discovery has a place to surface it.  Restores the
  invariant that every code in ERROR_CODES has a producer.
- Clarify that intra-bundle relative imports are NOT supported in v0; only
  absolute references between bundle modules work in this milestone.
- Use strict=False when re-resolving bundle_root in the walker; the path
  was already existence-checked, and a concurrent removal in the narrow
  window should not raise across the loader's public boundary.
- Hoist the json import out of _read_inline_bundle_json's body.

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

* refactor(lfx): split extension loader into a small subpackage (LE-1015)

Addresses the file-size feedback from the LE-1015 review.  The single
870-line loader.py becomes a flat package keyed off the four section
banners that already existed inline:

    loader/
      __init__.py     # re-exports the public surface
      _types.py       # SLOT constants, LoadedComponent, LoadResult
      _discovery.py   # filesystem walk + importlib.util orchestration
      _detection.py   # Component subclass identification (MRO heuristic)
      _orchestrator.py # load_extension, discover_inline_bundles
      _plugins.py     # manifest-first precedence over langflow.plugins

Largest file is now _orchestrator.py at 440 LOC (was 870); every file is
well under the 800-LOC project guideline.  No behavior change: the public
import paths from lfx.extension are unchanged, all 38 loader tests still
pass.  ``_canonicalize_distribution`` is now exported as
``canonicalize_distribution`` from ``loader._plugins`` (it's a stable
PEP-503 helper that downstream modules will reach for, so it loses the
private underscore).

The test suite is split to mirror the package:

    tests/unit/extension/loader/
      conftest.py             # shared fixtures, FakeDist, autouse scrub
      test_load_extension.py  # @official slot, identity, failure modes
      test_inline_bundles.py  # LANGFLOW_COMPONENTS_PATH, @extra slot
      test_plugins.py         # manifest-first precedence helpers
      test_types.py           # LoadedComponent, LoadResult, code parity

Each test file imports its own slice of the public API and pulls fixtures
from conftest, so a reader looking at one banner can read it in isolation.

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

* feat(lfx): atomic-swap Bundle reload pipeline + endpoint + CLI (LE-1018)

Five-stage reload (parallel staging load -> validate -> swap under write
lock -> cleanup -> emit) for installed Bundles in Mode A.  In-flight
flows keep the pre-swap class via existing references; new flows pick up
the post-swap class atomically; concurrent reloads on the same Bundle
are rejected with reload-in-progress.

Adds:

* lfx/extension/registry.py -- BundleRegistry with per-bundle
  reload-in-progress guard and components_index.json writer
* lfx/extension/reload.py -- the five-stage pipeline; events emission
  is stubbed (TODO LE-1017) so the swap mechanics can ship before the
  events service lands
* loader: optional module_namespace param so Stage 1 lands in
  __reload_staging__.<id> instead of the live _lfx_ext.* namespace
* errors: four new typed reload codes (reload-in-progress,
  reload-bundle-not-installed, reload-bundle-name-mismatch,
  reload-source-missing) with branch templates and snapshot tests
* HTTP: POST /api/v1/extensions/{id}/bundles/{name}/reload, gated by
  the existing get_current_active_user dependency, returns 409 with a
  typed body for the in-progress collision case
* CLI: lfx extension reload <id> [--bundle <name>] -- HTTP client
  against the dev server with text/json output and proper exit codes
  (--all is gated until LE-1019 lands the list endpoint)
* tests: 16 reload-pipeline tests covering the AC matrix (rename
  round-trip, broken-bundle isolation, concurrent readers, in-flight
  flow, double-reload guard, bundle-name mismatch) plus 9 CLI client
  tests

Mode A only.  In Mode B/C bundle changes require a Docker image rebuild
and the reload path is not exercised.

The events emission in Stage 5 is intentionally stubbed -- the LE-1017
ticket will swap the body of _emit_bundle_reload_event in one place
without touching the pipeline core.

* feat(frontend): palette Bundle reload action + loading + toasts

Adds the frontend half of the bundle reload flow.  When the Bundle
header is right-clicked or its overflow ("⋮") icon clicked, a Reload
action fires POST /api/v1/extensions/{id}/bundles/{name}/reload and
surfaces the result via the existing alert-store toast system.

What landed (frontend only):

  * src/controllers/API/queries/extensions/ -- typed wire-format models
    (ReloadBundleResponse, ExtensionErrorPayload, ReloadInProgressDetail)
    and the useReloadBundle mutation hook.  The hook unwraps the 409
    `reload-in-progress` detail into a stable, parseable Error message so
    the UI can branch without reading status codes.
  * components/bundleHeaderActions.tsx -- new Select-based overflow menu
    next to the Bundle header chevron.  Three toast paths: success
    (green, with components +/- delta), structural failure (red, with
    typed errors and inline hints), reload-in-progress (notice).
    Loading state swaps the kebab icon for a spinning Loader2 while
    the request is in flight.  Renders nothing when no extension_id is
    on the bundle, so the static SIDEBAR_BUNDLES list is unaffected.
  * components/bundleItems.tsx -- wires the new actions in next to the
    chevron, plus a context-menu (right-click) capture that opens the
    same overflow trigger so keyboard / mouse / right-click all share
    one source of truth.
  * types/index.ts -- BundleItemProps.item gains an optional
    extension_id; took the opportunity to extract the SidebarBundle
    interface and tighten three pre-existing `any` types.
  * customization/feature-flags.ts -- ENABLE_EXTENSION_RELOAD gate, off
    by default until the bundle-list endpoint that populates extension_id
    per bundle ships.
  * controllers/API/helpers/constants.ts -- EXTENSIONS URL constant.
  * Tests: 7 component tests + 3 mutation-hook tests, all green.  Total
    sidebar + extensions test count: 479 passing.

Deferred:

  * Event-pipeline subscription is left as an inline TODO.  The mutation
    response carries enough information to drive the toasts on its own
    today; once the events service lands the toast wiring will move to
    a `bundle_reloaded` / `bundle_reload_failed` listener so multi-tab
    and multi-worker swaps surface exactly once.

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

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat: End to end bundle installation

* fix: Review comments addressed

* Update component_index.json

* Update component_index.json

* Update router.py

* fix(docker): copy src/bundles before uv sync so workspace bundles resolve

Each directory under ``src/bundles`` is a uv workspace member referenced by
``langflow-base`` (and the root project) as a path dependency.  The Docker
builders ran ``uv sync --no-install-project`` after copying only the
top-level pyproject.toml files, so resolution failed with
``Distribution not found at: file:///app/src/bundles/<name>``.

Copying the whole ``src/bundles`` tree (rather than enumerating each
bundle) means a new bundle dropped under that dir does not require a
Dockerfile edit.  The full ``./src`` copy a few lines later produces the
same final layer either way; this earlier copy just unblocks the
dependency-resolution sync.

Touched all builders that run a workspace-resolving uv sync:

  * docker/build_and_push.Dockerfile
  * docker/build_and_push_base.Dockerfile
  * docker/build_and_push_ep.Dockerfile
  * docker/build_and_push_with_extras.Dockerfile
  * docker/dev.Dockerfile (bind-mount instead of COPY)

* Revert "fix(docker): copy src/bundles before uv sync so workspace bundles resolve"

This reverts commit 5aa008a3cd.

* feat: DuckDuckGo as Extension in new Bundle System (#13044)

* feat: DuckDuckGo Extension for bundles

* fix ruff errors

* Update test_pilot_duckduckgo_upgrade.py

* test(lfx): handle non-empty canonical migration table + editable installs

- test_path_override_bypasses_cache: mirror the cached canonical table
  into the temp file instead of asserting it's empty.  Drift in
  migration_table.json (the duckduckgo entries shipped with the B1
  pilot) no longer breaks the cache-bypass invariant.

- test_lfx_duckduckgo_ships_manifest: editable installs (pip install -e)
  surface only dist-info entries in dist.files, so we cannot use that
  path to find extension.json in the workspace venv.  Detect editable
  mode via direct_url.json's PEP 660 marker and fall through to walking
  the source tree; non-editable wheel installs still exercise the
  dist.files path the loader uses at runtime.

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

* fix(docker): copy src/bundles before uv sync so workspace bundles resolve

Each directory under ``src/bundles`` is a uv workspace member referenced by
``langflow-base`` (and the root project) as a path dependency.  The Docker
builders ran ``uv sync --no-install-project`` after copying only the
top-level pyproject.toml files, so resolution failed with
``Distribution not found at: file:///app/src/bundles/<name>``.

Copying the whole ``src/bundles`` tree (rather than enumerating each
bundle) means a new bundle dropped under that dir does not require a
Dockerfile edit.  The full ``./src`` copy a few lines later produces the
same final layer either way; this earlier copy just unblocks the
dependency-resolution sync.

Touched all builders that run a workspace-resolving uv sync:

  * docker/build_and_push.Dockerfile
  * docker/build_and_push_base.Dockerfile
  * docker/build_and_push_ep.Dockerfile
  * docker/build_and_push_with_extras.Dockerfile
  * docker/dev.Dockerfile (bind-mount instead of COPY)

---------

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

* fix: Review sweep

* fix: More review comments addressed

* Ruff check

* docs: add bundle porting guide

Step-by-step recipe for extracting a provider package from the in-tree
``src/lfx/src/lfx/components/<provider>/`` directory into a standalone
Extension Bundle distribution under ``src/bundles/<provider>/``.

The DuckDuckGo bundle is the reference; every section maps to a single
copy-pasteable change and a verification command.

Doc surfaces a forthcoming ``scripts/migrate/port_bundle.py`` automation
helper for the mechanical bits; that script lands on the next branch
together with the second-pilot port that validates the recipe end-to-end.

* fix(extension): accept Output(method=...) in build-method validator

The validator's static AST check looked for a literal ``build`` method
on every Component subclass and emitted ``build-method-missing`` when
absent.  Real Langflow components -- including the production
``DuckDuckGoSearchComponent`` and the in-tree ``ArXivComponent`` -- do
not declare a literal ``build``; they declare entry-points
declaratively via ``outputs = [Output(name=..., method=<name>)]`` and
the named method is what gets called.  Result: every clean port hit a
spurious ``build-method-missing`` error from ``lfx extension validate``.

Fix: extend ``_has_build_method`` to also accept any class that names a
method via ``Output(method="X")`` AND defines that method in the class
body.  The negative case ("Output(method=...) without a matching def")
still fires -- a typo'd method name would crash at runtime, so the
static check should keep flagging it.

Two new tests in ``test_validate.py`` lock the contract: positive case
mirroring duckduckgo / arxiv, negative case for typo'd method names.
All 26 validator tests pass.

PORTING.md updates fall out of running the recipe live against the
duckduckgo bundle on this branch:

  * Validate path is ``src/bundles/<bundle>/src/lfx_<bundle>``, not the
    bundle root (the manifest lives next to ``__init__.py``).
  * Index regen needs ``LFX_DEV=1`` to skip the prebuilt-index fast path
    and uses ``scripts/build_component_index.py``.
  * Drop the migration-table JSON from the ruff invocation (ruff treats
    it as Python and complains about the top-level expression).

* fix: Delete outdated components

* fix(palette): wire reload kebab via DropdownMenu, not Select

The reload kebab on the palette Bundle header was using Radix ``Select``
to back its overflow menu.  ``Select`` is for picking a value, not for
firing an action: ``onValueChange`` is gated by value-equality (so a
re-click of the only item is a no-op), and the popover-portal click
semantics interact poorly with the parent disclosure-trigger button.
The combined effect: clicking ⋮ → Reload opened the popover and closed
it, but never fired the network request, with no console error to point
at.

Switch to ``DropdownMenu`` (purpose-built action menu).
``DropdownMenuItem`` exposes ``onSelect`` which fires on every
activation -- the same callback path keyboard navigation uses -- so
clicking Reload reliably invokes the mutation.

Test mocks updated to drive the DropdownMenu primitives instead of
Select; all 8 bundleHeaderActions tests + the broader 437-test sidebar
suite still pass.

* fix(extension): route ddgs through the lockfile + drop bogus list endpoint hint

Two reviewer findings, both about reproducibility / correctness of
operator-facing surfaces.

[P2] ``docker/build_and_push_base.Dockerfile`` previously installed
``ddgs`` via an unpinned ``uv pip install ddgs`` after the workspace
sync.  That made the base image non-reproducible: a future ``ddgs``
release would silently drift from the tested lock state on every
rebuild.

Fix: route ddgs through the locked sync.

  * Restore the ``duckduckgo`` extra in ``src/backend/base/pyproject.toml``
    (``ddgs>=9.0.0``) as an internal "image-build sidecar".  Public
    consumers still install ``lfx-duckduckgo`` directly; the extra
    exists only to keep ``ddgs`` resolved in the lockfile.
  * The Dockerfile now passes ``--extra duckduckgo`` to ``uv sync
    --frozen``, picking up the locked ``ddgs==9.14.1``.
  * The follow-on bundle install keeps ``--no-deps`` so it does not
    duplicate the now-locked ``ddgs`` / ``lfx`` / ``langchain-community``.

[P3] ``langflow/api/v1/extensions.py`` returned a fix hint that pointed
operators at ``GET /api/v1/extensions`` -- a route that does not exist
in this PR (it lands with the LE-1019 list endpoint).  Replaced with a
reference to ``lfx extension list``, which is shipped here.

* fix(compat): bridge langflow.components.* dynamically via meta path finder

Commit 45552cd1df ("fix: Delete outdated components") removed the
physical shim files under ``src/backend/base/langflow/components/``
that forwarded saved-flow imports like
``from langflow.components.processing.converter import convert_to_dataframe``
or ``import langflow.components.knowledge_bases.retrieval`` to their
new ``lfx.components.*`` homes.  Without those shims, dotted imports
into ``langflow.components.<sub>.<leaf>`` failed at flow-load time --
the existing ``LangflowCompatibilityModule`` registers ``langflow.components``
itself in ``sys.modules`` but does not bridge submodules, so Python's
import machinery falls through to the now-empty langflow.components
directory and raises ``ModuleNotFoundError``.

Replace the deleted physical-shim stack with a single ``MetaPathFinder``
in ``langflow/__init__.py`` that dynamically resolves every
``langflow.components.<rest>`` import to ``lfx.components.<rest>`` and
registers the loaded lfx module in ``sys.modules`` under both names.
The langflow- and lfx-prefixed imports share a single underlying module
object, so class identity is preserved across the bridge -- ``isinstance``
checks against types resolved through either path keep working.

The finder also carries a small first-segment override map for the few
subpackages whose name diverged during the move; the only entry today is
``knowledge_bases`` -> ``files_and_knowledge``, matching the deleted
shim's intent.

Why a meta finder instead of restoring the physical shim files (option
1 from the scope analysis): the meta finder scales without per-bundle
maintenance.  Every future bundle extraction landed under ``lfx.components``
becomes reachable via the legacy ``langflow.components.<bundle>`` path
immediately; nobody has to remember to add a parallel langflow shim.

Six new unit tests in ``test_langflow_components_compat_shim.py`` lock
the contract: dotted submodule resolution, helpers re-export, the
``knowledge_bases`` override, class identity preservation, top-level
aliasing, and the "arbitrary extracted bundle" case that prevents
regression for future ports.

Verified pre-existing tests:
  * 17 dynamic-import integration tests pass.
  * The reload-route-guard suite still passes.
  * The Research Translation Loop starter-project test (which loads
    ArXivComponent) passes.

* Update index.tsx

* fix: Review pass on delivery

* fix: Second review sweep, bare names

* fix: Third review sweep

* Resolve dotted imports and attribute chains

Record import shape and flatten attribute chains so router references can be resolved across dotted imports and re-exports. Added ImportTarget dataclass, _attribute_chain helper, and switched IncludeCall/DecoratorRef to store attribute tuples. parse_file now records ImportTarget entries for imports and captures dotted parent/child chains for include_router and decorators. Replaced _resolve_var with _resolve_chain which handles "from" vs "module" imports, various import shapes (including import x.y and aliased imports), and prevents infinite recursion on re-export cycles.

* One more sweep

* Add seed-directory extension loading and docs

Introduce filesystem "seed directory" extension support and authoring docs. Adds three documentation pages (quickstart, manifest reference, author guide) and wires them into the docs sidebar. Implement load_seed_extensions to discover/load bundles from $LANGFLOW_SEED_DIR (default /opt/langflow/bundles), export it from loader/__init__ and extension package, and integrate it into the components import pipeline. Handle installed-vs-seed shadowing by preferring installed distributions and appending a typed seed-bundle-shadowed ExtensionError; add the corresponding error code and message. Update schema doc link and add unit/integration tests to cover seed loading, determinism, shadowing behavior, and migration-target resolution.

* Fix claims

* Fix docasaurus build

* Clean up the manual checklist

* Update test_pilot_duckduckgo_upgrade.py

* fix: Some wording issues with dogfooding

* fix: Comments addressed

* Update port_bundle.py

* Update component_index.json

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

* fix: pytest testpaths glob and accurate scaffold output in port_bundle

testpaths now uses ``src/bundles/*/tests`` so future bundle tests are
picked up automatically without hardcoding each bundle at the root.
pytest expands the glob via ``glob.iglob(..., recursive=True)``.

Rewrote port_bundle.py's ``_render_migration_entries`` and
``_render_test_scaffold`` to match the actual conventions:

* Migration entries now use ``bare_class_name``/``import_path``/
  ``legacy_slot`` + ``target`` + ``added_in`` (the keys
  ``lfx.extension.migration.loader`` actually reads) instead of the
  invented ``from``/``to``/``release`` shape.
* Test scaffold now imports ``load_migration_table`` and
  ``migrate_flow_payload`` -- the APIs the real tests use -- instead of
  a fictitious ``resolve_legacy_id``.  Includes the ``migration_table``
  fixture, ``_saved_flow``/``_saved_flow_node`` helpers, and the
  distribution-importable + manifest-shipped checks that mirror
  ``test_pilot_duckduckgo_upgrade.py``.

Verified by rendering the scaffold for duckduckgo with synthetic plan
data, dropping it into ``src/lfx/tests/integration/extension/``, and
running pytest -- ``3 passed, 2 skipped`` (skips are the wheel-only
checks, by design when run inside the lfx isolation venv).

* [autofix.ci] apply automated fixes

* fix: Review comments

* Update test_discovery.py

* feat: Port Arxiv to the Extension Framework (#13047)

* feat(bundles): port arxiv as the second-pilot Bundle + porting helper

Validates ``src/bundles/PORTING.md`` end-to-end by following its recipe
against a clean candidate (``ArXivComponent``: no third-party runtime
deps, no langflow-base extra, no deactivated duplicate).  Touchpoints
exercised:

  * Bundle skeleton at ``src/bundles/arxiv/`` mirroring duckduckgo.
  * In-tree provider directory removed from ``src/lfx/src/lfx/components/``
    along with its three references in ``components/__init__.py``.
  * Workspace wiring: dep, ``[tool.uv.sources]``, ``[tool.uv.workspace]``
    members, lockfile.
  * Migration table: bare-name + two import-path forms + legacy_slot
    entry.
  * Component index regenerated via ``LFX_DEV=1`` (forces dynamic
    discovery; without it the script reproduces stale entries).
  * Integration test ``test_pilot_arxiv_upgrade.py`` mirroring the
    duckduckgo pilot suite; 5 tests pass against the workspace install.

PORTING.md updates fall out of running the recipe live:
  * Validate path is ``src/bundles/<bundle>/src/lfx_<bundle>``, not the
    bundle root (the manifest lives next to ``__init__.py``).
  * Index regen needs ``LFX_DEV=1`` to skip the prebuilt-index fast path.
  * Drop the migration-table JSON from the ruff invocation (ruff treats
    it as Python and complains about the top-level expression).

``scripts/migrate/port_bundle.py`` is the mechanical helper referenced
from § Automation: stdlib-only, dry-run by default, refuses on invalid
input, and intentionally leaves migration-table edits + integration-test
authoring to a human (release version + bare-name uniqueness require
judgement).  Three guard rails verified: invalid bundle name,
existing-target-bundle, missing in-tree provider.

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

* Update Research Translation Loop.json

* Update .secrets.baseline

* fix: Move bundle test for arxiv

* Update PORTING.md

* Update component_index.json

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

* Update component_index.json

* [autofix.ci] apply automated fixes

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* [autofix.ci] apply automated fixes

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

* Update component_index.json

* Update component_index.json

* Update component_index.json

* fix: empty cache dict on reload

* Lint fixes

* Update test_components_cache_integration.py

* Update test_reload.py

* Hardening pass

* Update test_init_template.py

* fix: resolve cross-source bundle-name shadowing before registry population

The reload pipeline reads ``live.source_path`` from the registry on every
call.  Previously, the registry-population loop in
``import_extension_components`` only special-cased installed-shadows-seed;
for every other pair (seed/dev, seed/inline, dev/inline,
installed/dev, installed/inline) it silently overwrote earlier records
via last-wins iteration order.  A stale dev registration whose
``source_path`` pointed at a different filesystem location could clobber
the seed record's ``source_path``; reload would then walk the dev path
while the operator edited the seed copy on disk -- producing 200 OK with
empty deltas on every reload, including for syntactically broken edits.

Generalize the dedup pass to every (earlier, later) pair using the
explicit precedence ``installed > seed > dev > inline``, applied before
both registry population AND palette template construction so the two
read from the same winning source.  Add a new generic ``bundle-shadowed``
typed error code for the pairs the existing ``seed-bundle-shadowed`` did
not cover; keep ``seed-bundle-shadowed`` for the documented installed-
over-seed pair so existing CLI exit-code logic and snapshot tests stay
intact.  Both codes are warn-only in ``lfx extension list``.

Also add an INFO log line in reload Stage 1 with the resolved
``source_path`` so the next "200 OK with empty deltas" repro can be
triaged from the server log alone -- if the path logged is not the path
the operator was editing, this dedup is what to look at.

Includes a regression test
(``test_seed_bundle_shadows_dev_emits_generic_bundle_shadowed``) that
asserts both halves: seed wins in the BundleRegistry AND the registry's
``source_path`` is the seed path, not the stale dev path.

* Update component_index.json

* fix: widen lfx-* bundles' requires-python to <3.15 to match langflow root

The two pilot bundles (``lfx-arxiv``, ``lfx-duckduckgo``) were scaffolded
by ``scripts/migrate/port_bundle.py`` whose template hard-coded
``requires-python = ">=3.10,<3.14"``.  Because both bundles are uv
workspace members of the langflow root, that cap leaked into every
workspace-level resolve: ``cd src/lfx && uv sync`` (the path
``make lfx_tests`` takes) refuses to pick a Python 3.14 interpreter even
though lfx itself, langflow, and langflow-base all advertise
``>=3.10,<3.15``.  Hosts with 3.14 installed see:

    error: The requested interpreter resolved to Python 3.14.5, which
    is incompatible with the project's Python requirement: `>=3.10, <3.14`.

Fix at the source so future ``port_bundle.py`` runs do not regress this:
template emits ``<3.15``, and the two existing emitted pyprojects are
bumped in lockstep.  ``uv.lock`` regenerates with the wider range.

Verified ``make lfx_tests`` resolves cleanly on a host with both 3.13.12
and 3.14.5 installed; the focused extension slice runs to completion.

* Update __init__.py

* Update src/lfx/tests/unit/extension/migration/test_rewrite.py

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

* Update src/lfx/src/lfx/extension/loader/_plugins.py

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

* Update docs/docs/Deployment/deployment-extensions-production.mdx

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

* Update src/lfx/src/lfx/extension/loader/_orchestrator.py

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

* Update docs/docs/Develop/extensions-author-guide.mdx

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

* Update docs/docs/Develop/extensions-manifest.mdx

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

* fix: Coderabbit review suggestions

* Template updates

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* Tweaks to bundle hot reload

* [autofix.ci] apply automated fixes

* chore: Address review comments by @Cristhianzl

* [autofix.ci] apply automated fixes

* Update BUNDLE_API.md

* Update component_index.json

* Update component_index.json

* Update Structured Data Analysis Agent.json

* fix: Next round of review comments

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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-18 17:36:56 +00:00
5e9f0c37bc Merge branch 'release-1.9.3' into release-1.10.0
# Conflicts:
#	.secrets.baseline
#	docs/package.json
#	pyproject.toml
#	src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json
#	src/backend/base/pyproject.toml
#	src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py
#	src/frontend/package-lock.json
#	src/frontend/package.json
#	src/frontend/src/components/core/parameterRenderComponent/components/modelInputComponent/__tests__/ModelInputComponent.test.tsx
#	src/frontend/src/components/core/parameterRenderComponent/components/modelInputComponent/index.tsx
#	src/frontend/src/modals/modelProviderModal/hooks/useProviderConfiguration.ts
#	src/lfx/pyproject.toml
#	src/lfx/src/lfx/_assets/component_index.json
#	src/sdk/pyproject.toml
#	uv.lock
2026-05-14 21:20:42 -07:00
b695f97cd3 fix: More python 3.14 compatibility cleanup 2026-05-14 17:49:56 -07:00
f2b028f28b fix: update gunicorn constraint to allow version 26.x
- Update gunicorn constraint from <26.0.0 to <27.0.0
- Resolves dependency check failure with gunicorn 26.0.0
- Regenerate uv.lock with updated constraint
2026-05-14 18:01:34 -04:00
22e9003bec fix: correct version numbers for 1.9.3 patch release
- langflow-base: 0.10.0 -> 0.9.3
- lfx: 0.5.0 -> 0.4.3 (and dependency reference)
- sdk: 0.2.0 -> 0.1.3
2026-05-14 16:56:00 -04:00
e16c99d031 fix: upgrade langchain-classic to 1.0.7 (#13130)
chore: upgrade langchain-classic to 1.0.7

- Update version constraint from ~=1.0.0 to ~=1.0.7
- Fixes issues present in version 1.0.4
- Update uv.lock with new dependency resolution

Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
2026-05-14 16:51:35 -04:00
d5ef588e42 chore: bump versions to 1.9.3 2026-05-14 15:41:43 -04:00
a80cf1c649 chore: support Python 3.14 (#13085)
* feat: upgrade Docker images to Python 3.14 (experimental)

- Update pyproject.toml: requires-python from <3.14 to <3.15
- Update all 5 Dockerfiles to use Python 3.14:
  - Builder stage: python3.12-trixie-slim → python3.14-trixie-slim
  - Runtime stage: python:3.12-slim-trixie → python:3.14-slim-trixie

- src/backend/base/pyproject.toml
- docker/build_and_push_base.Dockerfile
- docker/build_and_push.Dockerfile
- docker/build_and_push_backend.Dockerfile
- docker/build_and_push_with_extras.Dockerfile
- docker/build_and_push_ep.Dockerfile

Python 3.14.5 was released on May 10, 2026. Upgrading to the latest
Python version should help reduce CVE vulnerabilities in Docker images.

This is an experimental change to test Python 3.14 compatibility:
- Docker images will use Python 3.14
- CI/CD workflows still test on Python 3.10-3.13
- Nightly build will validate if dependencies work with 3.14
- Can be reverted quickly if issues are found

- Monitor nightly build for failures
- If successful, update CI/CD workflows to add Python 3.14 to test matrix
- If failures occur, revert and investigate compatibility issues

* chore: support Python 3.14

Bump requires-python upper bound to <3.15 across langflow, langflow-base,
lfx, and langflow-sdk, and add 3.14 to CI test matrices so PRs are gated
on 3.14 compatibility.

Conditional pins for transitive deps without 3.14 wheels at the existing
caps:
- onnxruntime: >=1.26 on 3.14 (existing <1.24 cap retained for 3.10)
- faiss-cpu: >=1.13.2 on 3.14 (existing ==1.9.0.post1 retained for <3.14)

* chore: marker-gate IBM watsonx packages for Python 3.14

ibm-watsonx-ai 1.3.x cannot import on Python 3.14: its StrEnum subclasses
override __init__ in a way that conflicts with 3.14's reworked enum
__set_name__ path (TypeError on KnowledgeBaseFieldRole class creation).

Cap ibm-watsonx-ai, langchain-ibm, and the ibm-watsonx-orchestrate-*
extras at python_version<'3.14' until upstream adapts. Watsonx component
imports are already lazy, so this surfaces only at component-access time
on 3.14, where the existing ImportError handler in
lfx.components.ibm.__init__ degrades it gracefully.

test_model_utils.py imports ChatWatsonx at module top to verify
get_model_name resolves model_id; guard that import so the test
module skips on 3.14 instead of breaking collection.

* [autofix.ci] apply automated fixes

* chore: upgrade remaining Docker images to Python 3.14

build_and_push*.Dockerfile already moved to 3.14 in the merge from
feat/upgrade-python-3.14-docker-images. Apply the same bump to the
dev, devcontainer, and lfx Docker images so all in-repo Dockerfiles
share one Python version.

* [autofix.ci] apply automated fixes

* chore: gate 3.14-broken extras to python_version<'3.14'

cuga (and its transitive fastembed -> py-rust-stemmers source build),
altk/agent-lifecycle-toolkit (re-pulls ibm-watsonx-ai which was already
gated), langchain-pinecone, langwatch, ragstack-ai-knowledge-store, and
OpenDsStar all pin themselves below 3.14 upstream. Without a marker
guard, the workspace lock still tries to install them and a Docker
`uv sync` then attempts source builds that require Rust (CI Docker
test failure with py-rust-stemmers 0.1.5).

Add python_version<'3.14' (or <'3.13' for ragstack) to each pin so
those packages are simply omitted from the 3.14 install set until
upstream catches up. uv pip check is now clean on 3.14.2.

* test: skip test_altk_agent on Python 3.14

altk (agent-lifecycle-toolkit) is gated to python_version<'3.14'
upstream and now via the langflow-base [altk] extra marker. The test
imports altk at module top to exercise ALTKAgentComponent; guard the
import so collection skips on 3.14 instead of failing.

* test: skip remaining altk tests on Python 3.14

Three more test modules import lfx.base.agents.altk_* at module top,
which transitively imports altk. Add the same module-level skip guard
as test_altk_agent.py:
- test_altk_agent_logic.py
- test_altk_agent_tool_conversion.py
- test_conversation_context_ordering.py

* fix(calculator): replace removed ast.Num with ast.Constant for Python 3.14

ast.Num was deprecated in Python 3.8 in favor of ast.Constant and
removed entirely in 3.14. The calculator tool and its core walker
crashed on 3.14 with 'module ast has no attribute Num'.

Switch the isinstance checks to ast.Constant + isinstance(node.value,
(int, float)), and drop the now-dead ast.Num backwards-compat branch
in calculator_core.py (the ast.Constant branch already handles every
input it would have matched). Update the parser unit-test fixtures
to construct ast.Constant nodes.

* [autofix.ci] apply automated fixes

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

* test: skip LangWatch HTTP instrumentation tests on Python 3.14

langwatch is gated to python_version<'3.14' upstream. The
TestLangWatchHttpInstrumentation class patches langwatch.setup and
langwatch.trace inside a fixture, which requires langwatch to be
importable; on 3.14 the test errors with ModuleNotFoundError.

Guard the class with a skipif on langwatch availability.

* test: allow IBM and altk components to be missing on Python 3.14

test_all_modules_importable enforces that every component in __all__
imports cleanly. On 3.14 the ibm-watsonx-ai, langchain-ibm, and altk
packages are gated upstream and intentionally not installed, so the
WatsonxAI, WatsonxEmbeddings, and ALTKAgent components fail to import
as designed.

- test_all_components_in_categories_importable: accept a known-gated
  deny-list on 3.14 instead of failing.
- test_all_lfx_component_modules_directly_importable: extend the
  existing 'missing optional dependency' allowlist with altk,
  langchain_ibm, and ibm_watsonx_ai.

* fix(lfx): pass ensure_exists to user_cache_dir for Python 3.14

Python 3.14 tightened PurePath.__init__ to reject unknown keyword
arguments. The KeyedWorkerLockManager constructor was passing
ensure_exists=True to Path() instead of user_cache_dir(), which
silently worked on 3.10-3.13 but raises TypeError on 3.14 and also
meant the cache directory was never actually being created.

Move the kwarg to user_cache_dir() where it belongs and update the
two unit tests that asserted the buggy call shape.

* [autofix.ci] apply automated fixes

* test: accept either ZIP or JSON error path on Python 3.14

Python 3.14's zipfile.is_zipfile() now validates the central-directory
signature in addition to EOCD, so the garbage+EOCD payload no longer
passes the is_zipfile() dispatch in the /flows/upload/ route. The
endpoint still returns 400 with a descriptive detail (now from the JSON
branch); only the message wording differs, which the test was asserting
verbatim.

* fix(lfx): normalize cors_origins ['*'] back to '*' on Python 3.14

Pydantic-settings on Python 3.14 parses the env var '*' into ['*']
before the cors_origins field validator runs (the list[str] | str union
resolves differently than on 3.10-3.13). Collapse that back to the
bare-string wildcard so downstream consumers — including
warn_about_future_cors_changes and the test suite — see the same shape
on every supported Python version.

---------

Co-authored-by: vijay kumar katuri <vijay.katuri@ibm.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
(cherry picked from commit 1955f8fae5)
2026-05-13 22:23:39 +00:00
1955f8fae5 chore: support Python 3.14 (#13085)
* feat: upgrade Docker images to Python 3.14 (experimental)

## Changes
- Update pyproject.toml: requires-python from <3.14 to <3.15
- Update all 5 Dockerfiles to use Python 3.14:
  - Builder stage: python3.12-trixie-slim → python3.14-trixie-slim
  - Runtime stage: python:3.12-slim-trixie → python:3.14-slim-trixie

## Files Updated
- src/backend/base/pyproject.toml
- docker/build_and_push_base.Dockerfile
- docker/build_and_push.Dockerfile
- docker/build_and_push_backend.Dockerfile
- docker/build_and_push_with_extras.Dockerfile
- docker/build_and_push_ep.Dockerfile

## Rationale
Python 3.14.5 was released on May 10, 2026. Upgrading to the latest
Python version should help reduce CVE vulnerabilities in Docker images.

## Testing Strategy
This is an experimental change to test Python 3.14 compatibility:
- Docker images will use Python 3.14
- CI/CD workflows still test on Python 3.10-3.13
- Nightly build will validate if dependencies work with 3.14
- Can be reverted quickly if issues are found

## Next Steps
- Monitor nightly build for failures
- If successful, update CI/CD workflows to add Python 3.14 to test matrix
- If failures occur, revert and investigate compatibility issues

* chore: support Python 3.14

Bump requires-python upper bound to <3.15 across langflow, langflow-base,
lfx, and langflow-sdk, and add 3.14 to CI test matrices so PRs are gated
on 3.14 compatibility.

Conditional pins for transitive deps without 3.14 wheels at the existing
caps:
- onnxruntime: >=1.26 on 3.14 (existing <1.24 cap retained for 3.10)
- faiss-cpu: >=1.13.2 on 3.14 (existing ==1.9.0.post1 retained for <3.14)

* chore: marker-gate IBM watsonx packages for Python 3.14

ibm-watsonx-ai 1.3.x cannot import on Python 3.14: its StrEnum subclasses
override __init__ in a way that conflicts with 3.14's reworked enum
__set_name__ path (TypeError on KnowledgeBaseFieldRole class creation).

Cap ibm-watsonx-ai, langchain-ibm, and the ibm-watsonx-orchestrate-*
extras at python_version<'3.14' until upstream adapts. Watsonx component
imports are already lazy, so this surfaces only at component-access time
on 3.14, where the existing ImportError handler in
lfx.components.ibm.__init__ degrades it gracefully.

test_model_utils.py imports ChatWatsonx at module top to verify
get_model_name resolves model_id; guard that import so the test
module skips on 3.14 instead of breaking collection.

* [autofix.ci] apply automated fixes

* chore: upgrade remaining Docker images to Python 3.14

build_and_push*.Dockerfile already moved to 3.14 in the merge from
feat/upgrade-python-3.14-docker-images. Apply the same bump to the
dev, devcontainer, and lfx Docker images so all in-repo Dockerfiles
share one Python version.

* [autofix.ci] apply automated fixes

* chore: gate 3.14-broken extras to python_version<'3.14'

cuga (and its transitive fastembed -> py-rust-stemmers source build),
altk/agent-lifecycle-toolkit (re-pulls ibm-watsonx-ai which was already
gated), langchain-pinecone, langwatch, ragstack-ai-knowledge-store, and
OpenDsStar all pin themselves below 3.14 upstream. Without a marker
guard, the workspace lock still tries to install them and a Docker
`uv sync` then attempts source builds that require Rust (CI Docker
test failure with py-rust-stemmers 0.1.5).

Add python_version<'3.14' (or <'3.13' for ragstack) to each pin so
those packages are simply omitted from the 3.14 install set until
upstream catches up. uv pip check is now clean on 3.14.2.

* test: skip test_altk_agent on Python 3.14

altk (agent-lifecycle-toolkit) is gated to python_version<'3.14'
upstream and now via the langflow-base [altk] extra marker. The test
imports altk at module top to exercise ALTKAgentComponent; guard the
import so collection skips on 3.14 instead of failing.

* test: skip remaining altk tests on Python 3.14

Three more test modules import lfx.base.agents.altk_* at module top,
which transitively imports altk. Add the same module-level skip guard
as test_altk_agent.py:
- test_altk_agent_logic.py
- test_altk_agent_tool_conversion.py
- test_conversation_context_ordering.py

* fix(calculator): replace removed ast.Num with ast.Constant for Python 3.14

ast.Num was deprecated in Python 3.8 in favor of ast.Constant and
removed entirely in 3.14. The calculator tool and its core walker
crashed on 3.14 with 'module ast has no attribute Num'.

Switch the isinstance checks to ast.Constant + isinstance(node.value,
(int, float)), and drop the now-dead ast.Num backwards-compat branch
in calculator_core.py (the ast.Constant branch already handles every
input it would have matched). Update the parser unit-test fixtures
to construct ast.Constant nodes.

* [autofix.ci] apply automated fixes

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

* test: skip LangWatch HTTP instrumentation tests on Python 3.14

langwatch is gated to python_version<'3.14' upstream. The
TestLangWatchHttpInstrumentation class patches langwatch.setup and
langwatch.trace inside a fixture, which requires langwatch to be
importable; on 3.14 the test errors with ModuleNotFoundError.

Guard the class with a skipif on langwatch availability.

* test: allow IBM and altk components to be missing on Python 3.14

test_all_modules_importable enforces that every component in __all__
imports cleanly. On 3.14 the ibm-watsonx-ai, langchain-ibm, and altk
packages are gated upstream and intentionally not installed, so the
WatsonxAI, WatsonxEmbeddings, and ALTKAgent components fail to import
as designed.

- test_all_components_in_categories_importable: accept a known-gated
  deny-list on 3.14 instead of failing.
- test_all_lfx_component_modules_directly_importable: extend the
  existing 'missing optional dependency' allowlist with altk,
  langchain_ibm, and ibm_watsonx_ai.

* fix(lfx): pass ensure_exists to user_cache_dir for Python 3.14

Python 3.14 tightened PurePath.__init__ to reject unknown keyword
arguments. The KeyedWorkerLockManager constructor was passing
ensure_exists=True to Path() instead of user_cache_dir(), which
silently worked on 3.10-3.13 but raises TypeError on 3.14 and also
meant the cache directory was never actually being created.

Move the kwarg to user_cache_dir() where it belongs and update the
two unit tests that asserted the buggy call shape.

* [autofix.ci] apply automated fixes

* test: accept either ZIP or JSON error path on Python 3.14

Python 3.14's zipfile.is_zipfile() now validates the central-directory
signature in addition to EOCD, so the garbage+EOCD payload no longer
passes the is_zipfile() dispatch in the /flows/upload/ route. The
endpoint still returns 400 with a descriptive detail (now from the JSON
branch); only the message wording differs, which the test was asserting
verbatim.

* fix(lfx): normalize cors_origins ['*'] back to '*' on Python 3.14

Pydantic-settings on Python 3.14 parses the env var '*' into ['*']
before the cors_origins field validator runs (the list[str] | str union
resolves differently than on 3.10-3.13). Collapse that back to the
bare-string wildcard so downstream consumers — including
warn_about_future_cors_changes and the test suite — see the same shape
on every supported Python version.

---------

Co-authored-by: vijay kumar katuri <vijay.katuri@ibm.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-13 22:23:39 +00:00
ea29bcc6b9 feat: Redis-backed job queue for multi-worker deployments (#12588)
* feat: implement Redis job queue and fakeredis support
- Refactored the job queue service to support Redis-backed management for cross-worker scaling.
- Added environment variables for configuration:
    - `LANGFLOW_JOB_QUEUE_TYPE=redis`
    - `LANGFLOW_REDIS_QUEUE_DB=1`
- Updated job ownership methods to be asynchronous for improved concurrency handling.
- Enhanced Redis cache service with namespacing via key prefixes.
- Introduced `fakeredis` for in-memory Redis simulation in testin>
- Added comprehensive unit tests for Redis job queue components.

* fix: run  experimental warning for RedisCache usage only once

- Introduced a mechanism to emit a one-time warning for the RedisCache experimental feature during server runtime.
- The warning is logged only if no other worker has already emitted it, ensuring clarity for users regarding the experimental status of RedisCache.
- The implementation includes a temporary file check to prevent multiple warnings across different processes.

* docs: document environment variables for worker management
- Added documentation for LANGFLOW_GUNICORN_PRELOAD to explain preloading for better performance.
- Detailed the use of LANGFLOW_JOB_QUEUE_TYPE for specifying backends (e.g., Redis).
- Included LANGFLOW_REDIS_QUEUE_DB to define the database index for job queues.
- Updated the "High-Load Environments" guide with these optimal configurations.

* docs: updated 'High-load and multi-worker environments' section

* feat: enhance RedisJobQueueService with consumer wrapper management
- Introduced a caching mechanism for Redis stream consumers to optimize job data retrieval.
- Added methods to manage consumer wrappers, ensuring they are reused across sequential polls.
- Implemented cleanup logic to cancel and clear consumer wrappers during job cleanup and service stop.
- Expanded unit tests to verify consumer wrapper reuse and cleanup behavior.

* fix: ensure Redis keys are deleted during job cleanup even on cancellation

- Updated the cleanup_job method in RedisJobQueueService to guarantee Redis keys are removed even if the job cleanup is interrupted by a CancelledError.
- Added a new unit test to verify that Redis keys are deleted correctly when cleanup is called during task cancellation.

* fix: manage connection check task in RedisJobQueueService

- Added handling for the connection check task in the stop method to ensure it is properly cancelled and awaited if still running.
- This change improves resource management and prevents potential issues during service shutdown.

* fix: handle unpublished sentinel requeue on cancellation in RedisJobQueueService

- Updated the job processing logic to ensure that if a job is cancelled during the xadd operation, the unpublished sentinel is requeued instead of being dropped.
- Introduced a new unit test to verify this behavior, ensuring robustness in job handling during cancellations.

* fix: improve Redis job queue service with enhanced configuration and cleanup

- Added atexit cleanup to remove stale temporary files for RedisCache.
- Refactored Redis job queue service to use shared constants for stream prefixes, improving maintainability.
- Updated type hints for better clarity and consistency in RedisQueueWrapper and RedisJobQueueService.
- Enhanced error handling with configurable backoff for transient read failures.

* fix: enhance Redis job queue service with maxlen configuration for xadd

- Updated the xadd method in RedisJobQueueService to include maxlen and approximate parameters, improving stream management and preventing excessive memory usage.

* fix: enhance job ownership retrieval in RedisJobQueueService

- Updated the get_job_owner method to refresh the Redis key TTL on successful lookups, ensuring long-running jobs maintain their ownership anchor.
- Improved code clarity by extracting the owner key into a variable and adding detailed docstring explanations for better understanding of the TTL management.

* fix: improve job ownership handling in cleanup_job method

- Enhanced the cleanup_job method in RedisJobQueueService to accurately capture job ownership before deleting Redis keys, preventing potential data corruption in multi-worker scenarios.
- Added comments for clarity on ownership logic and its implications during job cleanup.

* fix: optimize TTL management in RedisJobQueueService

- Introduced periodic TTL refresh logic in the _bridge_to_redis method to enhance Redis stream management, reducing round-trips and improving throughput.
- Added constants for TTL refresh events and seconds to maintain clarity and configurability.
- Updated event handling to ensure TTL is refreshed appropriately based on event count and time elapsed.

* fix: improve event handling in flow response management

- Removed unnecessary error handling for missing event tasks in get_flow_events_response, allowing for smoother operation when no task exists.
- Updated create_flow_response to handle optional event_task parameter, ensuring proper cleanup during disconnections.
- Added unit tests to verify behavior when event tasks are missing, enhancing robustness in streaming scenarios.

* fix: enhance RedisQueueWrapper with startup grace period and stream observation

- Added a startup grace period to prevent premature end-of-stream signals when the producer has not yet issued its first XADD.
- Introduced a flag to track whether the stream has been observed, improving the handling of early polling scenarios.
- Updated logic to ensure proper handling of stream existence checks and logging for better debugging during job processing.

* fix: implement cleanup for old cross-worker job queues in RedisJobQueueService

- Added a new method to clean up done cross-worker consumer wrappers that are not owned by the current worker, ensuring proper resource management.
- Enhanced the existing cleanup logic to prevent memory leaks by explicitly pruning stale entries from the consumer wrappers dictionary.
- Improved logging to provide better visibility into the cleanup process for cross-worker jobs.

* fix: enhance job handling in JobQueueService with guarded task execution

- Updated the start_job method to accept a Coroutine type for task_coro, ensuring type safety.
- Introduced a new _guarded_task method to wrap job coroutines, guaranteeing that unhandled exceptions emit an error event and write a sentinel to the Redis Stream, improving reliability in job processing.
- Enhanced documentation to clarify the behavior of the new task handling mechanism and its implications for cross-worker consumers.

* fix: improve client disconnection handling in create_flow_response

- Added logging for scenarios where a client disconnects without an associated event_task, clarifying that the producer will continue running until the build completes.
- Documented the limitation regarding cross-worker passive disconnects and the need for a Redis side-channel for proper cancellation, enhancing observability in the logs.

* fix: enhance RedisQueueWrapper to manage initial read state and buffer behavior

- Introduced a flag to track the completion of the first XREAD call, ensuring proper buffer management during the initial read phase.
- Updated the empty method to reflect the state of the buffer accurately, preventing premature exits from the drain loop until the first read is complete.
- Improved documentation to clarify the behavior of the new flag and its impact on job processing.

* fix: clarify RedisQueueWrapper behavior in tests for buffer state and no-op operations

- Updated test documentation to explain the behavior of the empty() method in relation to the first XREAD completion, ensuring accurate understanding of buffer state during job processing.
- Adjusted assertions in tests to reflect the intended behavior of the RedisQueueWrapper, specifically regarding the no-op nature of put_nowait and its impact on the internal buffer.

* fix: update dependencies in pyproject.toml and uv.lock

- Added fakeredis dependency with a minimum version of 2.0.0 to both pyproject.toml and uv.lock files.
- Ensured proper formatting and comments in pyproject.toml for clarity on onnxruntime version constraints.

* fix: enhance RedisQueueWrapper and job queue handling for improved cancellation and buffer management

- Introduced a structural protocol `_CancellableQueue` to ensure queues can handle cancellation properly during client disconnects.
- Updated `RedisQueueWrapper` to implement this protocol, allowing for graceful cancellation of background tasks.
- Added a maximum size limit to the internal buffer to prevent unbounded memory usage and ensure backpressure on slow consumers.
- Implemented a done callback to handle unexpected fill task crashes, ensuring consumers are not left hanging indefinitely.
- Enhanced unit tests to verify compliance with the new protocol and the behavior of the buffer under various conditions.

* fix: RedisQueueWrapper sentinel delivery, error time-bound, and cancel response

- Deliver end-of-stream sentinel on fill-task cancellation (_on_fill_done now
  handles both cancelled and exception paths so consumers are never left hanging)
- Add _error_start time-bound to xread and exists() error loops: after
  _STARTUP_GRACE_S seconds of continuous Redis errors the sentinel is delivered
  instead of retrying forever
- Advance _last_id cursor only after buffer.put() succeeds so cancellation mid-put
  does not silently skip that message in the Redis cursor
- Return False from cancel_flow_build when event_task is None (cross-worker path)
  so the HTTP response correctly reports success=False instead of false success

* [autofix.ci] apply automated fixes

---------

Co-authored-by: ogabrielluiz <gabriel@langflow.org>
Co-authored-by: Jordan Frazier <jordan.frazier@datastax.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-13 21:09:51 +00:00
81913eb668 fix: add [proxy] extra to litellm dependency for langflow-ide (#12235)
* fix: add apscheduler and cryptography for litellm proxy_server imports

When langflow-ide logs through litellm (e.g. to langfuse), litellm imports
its proxy server module, which requires `apscheduler` and `cryptography` at
runtime. The natural fix would be `litellm[proxy]`, but that extra pins
boto3>=1.40.76, which collides with our `aioboto3` transitives on
release-1.10.0. Adding the two missing modules directly keeps the install
working without taking on the rest of the proxy server runtime.

Fixes #12228

* test: guard apscheduler and cryptography in litellm extra

Asserts the `litellm` optional-dependency group keeps the runtime modules
needed for langfuse logging via litellm.proxy.proxy_server (#12228).

---------

Co-authored-by: Jah-yee Agent <agent@openclaw.ai>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
2026-05-11 12:17:16 -07:00
b3f3ba109c fix: OpenTelemetry trace context propagation (#12962)
* deps: add opentelemetry http client instrumentation packages

Add opentelemetry-instrumentation-requests and opentelemetry-instrumentation-urllib3
to enable W3C TraceContext propagation on outgoing HTTP calls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(tracing): propagate W3C TraceContext on outgoing HTTP calls

Instrument requests and urllib3 HTTP clients with the tracer provider
so that traceparent headers are injected on outgoing HTTP requests
(e.g., to LLM APIs). This enables end-to-end distributed tracing.

Both Arize Phoenix and LangWatch tracers now:
- Call _instrument_http_clients() during setup
- Call _uninstrument_http_clients() during cleanup
- Handle missing packages gracefully with debug logging

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(tracing): add tests for HTTP client trace context propagation

Verify that:
- RequestsInstrumentor and URLLib3Instrumentor are called during tracer setup
- Instrumentors are uninstrumented during cleanup
- traceparent headers are injected with valid W3C format on outgoing requests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(tracing): address ruff linting issues in trace context propagation

- Use contextlib.suppress instead of try-except-pass in uninstrument methods
- Fix nested with statements using parenthesized context managers
- Fix unused arguments by prefixing with underscore
- Add timeout to requests.get calls
- Skip integration tests that mock at wrong layer (Session.send bypasses OTel)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(tracing): make HTTP client instrumentation process-scoped with ref-counting

The OpenTelemetry RequestsInstrumentor and URLLib3Instrumentor monkeypatch
globally, but tracers were calling instrument()/uninstrument() per instance.
If multiple graph runs overlapped, the first run to end() would uninstrument
globally and break context propagation for other active runs.

Changes:
- Add HTTPClientInstrumentationManager singleton with reference counting
- enable() increments count, instruments only on first call
- disable() decrements count, uninstruments only when count reaches zero
- Replace silent exception suppression with proper logging for debugging

Addresses PR review feedback from Qodo.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-11 08:21:28 -07:00
6e4475c139 fix: Unblock nightly install on macOS x86_64 due OpenDsStar (#13061) 2026-05-11 12:11:44 -03:00
da798a525d feat(components): Add Code Agents (CodeAct agent and OpenDsStar agent) and file ingestion components with supporting fixes (#12713)
* initial draft

* update DS Star agent

* chore(deps): use OpenDsStar 1.0.1 from PyPI

* refactor: move OpenDsStar to namespace, update imports, remove agents shim

* update open ds star version

* improved logging

* improved logging

* fix: propagate source file path for DataFrame inputs in ingestion components

DataFrame from CSV/Excel reads now carries the source file path via
pandas attrs, so IngestionDescriber and FileContentRetriever can
resolve the original file instead of searching per-row data keys.

* feat: add files_ingestion component bundle and bump OpenDsStar to 1.0.8

Register files_ingestion as a sidebar bundle in the frontend and
component registry. Update OpenDsStar dependency from 1.0.6 to 1.0.8.

* Add file content retriever component and tests

* Fix: Add tool_mode=True to FileContentRetriever outputs to prevent execution during build phase

* Fix: Return empty DataFrame instead of raising error when file_path not provided during build

* Update file content retriever component

* refactor: rename IngestionDescriberComponent to FileDescriptionGeneratorComponent

- Renamed class from IngestionDescriberComponent to FileDescriptionGeneratorComponent
- Updated component name attribute and display name
- Renamed files: ingestion_describer.py -> file_description_generator.py
- Renamed test file: test_ingestion_describer.py -> test_file_description_generator.py
- Updated all imports and references
- Rebuilt component index

BREAKING CHANGE: Component class name changed. Existing flows using IngestionDescriberComponent will need to be updated.

* fix: improve FileContentRetriever tool descriptions for CodeAct agent

- Add explicit warnings that tools expect string file paths only
- Clarify that search results/Data objects should not be passed
- Change error handling to raise ValueError (agents can handle exceptions)
- Add build-phase safety (return empty results when no path provided)
- Update tests to expect exceptions instead of error messages

This fixes CodeAct agent failures where it was trying to pass search
results (list of Data objects) to retrieve_content_as_dataframe()
instead of extracting the file path string first.

* fix: File Content Retriever now finds DataFrames with file_path in columns

- Added caching for file maps to avoid rebuilding on each method call
- Enhanced _get_file_maps() to check both attrs['source_file_path'] and 'file_path' column
- Fixes agent issue where DataFrame from Read File component couldn't be found
- Added test for DataFrame with file_path in columns scenario
- All 30 tests pass (26 passed, 4 skipped)

* fix: use to_csv() instead of to_string() for DataFrame text representation

Fixes agent hanging issue when retrieving file content as DataFrame.

The problem was that to_string() creates a formatted table representation
that cannot be parsed as CSV. When agents called retrieve_content_as_dataframe(),
it would try to parse this formatted text with pd.read_csv(), causing a
ParserError and infinite retry loop.

Changed to use to_csv(index=False) which produces valid CSV format that can
be parsed back into a DataFrame when needed.

- Maintains optimal performance by returning original DataFrame from dataframe_map
- Only uses CSV text representation as fallback
- All 26 tests pass
- Works correctly for both text and tabular files

* add agent template

* improve agent template

* bump OpenDsStar to 1.0.10 and update ingestion components

Upgrade OpenDsStar dependency from 1.0.8 to 1.0.10 in both langflow-base
and lfx pyproject.toml. Update file content retriever, file description
generator, component tool, and custom component with related improvements.
Expand test coverage for file content retriever.

* fix FileContentRetriever multi-file data retrieval and add code_timeout

The FileContentRetriever was broken for the multi-file case (when Read File
outputs a DataFrame with file_path + text columns). Three bugs were fixed:

1. Multi-file DataFrame mapped to wrong data: When Read File produced a
   summary DataFrame (one row per file, columns = [file_path, text]), the
   retriever mapped each file_path to the entire 2-row summary DataFrame
   instead of extracting per-file content. The agent would get 2 rows
   instead of thousands of actual data rows. Fixed by iterating rows and
   extracting each file's text into text_map.

2. CSV text now eagerly parsed into DataFrames: For .csv/.tsv files in
   text_map that lack a pre-built DataFrame, _get_file_maps() now parses
   the text into a DataFrame eagerly during initialization. This makes
   retrieve_content_as_dataframe work for the multi-file case without
   needing upstream structured DataFrames.

3. Maps built once, not per tool call: The file maps were rebuilt on every
   tool call because component_tool.py deepcopy's the component, and the
   maps were only built lazily during retrieval. Now the early-return paths
   (empty file_path) eagerly call _get_file_maps() during component build
   time, so the cached maps survive deepcopy. This is critical for
   scalability with hundreds of large files.

Additional changes:
- Removed _is_likely_file_content heuristic that was incorrectly filtering
  out valid file content
- Removed "Message" from input_types (was never handled)
- Removed redundant inner import of DataFrame
- Shortened error messages (cap available files to 5)
- Added warning log for unsupported input types
- Lazy CSV conversion: no longer eagerly converts structured DataFrames to
  CSV text in _get_file_maps, only converts on demand in retrieve_content
- Added code_timeout input to OpenDsStarAgentComponent (default 60s, was
  hardcoded 30s) to prevent timeouts with large datasets
- Added 19 unit tests covering all retrieval paths, caching, and the
  multi-file bug reproduction

* disable as_dataframe tool from vector store to fix agent confusion

The Chroma vector store's as_dataframe output was exposed as an agent tool,
returning a 2-row file index DataFrame (file_path + text columns). The agent
mistook this for actual data and tried to query 'price' on it, causing every
query to fail with KeyError.

Set tool_mode=False on the as_dataframe output so only search_documents is
exposed as a tool from the vector store. The agent now follows the correct
workflow: search_documents → get file path → retrieve_content_as_dataframe.

* Revert "disable as_dataframe tool from vector store to fix agent confusion"

This reverts commit e21c5dc649.

* bump OpenDsStar to 1.0.15, improve ingestion component tool descriptions and caching

- Upgrade OpenDsStar dependency from 1.0.10 to 1.0.15
- Add __deepcopy__ to FileContentRetriever to preserve cached maps across tool invocations
- Add JSON format support for eager DataFrame parsing
- Improve tool docstrings on FileContentRetriever and VectorStore for better agent usage
- Enable tool_mode on VectorStore search and table outputs

* support Message input in FileContentRetriever and FileDescriptionGenerator

- Add file_path to Message metadata in base_file._extract_file_metadata
- Accept Message type in FileContentRetriever.file_data input and handle
  it in _build_file_maps to extract file_path and text content
- Handle Message input in FileDescriptionGenerator to extract file_path
- Add tests for Message input: basic, missing file_path, and mixed types

* fix FileContentRetriever not appearing in component sidebar

- Remove forward reference to FileContentRetrieverComponent in __deepcopy__
  that broke the exec-based template builder, silently preventing registration
- Remove unnecessary cast() call in __deepcopy__
- Regenerate component_index.json (362 -> 363 components)
- Update template JSON edge handles to include Message in input_types

* add persistent directory, real-time logs, tool descriptions, and Merge Flows component

FileContentRetriever:
- Add persistent directory support for saving/loading text and DataFrame maps to disk
- Split text storage into individual files (texts/) instead of single JSON
- Guard against None file_data during tool deepcopy calls
- Warn when maps are empty after building
- Make Persistent Directory a visible (non-advanced) input

FileDescriptionGenerator:
- Switch from subprocess.run to Popen with real-time stderr streaming
- Add configurable timeout input (default 1800s, was hardcoded 600s)
- Stream subprocess progress to UI via self.log()

Tool descriptions:
- Add info field to Output model (excluded from serialization to avoid template pollution)
- Fix stale tool metadata overwriting fresh descriptions in component.py
- Each tool output now gets its own description instead of generic component description

New components:
- Add Merge Flows component to trigger multiple upstream flows from a single node

Tests:
- Add persistence tests (round-trip, skip duplicates, add new files, corrupted JSON, regression)
- Update FileDescriptionGenerator tests for Popen-based subprocess

* update Structured Data Agent template from UI re-export

* update Structured Data Agent template

* update Structured Data Agent template

* update Structured Data Agent template

* update Structured Data Agent template

* update Structured Data Agent template

* fix chardet perf, pipe deadlock, auto-sync, Chroma errors, and ingestion failure detection

Performance:
- Fix chardet.detect() scanning entire files (800s for 1.5GB) — sample first 100KB only
- Default ascii detection to utf-8 (superset) to handle non-ASCII chars beyond sample
- Fix subprocess stdout pipe deadlock — drain both stdout and stderr concurrently via select

FileContentRetriever:
- Add auto-sync: remove persisted entries for files no longer in file_data input
- Clean up orphaned files from persistent directory on save

FileDescriptionGenerator:
- Fail with clear error when descriptions are not generated (grouped by error reason)
- Increase default timeout from 1800s to 3600s via _DEFAULT_TIMEOUT_SECONDS constant
- Remove fast-path code (moved to OpenDsStar)

Chroma:
- Add clear error messages for missing persist directory, corrupted DB, and initialization failures
- Recreate persist directory if deleted between runs

Other:
- Add opendsstar_cache to .gitignore

* Chore(release): merge release 1.9.0 into main (#12710)

* test: add upgrade migration check to ci (#12061)

* Add upgrade migration check to ci

* [autofix.ci] apply automated fixes

* Add fetch step

* ruff

* Add merge migration

* Revert "Add merge migration"

This reverts commit fd32424739.

backups

* coderabbit suggestions

  1. Shell hardening in workflow - set -euo pipefail, full path grep, quoted variables
  2. _WORKSPACE_ROOT extracted as module constant (also addresses Cristhianzl's review comment about parents[5] duplication)
  3. git missing returns None instead of raising FileNotFoundError
  4. # noqa: S603 added to subprocess.run (fixes the Ruff CI failure)
  5. FK noise filtering now also compares target table/column, not just ondelete/onupdate
  6. Removed redundant git fetch origin main step (fetch-depth: 0 already fetches all branches)
  7. Deduplicated Alembic config creation in _get_main_branch_head (moved before the if branch)
  8. Simplified dict type hints (removed unnecessary dict[tuple, object])

* test: improve migration tests from PR review feedback

- Narrow broad except clause to only wrap subprocess.run call
- Add specific error messages for multi-head and unresolvable revisions
- Remove redundant hardcoded schema test (covered by compare_metadata)
- Fix SQLite FK noise filter to skip ondelete/onupdate comparison
- Add downgrade verification to test_upgrade_from_main_branch
- Add test file and workflow to CI trigger paths
- Add prompt for follow-up PostgreSQL migration test PR

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

* add engine check on downgrade

* [autofix.ci] apply automated fixes

* fix: harden CI error handling and test robustness

- Set validationPassed=false when validator crashes so CI fails instead of passing silently
- Wrap GitHub API calls in try-catch so comment-posting failures don't mask validation results
- Preserve git stderr in warnings for better CI debugging
- Add defensive handling for unexpected FK constraint shapes in SQLite noise filter
- Clean up SQLite WAL/SHM/journal companion files in test teardown

* Add explicit fetch to main

* ruff

* [autofix.ci] apply automated fixes

* Add sqlite filter tests and remove redundant fetch

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(deployments): unify payload passthrough from api to adapter (#12190)

* feat(deployments): unify dynamic payload passthrough across api and adapter

* use datatime.timezone for python3.10 compatibility

* use appropriate type vars in slots and sanitize error message

* tweaks to schemas

* use policy to avoid dump churn

* fix: allow clearing Max Tokens field with Backspace/Delete (#12198)

* fix: allow clearing Max Tokens field with Backspace/Delete

Empty string input was being converted to 0 via Number(""), which
triggered the min-value guard and snapped the field back to 1 before
onChange could propagate. Adding an early return for empty input lets
the field clear correctly, propagating null (no limit) downstream.

* test: add IntComponent tests for handleInputChange clearing behavior

Covers the regression where Backspace/Delete was blocked by the
min-value guard, and verifies that below-min values still clamp
correctly.

* fix: Resolve CodeQL false positives for path injection and URL substring sanitization (#12201)

* fix: Add explicit left/right DataFrame inputs for merge operations (#12177)

* add explicit left/right DataFrame inputs for merge operations

* [autofix.ci] apply automated fixes

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

* [autofix.ci] apply automated fixes

* ruff style and checker fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: add dict to allowlist preventing TableInput data loss (#12074)

* fix: add dict to allowlist preventing TableInput data loss

Co-Authored-By: DeyLak <DeyLak@users.noreply.github.com>

* test: add regression test for TableInput list[dict] preservation

Regression test for: https://github.com/langflow-ai/langflow/issues/12062

Co-Authored-By: DeyLak <DeyLak@users.noreply.github.com>

---------

Co-authored-by: DeyLak <DeyLak@users.noreply.github.com>
Co-authored-by: Cristhian Zanforlin Lousa <cristhian.lousa@gmail.com>

* chore: update pyproject versions 1.9.0

update pyproject versions 1.9.0

* fix: 1.9.0 nightly

1.9.0 nightly fix

* feat: add wxO deployment adapter (#12079)

* checkout wxo deployment adapter implementation

* checkout wxo deps and flow reqs impl

* clean up / minor refactor with updated tests

* major refactor: split up the implementation into folders and files

* clean up logic

* refactor and clean up of execution logic, improve type safety of "retry_create" helper, and remove dead code

* remove unused wxo service file

* remove "provider_name" arg and references

* fix: harden watsonx orchestrate deployment adapter for PR readiness

- Fix rollback AttributeError when agent_create_response is None
- Fix NoneType access on params in list() when called without params
- Fix inconsistent error types: use DeploymentNotFoundError in get/update
- Fix typo "occured" -> "occurred" in all error prefix messages
- Fix variable shadowing of fastapi.status in get_status()
- Fix pre-existing test bugs (wrong exception types, stale method refs)
- Fix e2e monkey-patching of non-existent service methods
- Add structured logging to create, delete, retry, and rollback flows
- Add jitter to retry backoff to avoid thundering herd
- Add __repr__ to WxOCredentials that fully masks the API key
- Extract hard-coded LLM model string to DEFAULT_WXO_AGENT_LLM constant
- Remove commented-out snapshot update code
- Expand test coverage from 24 to 75 tests covering retry logic,
  service methods, client auth, utilities, execution/status helpers,
  and artifact roundtrip

* fix(deployment): fix bugs and harden watsonx orchestrate adapter

- Fix update method silently discarding changes instead of sending them
  to the WXO API
- Wrap all synchronous SDK calls in asyncio.to_thread to avoid blocking
  the event loop
- Add error handling to get_status (was propagating raw exceptions)
- Use DeploymentType enum values instead of raw strings for
  SUPPORTED_ADAPTER_DEPLOYMENT_TYPES
- Fix type annotations in list method (list -> set)
- Fix typo in comment (reccomend -> recommend)
- Remove dead code: extract_agent_connection_ids,
  require_exclusive_resource, require_non_empty_string,
  resolve_health_environment_id, fetch_agent_release_status,
  normalize_release_status, resolve_lfx_runner_requirement,
  _pin_requirement_name, sync_langflow_tool_connections,
  create_langflow_flow_tool, resolve_snapshot_connections, and unused constants
- Make assert_create_resources_available and validate_connection async
- Make create_agent_run and get_agent_run async
- Add tests for list_types, get_status error handling, and update
  side-effects
- Update existing tests for async function signatures

* actually remove the dead code from tools.py

* properly await "validate_connection"

* update e2e test file

* add more scenarios to e2e test runner

* refactor(watsonx-orchestrate): improve WxOClient encapsulation and error messages
Encapsulate SDK private method access and endpoint paths inside
WxOClient wrappers so callers never handle raw paths or touch internal
_get/_post methods. Route all private HTTP calls through a single
_base client auto-created in __post_init__, removing the externally
constructed `base` field.
Additionally fix double-period and redundant text in error messages
produced by the ErrorPrefix + handler pattern, and update E2E/unit
assertions to match the sanitised error output.
Changes:
- types.py: bake endpoint paths into wrapper signatures (post_run,
  get_run, upload_tool_artifact, get_agents_raw); auto-create _base
  via __post_init__; remove base from constructor
- client.py: drop BaseWXOClient import and base= constructor arg
- core/execution.py: pass run_id / query_suffix instead of raw paths
- core/tools.py: pass tool_id instead of raw path
- service.py: fix double-period in ErrorPrefix interpolation; remove
  redundant restatements in generic except handlers
- tests: update _with_wxo_wrappers helper and test doubles to use
  _base; update FakeBaseClient._get to accept params
- e2e: update rollback scenario detail_contains to match sanitised msg

* skip import and tests of wxo adapter if current env is running python 3.10

* clarify random prefix / retry  behavior

* implement comments

* fix: align watsonx adapter with updated deployment schema
- Add `deployment_type` parameter to `get`, `update`, `redeploy`,
  `duplicate`, `delete`, `get_status`, and `undeploy_deployment` in
  WatsonxOrchestrateDeploymentService to match the updated
  BaseDeploymentService ABC
- Update e2e script to use renamed `add_ids` field on
  SnapshotDeploymentBindingUpdate

* remove non-interface method undeploy_deployment

* implement listing configs and snapshots

* add update implementation and improve http->deployment error translation and add tests

* improve exception handling

* checkout payload slot work

* custom payload schema for update

* new update implementation

* stop passing client cache to helpers

* add docs for ordereduniquests

* improve import patterns and document future risks for wxo dependencies

* remove global-variable prefixing of flows

* ref: harden typing, DRY helpers, and correctness fixes
- Replace `db: Any` with `db: AsyncSession` across client, config, and
  update_helpers modules
- Extract `_ensure_dict` / `ensure_langflow_connections_binding` helpers
  to eliminate repeated nested-dict safety logic in tools.py and
  update_helpers.py, with documentation explaining why malformed API
  payloads are silently corrected rather than rejected
- Use `PayloadSlot.parse()` for update payload validation instead of
  standalone helper; remove `parse_provider_update_payload`
- Fix lambda late-binding with default-argument captures in service.py
- Use `zip(strict=True)` in update_helpers for defensive mismatch
  detection
- Replace O(n²) duplicate detection with `collections.Counter` in
  payloads.py
- Simplify `dedupe_list` to `list(dict.fromkeys(...))`
- Move type-annotation-only imports into TYPE_CHECKING blocks in
  types.py and config.py
- Introduce `UPDATE_MAX_RETRIES` as a distinct constant from
  `CREATE_MAX_RETRIES`
- Fix "watsonX" → "watsonx" casing in error messages
- Clarify `get_status` docstring and `validate_connection` error message
- Add TODO(deployments-cache) for client cache invalidation on
  credential updates

* ref: drop client cache and adopt typed deployment context across the wxo adapter path, add request-context memoization with strict mixed-context guards, and lazily initialize wxo SDK clients. Add safer credential handling by storing only authenticators in WxOCredentials. Also improve provider error-detail extraction/messages and make the direct wxo E2E conflict scenario diagnostics and expectations more resilient.

* use explicit naming for context class; providerId

* fix error handling, retry safety, and exception diagnostics in wxo adapter

- Raise DeploymentError on empty API responses instead of fabricating
  fake success in create_agent_run_result and get_agent_run
- Elevate rollback failure logging from WARNING to ERROR for alerting
- Apply retryable filter to retry_rollback to skip 401/403/409/422
- Preserve exception chains (from exc) instead of suppressing (from None)
  across service.py, utils.py, execution.py, and update_helpers.py
- Broaden credential resolution catch to handle arbitrary DB exceptions
- Separate status code dispatch from string heuristics in
  raise_for_status_and_detail to prevent misclassification
- Add tests for all behavioral changes

* [autofix.ci] apply automated fixes

* fix: harden wxO adapter safety, immutability, and error diagnostics

- Make WxOClient and WxOCredentials frozen dataclasses with eager SDK
  client initialization to eliminate thread-safety races from
  asyncio.to_thread workers and prevent post-construction mutation
- Move instance_url validation and normalization into type __post_init__
- Raise DeploymentError on missing run_id instead of returning partial
  success with execution_id=None
- Preserve exception chains (from exc) instead of suppressing (from None)
  across create, update, and delete service methods
- Add warning logs when _ensure_dict replaces non-dict binding values
  and when _resolve_lfx_requirement falls back to minimum version
- Initialize derived_spec before try block to prevent potential NameError
- Log all ToolUploadBatchError errors before re-raising the first
- Change SUPPORTED_ADAPTER_DEPLOYMENT_TYPES from mutable set to frozenset
- Add tests for 409/422 error mapping in create, unsupported deployment
  type rejection, empty update rejection, zip artifact extraction paths,
  validate_connection negative paths, missing run_id, multiple deployment
  ID rejection, exception chain preservation, and _ensure_dict warning

* [autofix.ci] apply automated fixes

* fix ruff errors and and todo for status method

* fix mypy errors

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Jordan Frazier <jordan.frazier@datastax.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: 1.9.0 nightly (#12210)

fix 1.9.0 nightly

* fix(mcp): Add schema-driven type conversion (#11796)

* fix: nightly now properly gets 1.9.0 branch (#12215)

before it was attempting to pull release-notes as letters are alphanumerically after numbers when we sort -V then grab tail
now we only look at branch names that follow the pattern '^release-[0-9]+\.[0-9]+\.[0-9]+$'

* fix(mcp): Add schema-driven type conversion

- Add schema-driven type conversion (str→dict, str→int, etc.)
- normalize and unflatten tool arguments for MCP servers
- Unflatten flattened keys (e.g. params.search) into nested objects

* fix(mcp): handle dict type and array type in JSON schema for MCP tools

- Support "type": ["string", "null"] (JSON Schema array type)
- Normalize required to hashable elements (filter non-string entries)
- Add unit tests for create_input_schema_from_json_schema

* fix(mcp): map generic object type to dict for free-form params

When JSON schema has {"type": "object"} with no properties, treat it as
a free-form dict instead of building a nested Pydantic model. This allows
MCP servers expecting arbitrary key-value params to receive proper dicts,
and enables str→dict conversion via _normalize_arguments_for_mcp.

- Add conditional in parse_type: empty properties → dict, else nested model
- Add test_create_input_schema_generic_object_maps_to_dict

* fix(mcp): exclude None from tool arguments sent to MCP servers

* test_mcp: add more tests for datatypes

* fix(mcp): parse JSON strings for nested model params (e.g. foreman-mcp)

* fix(mcp): refactor _try_convert_value reducing repetition

* fix(mcp): add missing tests for remaining use cases

* fix(mcp): Fix mapping of None if expected is list, dict or str

* Update nightly_build.yml

---------

Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>

* fix: prevent overwriting user-selected global variables in provider c… (#12217)

* fix: nightly now properly gets 1.9.0 branch (#12215)

before it was attempting to pull release-notes as letters are alphanumerically after numbers when we sort -V then grab tail
now we only look at branch names that follow the pattern '^release-[0-9]+\.[0-9]+\.[0-9]+$'

* docs: add search icon (#12216)

add-back-svg

* fix: prevent overwriting user-selected global variables in provider config

Previously, the apply_provider_variable_config_to_build_config function would
automatically overwrite field values with environment variable keys whenever
an env var was present, even if the user had already selected a different
global variable.

This fix adds a check to only auto-set the environment variable if:
- The field is currently empty, OR
- The field is not already configured to load from the database

This preserves user selections while still providing automatic configuration
for new/empty fields.

Added comprehensive unit tests to verify:
- Auto-setting env vars for empty fields
- Preserving user-selected global variables
- Overwriting hardcoded values (expected behavior)
- Skipping when env var is not set
- Applying component metadata correctly

* [autofix.ci] apply automated fixes

* style: use dictionary comprehension instead of for-loop

Fixed PERF403 Ruff style warning by replacing for-loop with dictionary
comprehension in update_projects_components_with_latest_component_versions

* chore: retrigger CI build

* test: improve test coverage and clarity for provider config

- Renamed test_apply_provider_config_overwrites_hardcoded_value to
  test_apply_provider_config_replaces_hardcoded_with_env_var for clarity
- Added test_apply_provider_config_idempotent_when_already_set to document
  idempotent behavior when value already matches env var key
- Removed sensitive value from debug log message to prevent potential
  exposure of API keys or credentials

These changes improve test coverage by documenting the no-op scenario
and enhance security by avoiding logging of potentially sensitive data.

* chore: retrigger CI build

---------

Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
Co-authored-by: Steve Haertel <shaertel@ca.ibm.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>

* fix: Fixed CodeQL security scan about Incomplete URL substring sanitization on watsonx test suite (#12212)

* fix: Fixed CodeQL security scan about Incomplete URL substring sanitization

* fix coderabbitai comments

* fix: nightly now properly gets 1.9.0 branch (#12215)

before it was attempting to pull release-notes as letters are alphanumerically after numbers when we sort -V then grab tail
now we only look at branch names that follow the pattern '^release-[0-9]+\.[0-9]+\.[0-9]+$'

* fix failing action

* docs: add search icon (#12216)

add-back-svg

* Revert "Merge branch 'main' into dev-fix-security-code-scan-watsonx"

This reverts commit 41eb034e11, reversing
changes made to 4e51f4d836.

* Revert "Merge branch 'main' into dev-fix-security-code-scan-watsonx"

This reverts commit 4e51f4d836, reversing
changes made to 530bddd0a4.

---------

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

* fix: remove ibm-watsonx extra from complete installation (#12230)

* docs: lfx readme content (#11870)

* docs-add-lfx-content-to-readme

* github-link-syntax

* allowlist-blocklist

* docs: add a copy to markdown button to docusaurus theme (#12189)

* copy-page-component

* copy-theme-and-add-button

* docs: add versioning  (#12218)

* fix: nightly now properly gets 1.9.0 branch (#12215)

before it was attempting to pull release-notes as letters are alphanumerically after numbers when we sort -V then grab tail
now we only look at branch names that follow the pattern '^release-[0-9]+\.[0-9]+\.[0-9]+$'

* docs: add search icon (#12216)

add-back-svg

* initial-content

* cut-1.8-release-and-include-next-version

* stage-1.8.0-and-next

---------

Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>

* docs: replace api build automation (#12214)

* remove-workflows-file-and-script

* tag-hidden-endpoints

* update-scripts-and-specs

* fix: nightly now properly gets 1.9.0 branch (#12215)

before it was attempting to pull release-notes as letters are alphanumerically after numbers when we sort -V then grab tail
now we only look at branch names that follow the pattern '^release-[0-9]+\.[0-9]+\.[0-9]+$'

* docs: add search icon (#12216)

add-back-svg

---------

Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>
Co-authored-by: Debojit Kaushik <Kaushik.debojit@gmail.com>

* fix: prevent arbitrary file write via path traversal in files endpoint (#12227)

* fix(security): prevent arbitrary file write via path traversal in file uploads

* [autofix.ci] apply automated fixes

---------

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>

* docs: Add AI coding agent skills for code review, testing, and refactoring (#12241)

Add AI coding agent skills for code review, testing, and refactoring

* feat: Add Windows Playwright testing to nightly builds (#12221)

* feat: add Windows support for Playwright tests in nightly builds

- Add windows-latest as runner option in typescript_test.yml
- Update Playwright browser installation to be OS-aware (Windows doesn't support --with-deps)
- Add matrix strategy to nightly_build.yml to run tests on both Linux and Windows
- Update Slack notifications to indicate multi-platform testing
- Tests now run in parallel on ubuntu-latest and windows-latest

This enables catching Windows-specific regressions early in the nightly build process.

* fix: add shell: bash to all script steps for Windows compatibility

Windows runners default to PowerShell which doesn't understand bash syntax.
All steps with bash scripts now explicitly specify shell: bash to ensure
cross-platform compatibility.

* feat: make Windows Playwright tests non-blocking initially

Add continue-on-error for Windows tests to allow nightly builds to succeed
even if Windows-specific issues are found. This gives us visibility into
Windows bugs without blocking releases.

Windows tests will still run every night and report failures, but won't
block the build. Once Windows tests are stable, we can remove this flag.

* chore: fix white space

chore: fix white space

* fix: replace matrix strategy with separate jobs for Windows Playwright tests

- GitHub Actions reusable workflows don't support matrix strategy
- Split frontend-tests into frontend-tests-linux and frontend-tests-windows
- Windows tests are non-blocking (continue-on-error: true)
- Updated all job dependencies and Slack notification logic
- Addresses PR review comment about matrix limitation

* chore: trigger workflow validation refresh

---------

Co-authored-by: Adam Aghili <Adam.Aghili@ibm.com>

* fix: Avoid foreign key violation on span table with topological sort (#12232)

* fix: Foreign key violation on span table

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* address review comments

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: use deepcopy to prevent shared reference mutation in component updates (#12252)

* fix: use deepcopy to prevent shared reference mutation in component updates

Copies template data via deepcopy when updating project components to
prevent mutations from leaking between projects through all_types_dict.
Also fixes edge updates to use the copied project data and adds
cloneDeep in the frontend templatesGenerator.

* fix: deepcopy mutable FIELD_FORMAT_ATTRIBUTES and add coverage test

- Add deepcopy on field_dict[attr] assignment (line 192) to prevent
  shared references for mutable attributes like input_types, options,
  and fileTypes leaking back into all_types_dict
- Add test_update_components_does_not_mutate_field_format_attributes
  to verify the fix covers the FIELD_FORMAT_ATTRIBUTES update path

* feat: add support for Langchain 1.0 (#11114)

* feat: upgrade to LangChain 1.0

- langchain ~=1.2.0
- langchain-core ~=1.2.3
- langchain-community ~=0.4.1

Updated all langchain-* integration packages to versions compatible with langchain-core 1.0+.

* feat(lfx): add langchain-classic dependency for legacy agent classes

LangChain 1.0 removed AgentExecutor and related classes to langchain-classic.
This adds the dependency to maintain backward compatibility.

* refactor(lfx): update imports for LangChain 1.0 compatibility

- Move AgentExecutor, agent creators from langchain to langchain_classic
- Move AsyncCallbackHandler from langchain.callbacks to langchain_core.callbacks
- Move Chain, BaseChatMemory from langchain to langchain_classic
- Update LANGCHAIN_IMPORT_STRING for code generation

* fix(lfx): make sqlalchemy import lazy in session_scope

LangChain 1.0 no longer includes sqlalchemy as a transitive dependency.
Move the import inside the function where it's used to avoid import errors
when sqlalchemy is not installed.

* chore: update uv.lock for langchain-classic

* feat: enable nv-ingest optional dependencies for langchain 1.0

- Uncomment nv-ingest-api and nv-ingest-client, update to >=26.1.0
  (no longer has openai version conflict)
- Bump datasets from <4.0.0 to <5.0.0 to allow fsspec>=2025.5.1
  required by nv-ingest
- Update mlx-vlm TODO comment with accurate blocking reason

* chore: update nv-ingest to 26.1.1

nv-ingest 26.1.1 removes the openai dependency, resolving the
conflict with langchain-openai>=1.0.0 (which requires openai>=1.109.1).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: enable mlx and mlx-vlm dependencies for langchain 1.0

opencv-python 4.13+ now supports numpy>=2, resolving the conflict
with langchain-aws>=1.0.0 (which requires numpy>=2.2 on Python 3.12+).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: fix import order in callback.py

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: update imports to use langchain_classic for agent modules

* [autofix.ci] apply automated fixes

* fix: remove .item() calls in knowledge_bases.py

* fix(lfx): import BaseMemory from langchain_classic for langchain 1.0

* [autofix.ci] apply automated fixes

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

* refactor: update deprecated langchain imports for langchain 1.0

- langchain.callbacks.base -> langchain_core.callbacks.base
- langchain.tools -> langchain_core.tools
- langchain.schema -> langchain_core.messages/documents
- langchain.chains -> langchain_classic.chains
- langchain.retrievers -> langchain_classic.retrievers
- langchain.memory -> langchain_classic.memory
- langchain.globals -> langchain_core.globals
- langchain.docstore -> langchain_core.documents
- langchain.prompts -> langchain_core.prompts

Also simplified GoogleGenerativeAIEmbeddingsComponent to use native
langchain-google-genai 4.x which now supports output_dimensionality.

* [autofix.ci] apply automated fixes

* fix: add _to_int helper for pandas sum() compatibility across Python versions

* fix: update langfuse>=3.8.0 and fix cuga_agent.py (#11519)

* fix: update langfuse>=3.8.0 and fix cuga_agent.py

* [autofix.ci] apply automated fixes

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

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* feat: implement LangFuseTracer for langfuse v3 API compatibility and add unit tests

* fix: upgrade cuga to 0.2.9 for langchain 1.0 compatibility

* fix: improve error handling and return value in get_langchain_callback method

* fix: update package versions for compatibility and improvements

* [autofix.ci] apply automated fixes

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

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

* fix: update langwatch dependency to version 0.10.0 for compatibility

* fix: update environment variable for Langfuse host to LANGFUSE_BASE_URL

* Update dependency versions in Youtube Analysis project

- Downgraded googleapiclient from 2.188.0 to 2.154.0
- Updated langchain_core from 1.2.7 to 1.2.9
- Updated fastapi from 0.128.1 to 0.128.5
- Downgraded youtube_transcript_api from 1.2.4 to 1.2.3
- Changed langchain_core version from 1.2.7 to 0.3.81
- Cleared input_types in model selection

# Conflicts:
#	src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json
#	src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json
#	src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json
#	src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json
#	src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json
#	src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json
#	src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json
#	src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json
#	src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json
#	src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json
#	src/backend/base/langflow/initial_setup/starter_projects/Knowledge Retrieval.json
#	src/backend/base/langflow/initial_setup/starter_projects/Market Research.json
#	src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json
#	src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json
#	src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json
#	src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json
#	src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json
#	src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json
#	src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json
#	src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json
#	src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json
#	src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json
#	src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json
#	src/backend/base/langflow/initial_setup/starter_projects/Search agent.json
#	src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json
#	src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json
#	src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json
#	src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json
#	src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json
#	src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json
#	src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json
#	src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json

* fix: handle InvalidRequestError during session rollback

* update projects

* ️ Speed up method `LangFuseTracer.end` by 141% in PR #11114 (`feat/langchain-1.0`) (#11682)

Optimize LangFuseTracer.end 


The optimized code achieves a **140% speedup** (8.23ms → 3.42ms) through two complementary optimizations:

## 1. Fast-path for Common Primitives in `serialize()`

**What changed:** Added an early-exit check that returns immutable primitives (`str`, `int`, `float`, `bool`) directly when no truncation or special handling is needed:

```python
if max_length is None and max_items is None and not to_str:
    if isinstance(obj, (str, int, float, bool)):
        return obj
```

**Why it's faster:** 
- The profiler shows `_serialize_dispatcher()` consumed **81.5% of runtime** in the original code (40.4ms out of 49.6ms)
- This optimization reduced dispatcher calls from **8,040 to 1,013** (~87% reduction), as primitives now bypass the expensive pattern-matching dispatcher entirely
- The fast-path check itself is extremely cheap: just two quick conditionals and an `isinstance()` check against a tuple of built-in types

**When it helps:** This optimization is particularly effective for workloads with many primitive values in dictionaries and lists—which is exactly what the tracing use case provides (metadata dicts with strings, numbers, booleans).

## 2. Eliminate Redundant Serialization in `LangFuseTracer.end()`

**What changed:** Serialize `inputs`, `outputs`, and `metadata` once each, then reuse the results:

```python
inputs_ser = serialize(inputs)
outputs_ser = serialize(outputs)
metadata_ser = serialize(metadata) if metadata else None
```

**Why it's faster:**
- The original code called `serialize()` **6 times total** (3 for `.update()` + 3 for `.update_trace()`)
- The optimized version calls it **3 times**, then passes the cached results
- Profiler shows the time spent in `serialize()` calls dropped from **72.2ms to 31.2ms** (~57% reduction)
- This is pure elimination of redundant work—the same dictionaries were being serialized twice with identical results

**Impact on workloads:** The `test_end_multiple_iterations_calls_end_each_time` test (500 iterations) demonstrates this matters in hot paths. If `LangFuseTracer.end()` is called frequently during flow execution, avoiding duplicate serialization provides compounding benefits.

## Combined Effect

Both optimizations target the serialization bottleneck from different angles:
- The fast-path reduces the cost of *each* serialize call by ~75% for primitive-heavy data
- The caching reduces the *number* of serialize calls by 50%

Together, they deliver the observed 140% speedup, with the optimization being especially effective for the common case of metadata dictionaries containing mostly primitive types.

Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com>

* refactor: reorder imports and simplify serialization logic for primitives

* [autofix.ci] apply automated fixes

* fix: update google dependency version to 0.4.0 in component_index.json

* [autofix.ci] apply automated fixes

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

* fix: pin z3-solver<4.15.7 to restore Linux wheels for Docker build

z3-solver 4.15.7 dropped manylinux wheels, causing the Docker build to
fail when trying to compile from source. Temporary pin until codeflash
is removed.

* [autofix.ci] apply automated fixes

* fix: update google dependency version to 0.4.0

* [autofix.ci] apply automated fixes

* fix: update langchain_core version to 1.2.17 in multiple starter project JSON files

* [autofix.ci] apply automated fixes

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

* fix: update deprecated langchain imports to langchain_classic for 1.0 compatibility

* fix: align langchain-chroma version in optional chroma dependency group

* fix: nightly now properly gets 1.9.0 branch (#12215)

before it was attempting to pull release-notes as letters are alphanumerically after numbers when we sort -V then grab tail
now we only look at branch names that follow the pattern '^release-[0-9]+\.[0-9]+\.[0-9]+$'

* docs: add search icon (#12216)

add-back-svg

* [autofix.ci] apply automated fixes

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

* feat: fall back to langchain_classic for pre-1.0 imports in user components

Old flows using removed langchain imports (e.g. langchain.memory,
langchain.schema, langchain.chains) now resolve via langchain_classic
at two levels: module-level for entirely removed modules, and
attribute-level for removed attributes in modules that still exist
in langchain 1.0. New langchain 1.0 imports are never affected since
fallbacks only trigger on import failure.

* urllib parse module import bug

* Update component_index.json

* [autofix.ci] apply automated fixes

* chore: rebuild component index

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Harold Ship <harold.ship@gmail.com>
Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com>
Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>

* fix: prevent CI injection via unsanitized GitHub context interpolation (#12224)

Pass github.event.pull_request.head.ref through env: instead of
interpolating it directly into run: shell steps. This prevents bash
from evaluating command substitutions embedded in malicious branch names
before input validation runs.

Co-authored-by: Janardan Singh Kavia <janardankavia@ibm.com>

* feat: Refactor and Unify the ModelInput Selector Across Components (#12025)

* fix: Fixes Kubernetes deployment crash on runtime_port parsing (#11968) (#11975)

* feat: add runtime port validation for Kubernetes service discovery

* test: add unit tests for runtime port validation in Settings

* fix: improve runtime port validation to handle exceptions and edge cases

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@logspace.ai>

* fix(frontend):  show delete option for default session when it has messages (#11969)

* feat: add documentation link to Guardrails component (#11978)

* feat: add documentation link to Guardrails component

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* feat: traces v0 (#11689) (#11983)

* feat: traces v0

v0 for traces includes:
- filters: status, token usage range and datatime
- accordian rows per trace

Could add:
- more filter options. Ecamples: session_id, trace_id and latency range

* fix: token range

* feat: create sidebar buttons for logs and trace

add sidebar buttons for logs and trace
remove lods canvas control

* fix: fix duplicate trace ID insertion

hopefully fix duplicate trace ID insertion on windows

* fix: update tests and alembic tables for uts

update tests and alembic tables for uts

* chore: add session_id

* chore: allo grouping by session_id and flow_id

* chore: update race input output

* chore: change run name to flow_name - flow_id
was flow_name - trace_id
now flow_name - flow_id

* facelift

* clean up and add testcases

* clean up and add testcases

* merge Alembic detected multiple heads

* [autofix.ci] apply automated fixes

* improve testcases

* remodel files

* chore: address gabriel simple changes

address gabriel simple changes in traces.py and native.py

* clean up and testcases

* chore: address OTel and PG status comments

https://github.com/langflow-ai/langflow/pull/11689#discussion_r2854630438
https://github.com/langflow-ai/langflow/pull/11689#discussion_r2854630446

* chore: OTel span naming convention

model name is now set using name = f"{operation} {model_name}" if model_name else operation

* add traces

* feat: use uv sources for CPU-only PyTorch (#11884)

* feat: use uv sources for CPU-only PyTorch

Configure [tool.uv.sources] with pytorch-cpu index to avoid ~6GB CUDA
dependencies in Docker images. This replaces hardcoded wheel URLs with
a cleaner index-based approach.

- Add pytorch-cpu index with explicit = true
- Add torch/torchvision to [tool.uv.sources]
- Add explicit torch/torchvision deps to trigger source override
- Regenerate lockfile without nvidia/cuda/triton packages
- Add required-environments for multi-platform support



* fix: update regex to only replace name in [project] section

The previous regex matched all lines starting with `name = "..."`,
which incorrectly renamed the UV index `pytorch-cpu` to `langflow-nightly`
during nightly builds. This caused `uv lock` to fail with:
"Package torch references an undeclared index: pytorch-cpu"

The new regex specifically targets the name field within the [project]
section only, avoiding unintended replacements in other sections like
[[tool.uv.index]].

* style: fix ruff quote style

* fix: remove required-environments to fix Python 3.13 macOS x86_64 CI

The required-environments setting was causing hard failures when packages
like torch didn't have wheels for specific platform/Python combinations.
Without this setting, uv resolves optimistically and handles missing wheels
gracefully at runtime instead of failing during resolution.



---------



* LE-270: Hydration and Console Log error (#11628)

* LE-270: add fix hydration issues

* LE-270: fix disable field on max token on language model

---------



* test: add wait for selector in mcp server tests (#11883)

* Add wait for selector in mcp server tests

* [autofix.ci] apply automated fixes

* Add more awit for selectors

* [autofix.ci] apply automated fixes

---------



* fix: reduce visual lag in frontend  (#11686)

* Reduce lag in frontend by batching react events and reducing minimval visual build time

* Cleanup

* [autofix.ci] apply automated fixes

* add tests and improve code read

* [autofix.ci] apply automated fixes

* Remove debug log

---------




* feat: lazy load imports for language model component (#11737)

* Lazy load imports for language model component

Ensures that only the necessary dependencies are required.
For example, if OpenAI provider is used, it will now only
import langchain_openai, rather than requiring langchain_anthropic,
langchain_ibm, etc.

* Add backwards-compat functions

* [autofix.ci] apply automated fixes

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

* Add exception handling

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

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

* comp index

* docs: azure default temperature (#11829)

* change-azure-openai-default-temperature-to-1.0

* [autofix.ci] apply automated fixes

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

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

* [autofix.ci] apply automated fixes

---------



* [autofix.ci] apply automated fixes

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

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

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

* fix unit test?

* add no-group dev to docker builds

* [autofix.ci] apply automated fixes

---------





* feat: generate requirements.txt from dependencies  (#11810)

* Base script to generate requirements

Dymanically picks dependency for LanguageM Comp.
Requires separate change to remove eager loading.

* Lazy load imports for language model component

Ensures that only the necessary dependencies are required.
For example, if OpenAI provider is used, it will now only
import langchain_openai, rather than requiring langchain_anthropic,
langchain_ibm, etc.

* Add backwards-compat functions

* [autofix.ci] apply automated fixes

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

* Add exception handling

* Add CLI command to create reqs

* correctly exclude langchain imports

* Add versions to reqs

* dynamically resolve provider imports for language model comp

* Lazy load imports for reqs, some ruff fixes

* Add dynamic resolves for embedding model comp

* Add install hints

* Add missing provider tests; add warnings in reqs script

* Add a few warnings and fix install hint

* update comments add logging

* Package hints, warnings, comments, tests

* [autofix.ci] apply automated fixes

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

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

* Add alias for watsonx

* Fix anthropic for basic prompt, azure mapping

* [autofix.ci] apply automated fixes

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

* ruff

* [autofix.ci] apply automated fixes

* test formatting

* ruff

* [autofix.ci] apply automated fixes

---------



* fix: add handle to file input to be able to receive text (#11825)

* changed base file and file components to support muitiple files and files from messages

* update component index

* update input file component to clear value and show placeholder

* updated starter projects

* [autofix.ci] apply automated fixes

* updated base file, file and video file to share robust file verification method

* updated component index

* updated templates

* fix whitespaces

* [autofix.ci] apply automated fixes

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

* add file upload test for files fed through the handle

* [autofix.ci] apply automated fixes

* added tests and fixed things pointed out by revies

* update component index

* fixed test

* ruff fixes

* Update component_index.json

* [autofix.ci] apply automated fixes

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

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

* updated component index

* updated component index

* removed handle from file input

* Added functionality to use multiple files on the File Path, and to allow files on the langflow file system.

* [autofix.ci] apply automated fixes

* fixed lfx test

* build component index

---------





* docs: Add AGENTS.md development guide (#11922)

* add AGENTS.md rule to project

* change to agents-example

* remove agents.md

* add example description

* chore: address cris I1 comment

address cris I1 comment

* chore: address cris I5

address cris I5

* chore: address cris I6

address cris I6

* chore: address cris R7

address cris R7

* fix testcase

* chore: address cris R2

address cris R2

* restructure insight page into sidenav

* added header and total run node

* restructing branch

* chore: address gab otel model changes

address gab otel model changes will need no migration tables

* chore: update alembic migration tables

update alembic migration tables after model changes

* add empty state for gropu sessions

* remove invalid mock

* test: update and add backend tests

update and add backend tests

* chore: address backend code rabbit comments

address backend code rabbit comments

* chore: address code rabbit frontend comments

address code rabbit frontend comments

* chore: test_native_tracer minor fix address c1

test_native_tracer minor fix address c1

* chore: address C2 + C3

address C2 + C3

* chore: address H1-H5

address H1-H5

* test: update test_native_tracer

update test_native_tracer

* fixes

* chore: address M2

address m2

* chore: address M1

address M1

* dry changes, factorization

* chore: fix 422 spam and clean comments

fix 422 spam and clean comments

* chore: address M12

address M12

* chore: address M3
 address M3

* chore: address M4

address M4

* chore: address M5

address M5

* chore: clean up for M7, M9, M11

clean up for M7, M9, M11

* chore: address L2,L4,L5,L6 + any test

address L2,L4,L5 and L6 + any test

* chore: alembic + comment clean up

alembic + comment clean up

* chore: remove depricated test_traces file

remove depricated test_traces file. test have all been moved to test_traces_api.py

* fix datetime

* chore: fix test_trace_api ge=0 is allowed now

fix test_trace_api ge=0 is allowed now

* chore: remove unused traces cost flow

remove unused traces cost flow

* fix traces test

* fix traces test

* fix traces test

* fix traces test

* fix traces test

* chore: address gabriels otel coment

address gabriels otel coment latest

---------

Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
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: Ram Gopal Srikar Katakam <44802869+RamGopalSrikar@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: olayinkaadelakun <olayinka.adelakun@ibm.com>
Co-authored-by: Jordan Frazier <122494242+jordanrfrazier@users.noreply.github.com>
Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
Co-authored-by: Hamza Rashid <74062092+HzaRashid@users.noreply.github.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
Co-authored-by: Lucas Oliveira <62335616+lucaseduoli@users.noreply.github.com>
Co-authored-by: Edwin Jose <edwin.jose@datastax.com>
Co-authored-by: Himavarsha <40851462+HimavarshaVS@users.noreply.github.com>

* fix(test): Fix superuser timeout test errors by replacing heavy clien… (#11982)

fix(test): Fix superuser timeout test errors by replacing heavy client fixture                                                    (#11972)

* fix super user timeout test error

* fix fixture db test

* remove canary test

* [autofix.ci] apply automated fixes

* flaky test

---------

Co-authored-by: Cristhian Zanforlin Lousa <cristhian.lousa@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* refactor(components): Replace eager import with lazy loading in agentics module  (#11974)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: add ondelete=CASCADE to TraceBase.flow_id to match migration (#12002)

* fix: add ondelete=CASCADE to TraceBase.flow_id to match migration

The migration file creates the trace table's flow_id foreign key with
ondelete="CASCADE", but the model was missing this parameter. This
mismatch caused the migration validator to block startup.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add defensive migration to ensure trace.flow_id has CASCADE

Adds a migration that ensures the trace.flow_id foreign key has
ondelete=CASCADE. While the original migration already creates it
with CASCADE, this provides a safety net for any databases that may
have gotten into an inconsistent state.

* fix: dynamically find FK constraint name in migration

The original migration did not name the FK constraint, so it gets an
auto-generated name that varies by database. This fix queries the
database to find the actual constraint name before dropping it.

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* fix: LE-456 - Update ButtonSendWrapper to handle building state and improve button functionality (#12000)

* fix: Update ButtonSendWrapper to handle building state and improve button functionality

* fix(frontend): rename stop button title to avoid Playwright selector conflict

The "Stop building" title caused getByRole('button', { name: 'Stop' })
to match two elements, breaking Playwright tests in shards 19, 20, 22, 25.

Renamed to "Cancel" to avoid the collision with the no-input stop button.

* Fix: pydantic fail because output is list, instead of a dict (#11987)

pydantic fail because output is list, instead of a dict

Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>

* refactor: Update guardrails icons (#12016)

* Update guardrails.py

Changing the heuristic threshold icons.

The field was using the default icons. I added icons related to the security theme.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com>

* feat: Clean up the modelinput unification

* [autofix.ci] apply automated fixes

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

* Update test_embedding_model_component.py

* [autofix.ci] apply automated fixes

* Revert to main for other files

* More reversions

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

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

* [autofix.ci] apply automated fixes

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

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

* [autofix.ci] apply automated fixes

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

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

* Handle first run more elegantly in astra

* [autofix.ci] apply automated fixes

* Fix knowledge embedding dialog (#12071)

* fix: Handle message inputs when ingesting knowledge

* [autofix.ci] apply automated fixes

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

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

* Update test_ingestion.py

* [autofix.ci] apply automated fixes

* fix: Unify the knowledge creation model selector

* Revert tracing

* Update ingestion.py

* Rebuild comp index

* [autofix.ci] apply automated fixes

* Update test_ingestion.py

* [autofix.ci] apply automated fixes

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

* Update test_ingestion.py

* Update component_index.json

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* [autofix.ci] apply automated fixes

* Update comp index

* Update test_astradb_base_component.py

* Update Knowledge Ingestion.json

* [autofix.ci] apply automated fixes

* Fix broken tests

* Cleanup from claude

* [autofix.ci] apply automated fixes

* Fix failing tests

* Update test_unified_models.py

* [autofix.ci] apply automated fixes

* Update Nvidia Remix.json

* Refactor ingest

* Rebuild templates and component index

* Fix test

* [autofix.ci] apply automated fixes

* Update component_index.json

* [autofix.ci] apply automated fixes

* test: add update_build_config visibility tests and PR review fixes (#12114)

- Add update_build_config field-visibility tests to LanguageModelComponent,
  ToolCallingAgentComponent, and BatchRunComponent covering Ollama, WatsonX,
  OpenAI, and no-model-selected cases
- Remove 16 stale @pytest.mark.skip tests from test_agent_component.py
- Wire up validate_model_selection in agent.py for early input validation
- Document AstraDB intentional use of lower-level update_model_options_in_build_config
- Clarify model_kwargs info text to note provider-specific support

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update embedding_model.py

* fix: address PR review recommendations for feat-unify-models++ (#12116)

- Fix 9 skipped tests in test_batch_run_component.py by replacing model
  list with _MockLLM instances, following the existing pattern used by
  test_with_config_failure_handling
- Fix test_agent_component.py: set component.model to a valid list before
  calling get_agent_requirements() in the three max_tokens tests, since
  validate_model_selection now requires a list-format model
- Replace os.environ direct reads in apply_provider_variable_config_to_build_config
  with get_all_variables_for_provider() (DB-first, env fallback), and pass
  user_id through from handle_model_input_update
- Add deprecated stubs for update_provider_fields_visibility, _update_watsonx_fields,
  and _update_ollama_fields in model_config.py with DeprecationWarning pointing
  to handle_model_input_update
- Fix typo: "deault" -> "default" in structured_output.py TODO comment
- Add 4 new KnowledgeIngestionComponent tests: new-format model_selection
  metadata path, allow_duplicates=True, missing metadata file error, and
  _build_embedding_metadata without API key

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Ruff errors

* Update test_ingestion.py

* Update component index

* Test updates

* Update component_index.json

* Update stable_hash_history.json

* Template updates

* Update batch_run.py

* [autofix.ci] apply automated fixes

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

* Update Youtube Analysis.json

* Fix tests

* [autofix.ci] apply automated fixes

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

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

* Some cleanup and refactoring

* [autofix.ci] apply automated fixes

* Update Nvidia Remix.json

* Update Nvidia Remix.json

* Update unified_models.py

* Coderabbit AI review comments

* Component index update

* [autofix.ci] apply automated fixes

* Template updates

* [autofix.ci] apply automated fixes

* Template update

* [autofix.ci] apply automated fixes

* Review comments addressed

* [autofix.ci] apply automated fixes

* Update component_index.json

* Update stable_hash_history.json

* [autofix.ci] apply automated fixes

* Test updates

* Update test_ingestion.py

* Update test_ingestion.py

* Update test_ingestion.py

* [autofix.ci] apply automated fixes

* More clear tooltip text

* [autofix.ci] apply automated fixes

* Template updates

* Index and templates

* [autofix.ci] apply automated fixes

* Fix lambda build

* Template updates

* Rebuild comp index

* [autofix.ci] apply automated fixes

* Fix templates

* Fix failing test

* Update templates

* Update comp index

* [autofix.ci] apply automated fixes

* API key field in astra db

* Update starter

* Update comp index

* Starter proj update

* Add api key to field order

* Update test_unified_models.py

* Update test_unified_models.py

* [autofix.ci] apply automated fixes

* Update setup.py

* Update setup.py

* Update component_index.json

* [autofix.ci] apply automated fixes

* Return embedding models directly in KB

* [autofix.ci] apply automated fixes

* Update component_index.json

* fix: Refactor the unified models code

* Ruff checks

* Update flow_preparation.py

* [autofix.ci] apply automated fixes

* Update test_language_model_component.py

* fix: prevent overwriting user-selected global variables in provider c… (#12217)

* fix: nightly now properly gets 1.9.0 branch (#12215)

before it was attempting to pull release-notes as letters are alphanumerically after numbers when we sort -V then grab tail
now we only look at branch names that follow the pattern '^release-[0-9]+\.[0-9]+\.[0-9]+$'

* docs: add search icon (#12216)

add-back-svg

* fix: prevent overwriting user-selected global variables in provider config

Previously, the apply_provider_variable_config_to_build_config function would
automatically overwrite field values with environment variable keys whenever
an env var was present, even if the user had already selected a different
global variable.

This fix adds a check to only auto-set the environment variable if:
- The field is currently empty, OR
- The field is not already configured to load from the database

This preserves user selections while still providing automatic configuration
for new/empty fields.

Added comprehensive unit tests to verify:
- Auto-setting env vars for empty fields
- Preserving user-selected global variables
- Overwriting hardcoded values (expected behavior)
- Skipping when env var is not set
- Applying component metadata correctly

* [autofix.ci] apply automated fixes

* style: use dictionary comprehension instead of for-loop

Fixed PERF403 Ruff style warning by replacing for-loop with dictionary
comprehension in update_projects_components_with_latest_component_versions

* chore: retrigger CI build

* test: improve test coverage and clarity for provider config

- Renamed test_apply_provider_config_overwrites_hardcoded_value to
  test_apply_provider_config_replaces_hardcoded_with_env_var for clarity
- Added test_apply_provider_config_idempotent_when_already_set to document
  idempotent behavior when value already matches env var key
- Removed sensitive value from debug log message to prevent potential
  exposure of API keys or credentials

These changes improve test coverage by documenting the no-op scenario
and enhance security by avoiding logging of potentially sensitive data.

* chore: retrigger CI build

---------

Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
Co-authored-by: Steve Haertel <shaertel@ca.ibm.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>

* Update build_config.py

* [autofix.ci] apply automated fixes

* Update build_config.py

* Fix tests

* fix: Dropdown issue with field population

* Update test_unified_models.py

* Clean up key config

* [autofix.ci] apply automated fixes

* fix tests

* Fix tests

* fix: Update tests

* Update tests

* Update test_tool_calling_agent.py

* Update test_unified_models.py

* Update test_tool_calling_agent.py

* Update tests

* Google AI generative embeddings fixes

* [autofix.ci] apply automated fixes

* Merge release branch

* Template update

* Merge release branch

* [autofix.ci] apply automated fixes

* Update openai_constants.py

* Update openai_constants.py

---------

Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@logspace.ai>
Co-authored-by: keval shah <kevalvirat@gmail.com>
Co-authored-by: Antônio Alexandre Borges Lima <104531655+AntonioABLima@users.noreply.github.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>
Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com>
Co-authored-by: Ram Gopal Srikar Katakam <44802869+RamGopalSrikar@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: olayinkaadelakun <olayinka.adelakun@ibm.com>
Co-authored-by: Jordan Frazier <122494242+jordanrfrazier@users.noreply.github.com>
Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
Co-authored-by: Hamza Rashid <74062092+HzaRashid@users.noreply.github.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
Co-authored-by: Lucas Oliveira <62335616+lucaseduoli@users.noreply.github.com>
Co-authored-by: Edwin Jose <edwin.jose@datastax.com>
Co-authored-by: Himavarsha <40851462+HimavarshaVS@users.noreply.github.com>
Co-authored-by: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com>
Co-authored-by: Lucas Democh <ldgoularte@gmail.com>
Co-authored-by: Steve Haertel <stevehaertel@users.noreply.github.com>
Co-authored-by: Steve Haertel <shaertel@ca.ibm.com>

* fix: Wait for dynamic model fetch in Nvidia (#12229)

* fix: Wait for dynamic model fetch in Nvidia

* [autofix.ci] apply automated fixes

* Create test_nvidia_component.py

* Update test_nvidia_component.py

* [autofix.ci] apply automated fixes

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* [autofix.ci] apply automated fixes

* Update test_nvidia_component.py

* Update component_index.json

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: protect image downloads by flow ownership (#12234)

* fix: protect image downloads by flow ownership

* test: add clarifying comments for image access review

---------

Co-authored-by: Janardan Singh Kavia <janardankavia@ibm.com>

* feat: Add Windows Playwright test fixes to RC (#12265)

* feat: Add Windows Playwright tests to nightly builds

- Add windows-latest to typescript_test.yml runner options
- Add shell: bash to all script steps for cross-platform compatibility
- Split Playwright installation into OS-aware steps (Linux uses --with-deps, Windows/macOS/self-hosted don't)
- Fix artifact naming with OS prefix to prevent conflicts: blob-report-${{ runner.os }}-${{ matrix.shardIndex }}
- Split frontend-tests into separate Linux and Windows jobs in nightly_build.yml
- Add ref parameter to all test jobs to checkout code from release branch
- Add resolve-release-branch to needs dependencies
- Update Slack notifications to handle both Linux and Windows test results
- Windows tests are non-blocking (not checked in release-nightly-build condition)
- Update .secrets.baseline with new line number (263 -> 347) for LANGFLOW_ENG_SLACK_WEBHOOK_URL

Fixes LE-566

* fix: Use contains() for self-hosted runner detection

- Replace exact string equality (==, !=) with contains() for substring matching
- Fixes issue when inputs.runs-on is array format: '["self-hosted", "linux", "ARM64", ...]'
- Ensures self-hosted Linux runners correctly skip --with-deps flag

Addresses CodeRabbit feedback on PR #12264

* fix: Sanitize folder names for CodeQL (#12263)

* fix(deps): pin tar-fs to >=2.1.4 to fix symlink following vulnerability (#12078)

Adds override for tar-fs in package.json to ensure versions prior to
2.1.4 are never resolved. Addresses CVE in tar-fs <2.1.4 (PVR0686558)
where symlink validation bypass was possible with a crafted tarball.

* fix: Rebuild the embedding model in the nv template (#12275)

* fix: support ZIP file upload for flows and projects endpoints (#12253)

* feat: support ZIP file upload for flows and projects endpoints

Add ZIP upload support to both /flows/upload/ and /projects/upload/
endpoints, enabling round-trip download-then-upload workflows. Extract
shared ZIP parsing logic into a dedicated utility with zip bomb
protections (entry count and file size limits). Fix batch flow name
deduplication to avoid infinite loops and DB collisions. Add tests for
ZIP upload, empty ZIP rejection, and download-upload round-trip.

* fix: add type annotation to satisfy mypy union narrowing

* fix: address PR review for ZIP upload (#12253)

- Add BadZipFile handling in extract_flows_from_zip for defense-in-depth
- Wrap blocking Z…

* add OpenDsStar 1.0.20 dependency and update uv.lock

Add OpenDsStar==1.0.20 to both backend and lfx pyproject.toml.
Regenerate uv.lock to include OpenDsStar and its transitive deps.

* [autofix.ci] apply automated fixes

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

* fix ruff lint errors in codeagents, file ingestion tests, and inspect script

* fix lfx tests: mock subprocess.Popen instead of subprocess.run

The FileDescriptionGenerator uses subprocess.Popen, not subprocess.run.
Tests were mocking the wrong function, causing real subprocess execution
that failed with ModuleNotFoundError for OpenDsStar in isolated lfx env.

* [autofix.ci] apply automated fixes

* fix lfx test mock data to match expected subprocess output format

Subprocess returns {"results": [...], "failed": [], "total": N},
not a bare list. Tests now use _wrap_results() helper.

* bump OpenDsStar to 1.0.21 to fix litellm dependency conflict

* fix tools metadata merge to preserve user-edited descriptions, remove orphan submodule

- Preserve user-edited description and display_description in tools
  metadata merge (fixes edit-tools Playwright test)
- Remove orphaned OpenDsStar-fork submodule entry that caused CI
  post-cleanup warnings

* smart tools description merge: update from code unless user customized

Compare old description to display_description — if they match, the user
never edited it and we update from code (picking up new Output.info
descriptions). If they differ, the user customized it and we preserve
their edit.

* [autofix.ci] apply automated fixes

* address CodeRabbit review: fix 4 major and 9 minor issues

Major fixes:
- Chroma: only suggest persist_directory when not in server mode
- FileContentRetriever: new input overwrites stale persisted data
- FileContentRetriever: preserve file_path on returned Message
- FileDescriptionGenerator: drain pipes in non-select fallback to prevent deadlock

Minor fixes:
- inspect_chroma_db: align docstring with actual 2000-char truncation
- test_file_content_retriever: fix empty/misplaced test functions
- test_file_description_generator: align duplicate paths test with actual behavior
- format.ts: fix NODE prefix regex pattern
- open_ds_star_agent: use get_running_loop(), remove duplicate cast import
- codeact_agent_smolagents: document timeout behavior, simplify import fallback

* bump OpenDsStar to 1.0.22

* Write File: make agent-friendly with tool_mode inputs, format control, and flexible input types

- Add tool_mode to input field (DataFrameInput) so agents can pass content directly
- Add file_format tool_mode input so agents can choose output format (csv, json, etc.)
- Handle raw pandas DataFrames from code agents (auto-wrap to Langflow DataFrame)
- Handle string inputs from chat agents (JSON → DataFrame, plain text → Message)
- Improve descriptions for agent discoverability
- Bump OpenDsStar to 1.0.24 (async tool invocation fix)
- Add 9 new tests covering all new features

* Write File: hide format dropdowns in tool mode, improve descriptions

- Hide local_format/aws_format/gdrive_format when tool_mode is active
- Agent uses unified file_format input instead
- Shorten field descriptions to pass ruff line length checks

* fix: add file_format field to News Aggregator starter project

The SaveToFile component now has a file_format input — update the
starter project template so field_order matches the component definition.
Update secrets baseline hash for shifted line.

* [autofix.ci] apply automated fixes

* rename Structured Data Agent starter project to Structured Data Analysis Agent

* fix: regenerate starter projects to include file_format field in SaveToFile node

The SaveToFileComponent added a new file_format input but the starter
project JSONs were not regenerated, causing field_order mismatches in
both Structured Data Analysis Agent and News Aggregator starter projects.

* feat: add html as a supported file format in SaveToFileComponent

Add html to LOCAL_MESSAGE_FORMAT_CHOICES, GDRIVE_FORMAT_CHOICES, and
the _save_message handler (reuses the txt write path). AWS already
supported html. Update the file_format tool-mode description to
include html.

* test: add test for saving Message as html format

* fix: regenerate starter projects after adding html format to SaveToFileComponent

* [autofix.ci] apply automated fixes

* fix(tests): skip assistant panel e2e test when OPENAI_API_KEY is missing

Without a configured model provider the assistant panel renders a
"no models" state instead of the input textarea and model selector,
causing the test to fail in CI environments without API keys.

* fix: add file_format field to SaveToFile in starter projects

The autofix bot incorrectly removed the file_format entry. Re-add it
to both field_order and template in News Aggregator and Structured
Data Analysis Agent starter projects. Update secrets baseline.

* fix: rebuild component index to include file_format in SaveToFile

The CI autofix kept removing file_format from starter projects because
the prebuilt component_index.json lacked the field. The update script
loads components from this index in production mode, so it regenerated
starter projects without file_format. Rebuild the index so it includes
the file_format input, which makes the autofix a no-op.

* fix: hide format dropdowns in SaveToFile when used as tool

The storage_location handler in update_build_config was showing format
dropdowns regardless of tool mode. Now it checks tools_metadata to
detect tool mode and keeps format dropdowns hidden, since the agent
uses the unified file_format string input instead.

* fix: remove debug script and replace stderr debug logging with proper logger

Remove scripts/inspect_chroma_db.py (debugging script). Replace all
_dbg() stderr writes in FileDescriptionGeneratorComponent with
standard logger calls at appropriate levels (debug/warning/info).

* fix: avoid double agent execution in OpenDsStarAgentRunnable.astream

astream was calling ainvoke after fully consuming the stream, which
re-executed the entire graph. Use the last streamed chunk as the final
result instead.

* fix: address PR review feedback from ogabrielluiz

- Mirror positional-to-kwargs mapping in async tool path (component_tool.py)
- Add final_answer guard to timeout suppression (codeact_agent_smolagents.py)
- Extract _build_graph_input() helper to deduplicate state dict x4 (open_ds_star_agent.py)
- Split ImportError from other exceptions in set_main_event_loop (open_ds_star_agent.py)
- Add sys.platform != 'win32' guard for select() on pipes (file_description_generator.py)
- Move ChromaError import before try block (chroma.py)
- Add logger.warning to __deepcopy__ fallback paths (component.py)
- Change accumulate_usage from additive to max-based merge (token_usage.py)
- Add async positional-arg test and update token usage tests

* increase opendsstar to 1.0.25 to fix pydantic dependency conflict

* vector stores: remove tool_mode=True for as_dataframe output

* increase OpenDsStar to 1.0.26

---------

Co-authored-by: Gal-Bloch <gal.bloch@ibm.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
Co-authored-by: Jordan Frazier <122494242+jordanrfrazier@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Hamza Rashid <74062092+HzaRashid@users.noreply.github.com>
Co-authored-by: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com>
Co-authored-by: Cristhian Zanforlin Lousa <cristhian.lousa@gmail.com>
Co-authored-by: Antônio Alexandre Borges Lima <104531655+AntonioABLima@users.noreply.github.com>
Co-authored-by: DeyLak <DeyLak@users.noreply.github.com>
Co-authored-by: Adam Aghili <Adam.Aghili@ibm.com>
Co-authored-by: Jordan Frazier <jordan.frazier@datastax.com>
Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>
Co-authored-by: Florian Schüller <schuellerf@users.noreply.github.com>
Co-authored-by: Steve Haertel <stevehaertel@users.noreply.github.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
Co-authored-by: Steve Haertel <shaertel@ca.ibm.com>
Co-authored-by: Mateusz Szewczyk <139469471+MateuszOssGit@users.noreply.github.com>
Co-authored-by: Debojit Kaushik <Kaushik.debojit@gmail.com>
Co-authored-by: Janardan Singh Kavia <janardankavia@ibm.com>
Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
Co-authored-by: vjgit96 <vijay.katuri@ibm.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@logspace.ai>
Co-authored-by: Harold Ship <harold.ship@gmail.com>
Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com>
Co-authored-by: keval shah <kevalvirat@gmail.com>
Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com>
Co-authored-by: Ram Gopal Srikar Katakam <44802869+RamGopalSrikar@users.noreply.github.com>
Co-authored-by: olayinkaadelakun <olayinka.adelakun@ibm.com>
Co-authored-by: Lucas Oliveira <62335616+lucaseduoli@users.noreply.github.com>
Co-authored-by: Edwin Jose <edwin.jose@datastax.com>
Co-authored-by: Himavarsha <40851462+HimavarshaVS@users.noreply.github.com>
Co-authored-by: Lucas Democh <ldgoularte@gmail.com>
Co-authored-by: Anderson Filho <115162146+andifilhohub@users.noreply.github.com>
Co-authored-by: April I. Murphy <36110273+aimurphy@users.noreply.github.com>
Co-authored-by: himavarshagoutham <himavarshajan17@gmail.com>
Co-authored-by: Viktor Avelino <viktor.avelino@gmail.com>
Co-authored-by: Hamza Rashid <hzarashid@gmail.com>
Co-authored-by: Rodrigo Nader <rodrigonader@MacBook-Pro-de-Rodrigo.local>
Co-authored-by: ogabrielluiz <gabriel@langflow.org>
Co-authored-by: Tarcio <rodriguestarcio.adv@gmail.com>
Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com>
Co-authored-by: Alfio Gliozzo <54385608+gliozzo@users.noreply.github.com>
Co-authored-by: Alfio Gliozzo <gliozzo@us.ibm.com>
Co-authored-by: OpenAI Codex <noreply@openai.com>
Co-authored-by: manav2000 <manav2000@users.noreply.github.com>
Co-authored-by: Deon Sanchez <69873175+deon-sanchez@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: DAVID BOAZ <DAVIDBO@il.ibm.com>
Co-authored-by: Arek Mateusiak <severfire@users.noreply.github.com>
Co-authored-by: DevByteAI <abud6673@gmail.com>
Co-authored-by: Alice Reis <alicemarianareis@gmail.com>
Co-authored-by: Alex Kuligowski <alekuligowski@gmail.com>
Co-authored-by: a-effort <35465683+a-effort@users.noreply.github.com>
2026-05-10 13:54:13 +00: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
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
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
2652d7a52e fix(LE-602): Update Pydantic to >=2.13.0 for fastapi-pagination v0.16.0 compatibility (#12938)
fix(LE-602): update pydantic to >=2.13.0 for fastapi-pagination v0.16.0 compatibility

- Updated pydantic from ~=2.12.5 to >=2.13.0,<3.0.0 in langflow-base
- Updated uv.lock with pydantic 2.13.3 and pydantic-core 2.46.3
- Kept SDK and lfx packages with flexible >=2.0.0 constraint (no fastapi-pagination dependency)
- Verified compatibility with existing tests
2026-04-29 21:00:56 +00:00
7d4d3e13a3 chore: bump versions to 1.9.2 (#12898) 2026-04-28 14:53:35 +00:00
b9e81f6edd Merge remote-tracking branch 'origin/main' into release-1.10.0 2026-04-23 19:21:59 -07:00
0732423f27 chore: security patch (#12725)
* chore: security patch

security patch

* chore: upgrade package-lock.json

* chore: smolagents and transformer update

* chore: redis upgrade

* chore: litellm upgrade

* fix: Pin click to avoid lower versions

## Root cause

**litellm 1.83.5+** introduced an exact pin `click==8.1.8` in its `requires_dist` (upstream bug [BerriAI/litellm#26154](https://github.com/BerriAI/litellm/issues/26154) — "Pinning exact dependency versions breaks downstream consumers"). When this branch bumped litellm to 1.83.11, uv was forced to downgrade click from 8.3.2 → 8.1.8. Click 8.2+ captures stderr separately by default; 8.1 merges it — hence `ValueError: stderr not separately captured`.

## Fix

- [pyproject.toml:155](pyproject.toml:155) — added `"click>=8.3.0"` to `[tool.uv] override-dependencies` with comment linking the upstream issue.
- [src/backend/base/pyproject.toml:112](src/backend/base/pyproject.toml:112) — same override so `langflow-base` Docker builds pick it up too.
- Regenerated `uv.lock` (click: 8.1.8 → 8.3.3).
- Patched the `click` entry in `src/backend/base/uv.lock` to 8.3.3 (that lockfile is used by `docker/build_and_push_base.Dockerfile` via `uv sync --frozen`; uv treats backend/base as a workspace member so I updated its click block directly — no other references to 8.1.8 remain).
- Reverted [src/lfx/tests/unit/cli/test_run_real_flows.py](src/lfx/tests/unit/cli/test_run_real_flows.py) back to its original `result.stderr` usage — now passes cleanly with click 8.3.3.

All 19 tests in the file pass.

* Update build_and_push_backend.Dockerfile

The `uv pip install` command doesn't read `[tool.uv] override-dependencies` from the target packages' pyproject.toml — those overrides only apply during `uv lock`/`uv sync`. The fix is to pass the overrides explicitly via `--overrides`.

Now let me verify it works by running the same install locally.

Resolution succeeded — click==8.3.3, aiohttp==3.13.5, litellm==1.83.11 all coexist. Let me also test without `--overrides` to confirm I reproduce the original failure.

Reproduced the Docker failure locally. Now test with the overrides file:

Fix verified — resolution succeeds with the overrides file, failing without. Let me clean up and show the final Dockerfile change.

## Summary

**Root cause:** The Dockerfile uses `uv pip install ./src/...` which **does not read** `[tool.uv] override-dependencies` from the target packages' `pyproject.toml` — those overrides only apply during `uv lock`/`uv sync`. On Linux, `cuga>=0.2.20` requires `aiohttp>=3.13.5`, but `litellm==1.83.11` exact-pins `aiohttp==3.13.3` (same upstream bug as the click pin, [BerriAI/litellm#26154](https://github.com/BerriAI/litellm/issues/26154)). Without an active override, resolution fails.

**Fix:** Write a `/tmp/uv-overrides.txt` file mirroring the workspace's `override-dependencies` (litellm, python-dotenv, openai, aiohttp, click) and pass `--overrides /tmp/uv-overrides.txt` to `uv pip install`.

Verified locally by reproducing the exact failure in an isolated tmp directory (to escape the workspace's pyproject.toml auto-apply), then confirming the overrides file resolves it:
- aiohttp==3.13.5 ✓
- click==8.3.3 ✓
- litellm==1.83.11 ✓
- cuga==0.2.22 ✓

* Templates version update

* Update .secrets.baseline

* chore: update overrides

* chore: bump version

* chore: bump main version

* chore: bump SDK version to 0.1.1

* chore: run uv lock and uv sync after SDK version bump

* chore: read the overrides from a single source

security patch

* chore: add pip check toggle

add pip check toggle

* chore: litellm base uv.lock update

* fix(chore): Pin litellm back to last working release

* fix(chore): Pin to 1.83 and higher litellm

* Update build_and_push_backend.Dockerfile

* chore: update base uv.lock

* fix: lazyload toolguard since its an optional extra

* Update .secrets.baseline

* Update component_index.json

* Rebuild component index

* Update component_index.json

---------

Co-authored-by: Eric Hare <ericrhare@gmail.com>
Co-authored-by: vijay kumar katuri <vijay.katuri@ibm.com>
(cherry picked from commit 60a8f76c3fde17124057626c671ea8162872837a)
2026-04-23 17:49:53 -07:00
957ade8880 chore: upgrade wxo adk to 2.8.0 (#12707)
* chore: update wxo adk (2.8.0)

* make sure all sites use the helper

* revert tests

* remove thin helper and use adk directly

(cherry picked from commit b4f0870980)
2026-04-23 17:49:51 -07:00
9d84ec14d9 chore: version bump 1.10.0
version bump
langflow: 1.10.0
langflow-base: 0.10.0
lfx: 0.5.0
langflow-sdk: 0.2.0
2026-04-15 16:11:11 -04:00
da516b7045 Merge release branch 2026-04-14 16:44:45 -07:00
38d142a723 fix: Upgrade cuga to 0.2.20 to resolve playwright dependency conflict (#12703)
* fix: upgrade playwright to 1.58.0 to address Chromium CVEs

- Add playwright>=1.58.0 to override-dependencies in pyproject.toml
- Update uv.lock: playwright 1.49.0 -> 1.58.0, pyee 12.0.0 -> 13.0.1
- Fixes CVE-2026-2313, CVE-2026-2314, CVE-2026-2315, CVE-2026-2319,
  CVE-2026-2321, CVE-2026-2441, CVE-2026-2648, CVE-2026-2649
- Ensures Docker builds download updated Chromium with security patches

* fix: update npm to latest version to address brace-expansion CVE-2026-33750

- Add npm update after Node.js installation in Dockerfile
- Fixes CVE-2026-33750 in system npm's brace-expansion dependency
- System npm had brace-expansion 2.0.2, update gets 5.0.5+
- Low risk change: npm is backward compatible, only affects CLI tool

* revert: remove npm update from Dockerfile

- npm update attempts were causing CI build failures
- Bundled npm has issues but updating it is proving problematic
- Focus on playwright CVE fix which is the primary concern
- brace-expansion CVE-2026-33750 is lower priority (DoS only)

* chore: sync uv.lock files

sync uv.lock files

* fix(mcp): dedupe edges in connect_components (#12701)

* fix(mcp): make add_connection idempotent to avoid duplicate edges

connect_components used to append a new edge unconditionally. Because
the edge id is deterministic from source/target/handles, calling it for
a pair the flow already had wired up (UI-then-MCP, batch retry, or just
a repeat call) produced a second edge with the same id, double-wiring
the flow at runtime.

Before appending, scan the existing edges for one with the same id and
return that instead. Different outputs/inputs between the same pair
still produce distinct ids and remain supported.

* test(mcp): cover dedupe against UI-saved edges, broaden match key

Older Langflow UIs saved edges with an `xy-edge__` id prefix instead of
the current `reactflow__edge-`, so an id-based dedup would miss the
UI-then-MCP case for any flow that came from an older version. Switch
the existence check to a structural one (source, target, sourceHandle
name, targetHandle fieldName) so the same logical connection dedupes
regardless of id format.

Add a fixture-driven test that loads MemoryChatbotNoLLM.json (an
xy-edge-prefixed flow) and replays each connection through
add_connection, asserting the edge count does not grow.

* fix(mcp): validate_flow fast-fails and reports partial errors (#12697)

* fix(mcp): validate_flow fast-fails and reports partial errors

validate_flow polled /monitor/builds for up to 30 seconds waiting for
every component to finish before reporting errors. When a component
fails early (for example a missing required field), downstream
components never run, so the loop waited out the full window and
returned just "Build timed out: N/M components completed" with no
actionable context.

- Short-circuit as soon as any completed build reports valid: false;
  return those errors immediately instead of polling on.
- On timeout, include the errors from the builds that did complete
  plus a component_count so the caller can see progress.
- Extract _collect_build_errors so the poll loop and timeout branch
  share the same error shape.

* fix(mcp): stream validate_flow build inline instead of polling

The previous implementation triggered an async build and polled
/monitor/builds, which depended on FastAPI BackgroundTasks firing the
log_vertex_build calls after the trigger request had returned. Under
ASGI test transport these tasks never run, so /monitor/builds stayed
empty and validate_flow timed out with component_count=0.

Switch to event_delivery=direct so the build streams its events back
inside the same request:

- Drive the build via client.stream_post and aggregate per-vertex
  results from end_vertex events.
- Fast-fail on the first vertex with valid=false, since downstream
  vertices depend on it and would not produce useful information.
- Surface top-level error events as a single flow-level error.
- Replace _collect_build_errors with _extract_vertex_error, which
  reads the structured error payload from the end_vertex outputs.

Update the lfx unit tests to use the streaming shape and tighten the
backend integration test to assert real success now that the build
actually runs end to end under ASGI.

* fix(graph): make end_all_traces_in_context Python 3.10 compatible

The implementation called asyncio.create_task(coro, context=context),
but the context= keyword was added to create_task in Python 3.11. On
3.10 it raised TypeError. The bug was latent because nothing in the
test suite previously consumed a streaming build response far enough
for Starlette to dispatch the post-response BackgroundTasks where this
code lives. The validate_flow streaming change exposes it.

On 3.10, route the create_task call through context.run so the new
Task copies the captured context as its current context, matching the
isolation the 3.11 path provides via the context= kwarg.

Add a regression test that asserts end_all_traces sees the value of a
contextvar set before the context was captured, even after the caller
mutates that var.

* fix: failing wxo list llm test (#12700)

patch service layer and update failing test

* [autofix.ci] apply automated fixes

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

* Try to fix the missing typer import

---------

Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
Co-authored-by: Adam Aghili <Adam.Aghili@ibm.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@logspace.ai>
Co-authored-by: Hamza Rashid <74062092+HzaRashid@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
2026-04-14 21:23:12 +00:00
19df4606ae chore: update deps (#12657)
* chore: update deps

update deps due to sec vuln

* chore: langchain-core>=1.2.28

langchain-core>=1.2.28

* chore: update pypdf

pypdf 6.10

* chore: pyarrow, openai, litellm, mem0ai, toolguard

picomatch, pyarrow, openai, litellm, mem0ai, toolguard

* chore: override litellm

* chore: match base uv.lock to root

* chore: update tool.uv position

update tool.uv position

* chore: langflow-base[complete]>=0.9.0

langflow-base[complete]>=0.9.0

* chore: revert pyarrow

revert pyarrow

* chore: revert "lfx~=0.4.0",

* chore: lfx white space

* chore: remove allow-direct-references = true

* chore: uv lock --upgrade after merge
2026-04-13 23:23:37 +00:00
95d4c94ef9 fix: upgrade playwright to 1.58.0 to address Chromium CVEs (#12668)
* fix: upgrade playwright to 1.58.0 to address Chromium CVEs

- Add playwright>=1.58.0 to override-dependencies in pyproject.toml
- Update uv.lock: playwright 1.49.0 -> 1.58.0, pyee 12.0.0 -> 13.0.1
- Fixes CVE-2026-2313, CVE-2026-2314, CVE-2026-2315, CVE-2026-2319,
  CVE-2026-2321, CVE-2026-2441, CVE-2026-2648, CVE-2026-2649
- Ensures Docker builds download updated Chromium with security patches

* fix: update npm to latest version to address brace-expansion CVE-2026-33750

- Add npm update after Node.js installation in Dockerfile
- Fixes CVE-2026-33750 in system npm's brace-expansion dependency
- System npm had brace-expansion 2.0.2, update gets 5.0.5+
- Low risk change: npm is backward compatible, only affects CLI tool

* revert: remove npm update from Dockerfile

- npm update attempts were causing CI build failures
- Bundled npm has issues but updating it is proving problematic
- Focus on playwright CVE fix which is the primary concern
- brace-expansion CVE-2026-33750 is lower priority (DoS only)

---------

Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
2026-04-13 21:04:34 +00:00
34886de048 fix: Updated Pillow minimum version (#12609)
* fix(frontend): enforce brace-expansion override

* fix: enforce handlebars version >=4.7.9 in frontend overrides

* fix: update Pillow minimum version to 12.1.1

---------

Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
2026-04-09 20:32:58 +00:00
499815a630 feat: add policies component for tool protection via ToolGuard (#12592)
* feat: add policies component for tool protection via ToolGuard

Reintroduce the policies component from #12564 (originally by @boazdavid).
Adds policy-based tool protection system with business policy enforcement
using ToolGuard, including guard code generation from policy definitions,
support for multiple language models, and enhanced tool metadata.

Adds toolguard>=0.2.4 dependency and click>=8.3.2 override.

* [autofix.ci] apply automated fixes

* Update dependencies for new toolguard

* Update component_index.json

* Update uv.lock

---------

Co-authored-by: DAVID BOAZ <DAVIDBO@il.ibm.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-04-09 15:13:20 +00:00