Commit Graph

18163 Commits

Author SHA1 Message Date
2f061d470e fix(execution): register ExecutorService factory and update seam test mocks
- register ExecutorServiceFactory in register_all_service_factories so
  EXECUTOR_SERVICE resolves at app startup; without it the seam raised
  NoFactoryRegisteredError across integration and mcp tests
- test_base.py graph.async_start mocks now default the leading positional
  param (the seam calls async_start with inputs as a keyword), fixing the
  'missing 1 required positional argument' failures
- add executor_kind to the settings composition EXPECTED_FIELDS set
2026-06-17 15:39:05 -03:00
276ed1f1d5 fix(execution): close async generators on early exit and harden seam tests
- run_to_completion and Coordinator.stream wrap iteration in contextlib.aclosing
  so the underlying generator is finalized when the loop returns or raises early
- execute_loop_body wraps its stream in aclosing for the same mid-iteration guarantee
- drop the unused inputs param from Coordinator.stream; the streaming path reads
  initial_inputs from runtime_options, so inputs was a silent no-op, and document it
- test_coordinator_uses_settings_executor_kind uses monkeypatch + a finalizer so a
  mid-test failure can't poison session settings
- test_registry_returns_same_executor_instance_across_runs builds a fresh graph per run
- test_set_default_coordinator_overrides_singleton restores the singleton afterward
2026-06-17 15:24:42 -03:00
357ea19156 test(execution): contract suite, cancellation guarantees, seam docstrings
Robustness pass on the execution seam after using it to integrate an external
executor end-to-end. Four things this pins down:

1. Reusable executor contract suite
   - tests/unit/execution/test_executor_contract.py
   - ExecutorContract with 7 universal seam guarantees: kind shape, execute()
     returns an AsyncIterator, stream ends with exactly one RunComplete,
     instance is reusable across runs, concurrent runs are isolated, consumer
     cancellation does not hang or leak, execute() signature is stable.
   - TestInProcessExecutorContract subclasses and provides fixtures. Downstream
     executors (stepflow, future remote/sandbox) get the same battery by
     subclassing and overriding two fixtures.

2. Cancellation/cleanup correctness
   - tests/unit/execution/test_cancellation.py
   - InProcessExecutor wraps graph.async_start() in try/finally with explicit
     aclose so consumer aclose cascades to the underlying graph generator.
     Previously the inner generator was abandoned and only finalized on a GC
     pass: a real leak for executors holding subprocesses or sockets.
   - Coordinator.run and Coordinator.stream propagate aclose the same way so
     the full chain (consumer -> coordinator -> executor -> graph) cleans up
     deterministically.

3. Documented seam contracts
   - Unit.runtime_options: free-form bag, "_"-prefixed keys reserved for
     executor-internal flags, common in-process keys listed.
   - StepResult.payload: untyped on purpose; each executor defines its own
     event vocabulary; consumers normalize at consumption site.
   - RunComplete.outputs: only the legacy in-process path populates it;
     streaming consumers should collect from StepResult.payload.
   - Executor ABC: lifecycle (shared instance, must be reusable, must tolerate
     concurrent execute() calls and consumer aclose).

4. Coordinator-routed E2E suite
   - tests/unit/execution/test_coordinator_e2e.py
   - Real Graph through Coordinator -> registry -> InProcessExecutor chain.
   - Asserts payload shape, RunComplete never leaks to stream() consumers,
     dispatch routes to configured kind, registry returns same instance.

Full execution suite: 63 passing. flow_executor coordinator test: passing.
2026-06-17 14:37:40 -03:00
e320e5df5d feat(execution): make executor seam pluggable via lfx services
Introduce an ExecutorService that owns the registry and the default coordinator,
discovered through the standard lfx ServiceManager (parity with cache, database,
storage, etc). Add an executor_kind setting so the default kind can be configured
without touching code, and an lfx.executors entry-point group for third-party
executors. Entry-point discovery refuses to overwrite an existing kind so an
installed package cannot silently replace the built-in in-process executor;
explicit replacement still works through ExecutorService.register().

The lfx.execution public API (get_default_coordinator, get_default_registry,
set_default_coordinator, reset_default_coordinator) now resolves through the
service manager but keeps the same surface, so existing call sites in Graph.arun,
flow_executor, the CLI, run/base, and loop_utils are unchanged.

Also surface root-cause tracebacks in lfx.services.deps.get_service: the helper
still returns None on failure (callers like get_db_service rely on that), but it
now logs the exception so init failures stop disappearing into the void.
2026-06-17 14:37:40 -03:00
bbee6c7dca refactor(execution): wrap default singletons in _Defaults holder, drop noqas 2026-06-17 14:36:34 -03:00
eeb357b376 test(execution): shared simple_graph fixture, reset_default_coordinator helper, real-executor loop tests, behavior assertions 2026-06-17 14:36:34 -03:00
219990a3d3 refactor(execution): add Coordinator.stream helper, lift imports, replace em-dash 2026-06-17 14:36:34 -03:00
6fe62fa059 fix(execution): explicit legacy dispatch flag, forward fallback_to_env_vars, real-graph concurrency tests 2026-06-17 14:36:15 -03:00
b2f1bef1d0 feat(execution): route Loop subgraph through coordinator (seam #4) 2026-06-17 14:36:15 -03:00
154172451a feat(execution): route CLI and run/base through coordinator (seam #3) 2026-06-17 14:36:15 -03:00
6c760288fe feat(execution): route flow_executor through coordinator (seam #2) 2026-06-17 14:36:14 -03:00
6e75e0d225 feat(execution): route Graph.arun through coordinator (seam #1) 2026-06-17 14:35:47 -03:00
23b71ec90e feat(execution): default singleton with in-process pre-registered + setter 2026-06-17 14:35:46 -03:00
aff533a512 feat(execution): add Coordinator with streaming run + run_to_completion 2026-06-17 14:35:46 -03:00
eb58000faf feat(execution): add InProcessExecutor (streaming + legacy passthrough) 2026-06-17 14:35:46 -03:00
79786880fe feat(execution): add executor registry (register/get only) 2026-06-17 14:35:46 -03:00
9a4421e1eb feat(execution): add identity partition function 2026-06-17 14:35:46 -03:00
8595490356 feat(execution): add Executor abstract base class 2026-06-17 14:35:46 -03:00
d657198245 feat(execution): add core types (Unit, StepResult, RunComplete) 2026-06-17 14:35:46 -03:00
3e96a7b80c feat(execution): scaffold execution package with test isolation fixture 2026-06-17 14:35:46 -03:00
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
97c5598ee3 fix(authz): schedule periodic audit-log retention cleanup (#13546)
* fix(authz): schedule periodic audit-log retention cleanup

clean_authz_audit_log() was only invoked once, at startup inside
initialize_services(). A long-running instance never pruned authz_audit_log
again after boot, so the table grew unbounded between restarts even though the
retention helper was already implemented and unit-tested.

Wire the same helper to a recurring background worker:

- New AuditLogCleanupWorker (services/task/audit_cleanup.py), modelled on the
  sibling temp_flow_cleanup.CleanupWorker: a stop-event-driven asyncio task that
  prunes on a fixed interval in its own session_scope(). Best-effort -- the
  helper logs-and-swallows DB errors and an outer guard keeps the loop alive, so
  it never blocks the event loop or request path.
- Gated: the worker only schedules when AUTHZ_AUDIT_ENABLED is True and
  AUTHZ_AUDIT_RETENTION_DAYS > 0; otherwise start() is a no-op. Retention=0
  stays a no-op end to end.
- Sleep-first loop: the unconditional startup sweep still prunes at boot, so the
  first scheduled pass waits one interval to avoid a redundant immediate delete.
  The startup sweep is left unchanged.
- New AUTHZ_AUDIT_CLEANUP_INTERVAL setting (default 86400 = daily, floor 300s).
- Started/stopped from the application lifespan, both best-effort.

Tests (test_audit_cleanup_worker.py) show cleanup runs repeatedly on the
recurring schedule (not just at startup), is a no-op when retention or auditing
is disabled, survives sweep failures, and -- end to end against a real SQLite
engine -- prunes a row inserted after startup while leaving in-window rows.

Closes the audit-retention-scheduling gap (C) for OSS RBAC on release-1.10.0.

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

* refactor(authz): read AUTHZ_AUDIT_CLEANUP_INTERVAL directly

The cleanup worker resolved the sweep interval via getattr-with-default
plus a TypeError/ValueError guard, mirroring the field default in a
module constant. Pydantic already guarantees the field is present and
>= 300, so those fallbacks were unreachable and the constant was a
second source of truth that could drift.

Read the setting directly; keep DEFAULT_CLEANUP_INTERVAL_SECONDS only as
the pre-start() placeholder for unstarted workers. Drop the matching
missing/garbage-fallback test assertion.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 21:18:54 +00:00
5d1c36c8b1 test(authz): RBAC enforcement + share-lifecycle integration tests via a test-double enforcer (#13549)
* test(authz): RBAC enforcement + share-lifecycle integration tests via a test-double enforcer

No automated test exercised end-to-end authorization enforcement. The OSS
authorization service is a pass-through (enforce() always returns True,
supports_cross_user_fetch() is False), so allow/deny semantics could not be
asserted against it — only guard-wiring unit tests existed.

Add a lightweight, OSS-only test-double enforcer plus integration tests that
drive the real flow routes over HTTP under a genuine allow/deny signal — no EE
Casbin package required.

- _policy_double.py: PolicyTestAuthorizationService derives allow/deny from the
  seeded authz_role / authz_role_assignment / authz_share rows and sets
  SUPPORTS_CROSS_USER_FETCH=True. install_policy_authz() swaps it onto the
  service manager (str-enum keys make ServiceType interchangeable) and flips
  AUTHZ_ENABLED=true / AUTHZ_SUPERUSER_BYPASS=false, restoring both on exit, so
  every get_authorization_service() call site (guards, fetch, listing, helpers)
  sees it for the duration of a test. Ships seed helpers (roles/assignments/
  shares) so tests stay declarative.

- test_rbac_enforcement_integration.py:
  * Role matrix (Phase 1.11) on flow routes, with flows owned by a separate user
    so the guards' owner-override does not mask the role decision:
      - viewer: read + execute (build) allowed; write/delete -> 404; create -> 403
      - developer: write + create allowed; delete -> 404
      - admin: full, including delete
  * Share lifecycle (Phase 3.13): Alice shares a flow with Bob ->
    Bob GET/PATCH/build succeed; without the share every fetch route -> 404
    (UUID-privacy mask). A read-level share grants GET but 404s PATCH, proving
    permission_level (not mere share presence) is enforced.
  * Domain resolution: a workspace-scoped grant authorizes a flow in that
    workspace but 404s a flow in another — trips if _resolve_authz_domain
    regresses.

In each test a cross-user GET -> 200 (only possible with enforcement on +
share-aware fetch) is the linchpin proving the paired deny is real enforcement,
not an owner-scoped fetch miss; removing a guard flips a 404 to 200/200.

Closes the enforcement integration-test gap (D) for OSS RBAC on release-1.10.0.
Per the ticket's triage note, the reusable test-double also stands alone if the
team prefers the deny-path matrix to live in EE.

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

* test(authz): harden policy double per review — strict scoped grants, deterministic seeding, read-share build denial

- _assignment_covers: a scoped assignment missing domain_id no longer
  widens to global coverage; only domain_type='global' is global
- assign_role: fail fast (ValueError) on non-global assignments without
  a domain_id so malformed grants can't hide domain-resolution bugs
- seed_system_roles: overwrite preexisting viewer/developer/admin rows
  so the asserted policy matrix is always SYSTEM_ROLE_PERMISSIONS
- read-only share test: also assert build/execute is denied (404), not
  just PATCH

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:35:05 -07: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
72f86c96eb ci: gate backend tests by Python changes (#13614)
* ci: gate backend tests by Python changes

* fix(ci): update test conditions to include docs-only path filter

* Update .github/workflows/ci.yml

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

---------

Co-authored-by: Adam-Aghili <149833988+Adam-Aghili@users.noreply.github.com>
2026-06-15 18:35:30 +00:00
bb930e2ffe docs: build docker from source (#13041)
* docs-add-build-from-source-and-refresh

* peer review

* peer-review

* peer-review

* peer-review
2026-06-15 17:16:28 +00:00
ca29afab5c fix(frontend): restore Inspection Panel access to hidden advanced fields (1.11.0) (#13626)
fix(frontend): restore Inspection Panel access to hidden advanced fields

Fields that were both advanced=True and listed in HIDDEN_FIELDS became
unreachable from the Inspection Panel: hidden from the node body (advanced)
and removed from the panel (HIDDEN_FIELDS), leaving no edit path. This
affected every HIDDEN_FIELDS entry, originally reported for Chat Input/Output
Store Messages (should_store_message).

Keep HIDDEN_FIELDS out of the default advanced view (the #12473 declutter
intent) but stop filtering them out of edit-fields mode, so users can surface
and edit them via the visibility toggle. Also drop the stale Agent verbose
entry (removed from the component via drop = {verbose}) while keeping the
still-live format_instructions and output_schema hidden. i18n the two
remaining hardcoded panel strings.

Fixes #13595
2026-06-15 16:51:46 +00:00
de06b9176a fix(frontend): duplicate tooltip + raw i18n key on collapsed sidebar nav (1.11.0) (#13652)
fix(frontend): remove duplicate tooltip and raw i18n key on collapsed sidebar nav

The floating canvas control nav (shown when the sidebar is collapsed)
rendered two tooltips per icon: a native `title` attribute on
ControlButton plus the styled ShadTooltip. On top of that,
MemoizedComponents passed the raw i18n key (`item.tooltip`) as the
tooltip text instead of running it through `t()`, so the ShadTooltip
exposed strings like `sidebar.nav.bundles` while the native title showed
the bare id (`bundles`).

- CanvasControlButton: drop the native `title` (the duplicate tooltip);
  keep accessibility via `aria-label`. The ShadTooltip is the single
  visual tooltip. This also removes the redundant native tooltip from the
  zoom/fit/lock control buttons.
- MemoizedComponents: translate the nav tooltip with `t(item.tooltip)`.

Adds an isolated CanvasControlButton regression test asserting no native
`title` and that the label is surfaced via aria-label + ShadTooltip.
2026-06-15 14:44:37 +00:00
02319696dc feat: add docs feedback components (#13627)
* add-docs-page-feedback-component

* make-buttons-same-size
2026-06-12 18:03:54 +00:00
3e3a24e353 fix: fail fast when Redis job queue backend is unreachable (#13456)
* fix: fail fast when Redis job queue backend is unreachable

When LANGFLOW_JOB_QUEUE_TYPE=redis is set but Redis is not reachable,
Langflow booted normally and then raised a raw redis ConnectionError as
a 500 on the first flow execution, with no clear cause.

Probe Redis at startup (bounded retry) and abort boot with an actionable
error when it stays unreachable, mirroring the existing external-cache
connectivity check. Translate a later Redis outage on the build and
ownership paths into a clean HTTP 503 via a typed
JobQueueBackendUnavailableError instead of a raw stack trace.

* [autofix.ci] apply automated fixes

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

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

* [autofix.ci] apply automated fixes

* fix: address review - probe redis pre-start, redact credentials, cancel orphaned build

- is_connected() now probes with a temporary client when the service has
  not started yet: the startup fail-fast in initialize_services() runs
  before the per-worker start() creates the client, so it previously
  rejected every redis boot, healthy or not
- connection_target redacts URL userinfo so credentials never reach
  server logs or the HTTP 503 detail
- build_flow cancels the just-started build (best-effort) when owner
  registration fails, instead of leaving an unreachable build running
- register_job_owner only records the local owner after the Redis write
  succeeds, so a failed write cannot leave same-worker ownership checks
  passing while other workers see the job as unowned

---------

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-06-12 17:13:55 +00:00
538bcf3845 feat: docs page copy-as-markdown keyboard shortcut (#13628)
* add-copy-page-keyboard-shortcut

* peer-review
2026-06-12 16:58:50 +00:00
415323ec6d docs: migrate code blocks to native Prism and restyle API reference pages (#13299)
* docs: migrate code blocks from CodeSnippet to native Prism

Replace the custom CodeSnippet component (@code-hike/lighter) with
Docusaurus's native @theme/CodeBlock across all MDX files (current and
versioned docs). Add bash to additionalLanguages and swizzle
prism-include-languages.js to add custom token highlighting for shell
commands and flags. Remove @code-hike/mdx dependency.

* docs: improve inline code styling

Darken inline code background, increase horizontal padding to 0.4em,
fix vertical alignment, and remove border in light mode.

* docs: address PR review — fix code slice regression and CSS/regex polish

- Inline RecursiveCharacterTextSplitter inputs and methods as literal
  code blocks in concepts-components.mdx (current + 1.8.0 + 1.9.0),
  restoring the focused slices lost when migrating from CodeSnippet
- Scope bash-plain Prism regex to unambiguous CLI subcommands only,
  removing generic bash builtins (run, add, get, set, start, stop, etc.)
- Merge duplicate .theme-code-block CSS rules into a single declaration

* fix(docs): prevent horizontal scroll on API docs pages

The Redoc two-column layout (sidebar 300px + api-content 1300px)
totals 1600px, expanding .main-wrapper beyond narrower viewports
because it has overflow:visible. Clips at .main-wrapper using the
html.plugin-redoc class that Docusaurus adds on API pages only.

* fix(docs): API docs sidebar and layout fixes

- Disable Redoc built-in search (disableSearch: true)
- Pin sidebar top to navbar height (top: 60px) so it never hides behind navbar
- Remove hardcoded #111 background from dark mode sidebar

* fix(docs): render markdown correctly in API docs descriptions

The _clean_descriptions function was converting newlines to <br> tags,
mixing HTML with Markdown. CommonMark stops parsing Markdown headings
(###) inside HTML blocks, causing them to appear as literal text in Redoc.

Replace the <br> conversion with a simple strip() so descriptions remain
pure Markdown and Redoc renders headings, lists, and code blocks correctly.

* feat(docs): align API docs colors with Langflow brand

- Set primaryColor to #F471B5 (Langflow pink)
- Add HTTP method badge colors matching Langflow palette
- Set schema.linesColor and requireLabelColor to brand pink
- Set inline code color to pink, headers to #e3e3e3
- Set sidebar background to #18181b (matches frontend dark bg)
- Set rightPanel background to #0d0d0f, codeBlock to #161618
- Refactor: move color config from CSS to theme.theme where safe
- Remove dead search input CSS (search disabled via disableSearch:true)
- Consolidate duplicate .menu-content rules

* wip(docs): API docs styling — colors, components, light/dark themes

* fix(docs): fix Response samples h3 title padding and refactor HTTP method button CSS

* feat(docs): add sidebar dark background, active item styles, and right panel color adjustments

* fix(docs): add sidebar borders and remove operation divider border

* fix(docs): fix expanded response background and align dark/light theme colors

* refactor(docs): standardize selectors, comments and remove duplicate rules in redocusaurus.css

* refactor(docs): apply PR review — CSS custom properties, version pin, dom version comments, fix overflow

* fix(docs): fix Redocly badge visibility covered by sidebar background

* fix(docs): extend sidebar border-right to Redocly badge area

* refactor(docs): replace hardcoded #ffffff label color with --redoc-text-label variable

* fix(docs): lighten inline code background in API docs dark theme

Redoc's default typography.code.backgroundColor (rgba(38, 50, 56, 0.05))
is nearly invisible over the dark background. Override it with
rgba(255, 255, 255, 0.05) in dark theme only, excluding pre > code so
code sample blocks stay unaffected.

* feat(docs): align docs primary pink with API spec brand color

Use #f471b5 (API spec primaryColor) as --ifm-color-primary in dark theme
and #e44fa0 (slightly darkened for contrast on white) in light theme.
Remove dark-theme pink overrides in sidebar.css (#ff6ad0 CTA and
hsla(329, 55%, 68%) active TOC link) — they compensated for the old
muted pink and are redundant now that the primary itself is bright.

* feat(docs): lighten dark theme text colors for better readability

Bump body text (#a8a8b0 -> #bcbcc4), headings (#cdcdd4 -> #dcdce2)
and sidebar menu (#8a8a92 -> #9c9ca4) one step brighter.

* chore(docs): add IBM Equal Access accessibility-checker setup

Add accessibility-checker as devDependency with aceconfig.js (policy
IBM_Accessibility, JSON reports in docs/a11y-results/, gitignored).
Scan with: npx achecker <url> against a built docs site.

* fix(docs): WCAG AA contrast and ARIA fixes across docs and API reference

Validated with IBM Equal Access scans (light theme): home, quickstart and
component pages at 0 violations; /api from 3382 down to 167 (all remaining
are Redoc-internal DOM: schema table headers, svg/select labels).

Docs site:
- Light primary pink #d11074 — passes 4.5:1 on white and inline-code bg
- Light Prism palette darkened per-token to pass 4.5:1 on #f9f9fd
- TabItem swizzled to give tabpanels an accessible name (aria-label)
- codeBlockA11y client module: scrollable code blocks get role=region +
  unique label; non-scrollable ones lose the needless tabindex

API reference (Redocusaurus):
- redocA11y client module: role=main on api-content, role=navigation on
  sidebar — fixes 1924 aria_content_in_landmark violations
- HTTP method badges and response chips darkened to pass with white text
- Light-theme overrides: accessible pink #cd1072 for links, required
  markers, constraint chips, schema tree lines; darker grays for utility
  buttons and type labels (incl. 0.7-opacity wrapper fix)
- Sidebar active/hover items use regular text color, method badges keep
  their own colors; expandable property names match non-expandable ones

* fix(docs): WCAG AA contrast fixes for dark theme

Validated with IBM Equal Access scans in dark mode (temporary
colorMode.defaultMode flip during scanning): home, quickstart and
component pages at 0 violations; /api matches light at 167 remaining
(all Redoc-internal DOM: table headers, svg/select labels).

- Code block comments/line numbers #4a5060 -> #798197 (4.56:1 on #18181a)
- Redoc dark sample tokens: boolean/null #e95c59, number #5392b8
- Status-code tabs: lift docusaurus-theme-redoc's #303846 !important
  selected-tab rule with a higher-specificity override
- oneOf variant buttons: dark text in both themes (their white/pink
  backgrounds are theme-independent)
- redocA11y client module: patch response chip colors (success green /
  error red) to dark-accessible variants when data-theme=dark — a single
  Redoc theme color cannot pass on both light and dark derived
  backgrounds, and status is only distinguishable by computed color

* fix(docs): resolve remaining Redoc-internal accessibility violations

Extend the redocA11y client module with semantic patches for Redoc DOM
the theme cannot reach (validated: 0 IBM Equal Access violations on all
scanned pages in both light and dark themes):

- Decorative svg chevrons/arrows: aria-hidden=true (svg_graphics_labelled)
- Content-type dropdowns: aria-label (input_label_exists)
- Schema field tables (2-col name|description layout, no <th> anywhere):
  role=presentation — content reads in DOM order; role=rowheader on <td>
  is invalid ARIA inside a native table (table_headers_exists/related)
- Semantic patches run on the next animation frame after DOM changes so
  Redoc's lazy-rendered operations are covered immediately; the heavier
  color patch stays debounced

* ci(docs): gate docs accessibility with IBM Equal Access scans

Add test-docs-accessibility job to docs_test.yml (rides the existing
docs/** path filter from ci.yml): build + scan 4 representative pages
(home, quickstart, component page, /api) in light theme, then flip
colorMode.defaultMode to dark, rebuild and scan again.

- scripts/a11y-ci.sh: serves the build and runs npx achecker per page
  with one retry to absorb Redoc lazy-render timing flakes; any real
  violation fails the job (failLevels: violation)
- aceconfig.js: pin ruleArchive to 19May2026 so IBM rule updates don't
  break CI without a deliberate bump

* ci(docs): fix Chrome sandbox launch on Ubuntu 24.04 runners

Ubuntu 24.04 restricts unprivileged user namespaces via AppArmor, which
prevents puppeteer's Chrome (used by the IBM checker) from starting its
sandbox. Re-enable them with the documented sysctl workaround instead of
weakening the browser with --no-sandbox.

* fix(docs): align response status code with description text

Redoc sets vertical-align: top and a smaller line-height on the status
code <strong> inside response buttons, leaving "200" visually higher
than "Successful Response". Align both to the shared text baseline.

* refactor(docs): apply PR review feedback

- redocA11y: match only real Redoc routes (/api, /api/workflow) — a bare
  startsWith("/api") also matched docs pages like /api-request and
  leaked one body MutationObserver per navigation
- codeBlockA11y: also observe the hidden attribute — Docusaurus tabs
  toggle panels via hidden (no childList mutation), so scrollable blocks
  inside an initially hidden tab were never re-evaluated for tabindex
- Extract Prism themes to src/prismThemes.js (docusaurus.config.js was
  past the 600-line red flag)
- concepts-components.mdx (current + 1.9.0 + 1.8.0): comment pointing
  hardcoded snippets to recursive_character.py to mitigate drift

Validated: clean build + IBM Equal Access scans 4/4 passing.

* replace-openapi-file-with-1.10

* migrate-prism-changes-to-1.10-version

* a11y-script-dont-block

---------

Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
2026-06-12 13:58:04 +00:00
29140c06f0 fix(ci): resolve validate-version output in release-lfx changelog link (1.11.0) (#13612)
fix(ci): resolve validate-version output in release-lfx changelog link

The create-release job references
needs.validate-version.outputs.current_version in its generated release
notes (the Full Changelog compare link), but validate-version was not in
the job's needs array, so the expression evaluated empty and the link
rendered as compare/v...lfx-vX.Y.Z (broken base).

Add validate-version to the create-release needs. This adds no real
serialization: create-release already waits on release-lfx, which
transitively requires validate-version via run-tests, and the job's
always() if-condition is unaffected.

Flagged by actionlint: property "validate-version" is not defined in
object type {build-docker, release-lfx}.
2026-06-10 08:42:28 -07:00
dea7b09257 fix(ci): create GitHub releases on the dispatched v-prefixed tag (1.11.0) (#13607)
fix(ci): create GitHub releases on the dispatched v-prefixed tag

The create_release job passed the bare version (v stripped) as the
release tag with no commit target, so when that tag did not exist
GitHub minted a new lightweight tag at the default-branch HEAD -- the
wrong commit, still carrying the previous version (main only adopts a
release's version via the post-release back-merge). Every release since
1.8.2 shipped a stray bare tag (1.8.2, 1.8.3, 1.9.0-1.9.6, 1.10.0)
pointing at a previous-version commit, and the GitHub release had to be
manually re-pointed to the real vX.Y.Z tag after each release.

- create_release now attaches the release to inputs.release_tag for
  stable releases; pre-releases keep their computed tag (e.g.
  1.10.0rc1) but it is minted at the release commit via 'commit:'.
- release-lfx.yml pins the minted lfx-v* tag to github.sha instead of
  the default branch.

The validate-tag-format guard (#12847) only blocks at dispatch time;
create_release was re-creating the very duplicates it guards against.
2026-06-10 08:41:41 -07:00
84c3bbebcd fix(ci): scope nightly migration-test pre-releases to the langflow stack (1.11.0) (#13604)
fix(ci): scope nightly migration-test pre-releases to the langflow stack

The previous fix (#13599) added a global --prerelease=allow, which let
UNRELATED dependencies resolve to alphas: on nightly run 27274206250
the stable->nightly upgrade pulled pydantic 2.14.0a1 + pydantic-yaml
1.6.1a1, and the pydantic alpha breaks langchain-core at import time
(RunnablePassthrough pydantic ValidationError), failing the nightly
boot right after a successful install. Clean installs were fine - only
this upgrade path resolved the alpha combo.

Scope pre-release eligibility to the langflow lockstep stack instead:
uv accepts a pre-release when the package's own requirement carries a
pre-release marker, but not via transitive pins, and the nightly chain
is langflow -> langflow-base -> lfx -> langflow-sdk with exact ==devN
pins. Request each directly; langflow-sdk versions independently
(0.2.0.devN), so an explicit .dev0 floor marks it eligible while lfx's
exact pin selects the version. The 'latest' branch gets the same
treatment via .dev0 floors on all four.

Verified by dry-run against PyPI: langflow/langflow-base/lfx at
1.11.0.dev2 + langflow-sdk 0.2.0.dev2 resolve with pydantic staying at
stable 2.13.4.
2026-06-10 07:19:36 -07:00
75e01157fe fix(ci): allow pre-releases when pinning the nightly in migration validation (1.11.0) (#13600)
fix(ci): allow pre-releases when pinning the nightly in migration validation

Migration Test: pip/venv (stable -> nightly) failed deterministically on
nightly run 27260425158 (twice, including a rerun):

  hint: langflow-base was requested with a pre-release marker (e.g.,
  langflow-base==1.11.0.dev1), but pre-releases weren't enabled
  (try: --prerelease=allow)

This is the first nightly publishing as a canonical .devN pre-release
of the langflow distribution (nightly -> stable bundle cutover). The
'latest' branch of the upgrade step already passes --prerelease=allow,
but the pinned-version branches do not. uv implicitly allows the
pre-release for the directly requested ==X.Y.Z.devN pin, yet langflow's
metadata pins langflow-base==X.Y.Z.devN transitively, and uv rejects
transitive pre-releases unless they are enabled - so the install fails
after the stable uninstall, sinking the migration test.

Add --prerelease=allow to both pinned-version install lines.
2026-06-10 04:50:26 -07:00
0555eeced1 fix(test): gate models.dev background refresh out of tests (#13596)
Integration tests failed twice in nightly run 27260425158 with pyleak
EventLoopBlockError - first Integration Tests 3.14, then 3.12 on the
rerun, each time in a different test. The blocking stack points at
refresh_models_dev_periodically: every app boot unconditionally starts
a lifespan task that immediately fetches https://models.dev/api.json,
so the request lands mid-test in whatever test happens to be running.
Under pyleak's asyncio debug instrumentation the fetch blocked the loop
0.797s against a 0.2s threshold. Whichever test draws the short straw
flakes - which is why it looked transient and moved between versions.

Add a LANGFLOW_MODELS_DEV_REFRESH env gate (default unchanged: enabled)
and disable it session-wide in the backend test conftest. Tests fall
back to the bundled static model lists, which is also deterministic.

Verified: with the gate set, app boot makes zero models.dev requests;
the previously failing integration test passes.
2026-06-10 04:36:38 -07:00
086e38898d fix(ci): anchor langflow-base version extraction in nightly docker build (1.11.0) (#13592)
fix(ci): anchor langflow-base version extraction in nightly docker build

The first nightly on the 1.11 workspace (tag v1.11.0.dev0, run
27253229568) failed in Build Nightly Base Package within seconds:
'Base version format is incorrect'. The extraction (uv tree, grep
langflow-base unanchored, awk field 3, first line) broke because uv
tree now prints the langflow-base workspace-root line
('langflow-base v1.11.0.dev0', two fields) before any dependency line
('langflow-base[complete] v1.11.0.dev0' under the langflow root, three
fields), so the first match yields an empty field 3 and the format
check exits 1. uv tree's stderr is discarded, which made the real
cause invisible in CI.

Anchor to the root line and take field 2 instead - the exact pattern
the langflow (main package) extraction in this same file already uses,
which is why the main-package builds passed on the same tag. Verified
both extractions print 1.11.0.dev0 against a local checkout of
v1.11.0.dev0.
2026-06-10 00:25:55 -07:00
d065523493 fix(test): raise spawn-child join timeout in test_multi_process_visibility (#13588)
The test spawns a child via multiprocessing spawn context, which
cold-imports the full langflow package (plus coverage's multiprocessing
hooks in CI) before appending a single event. The 10s join timeout is
routinely exceeded on a loaded CI runner sharing 4 vCPUs with a second
xdist worker: in nightly run 27253229568 (Unit Tests - Python 3.12 -
Group 5) the test failed all 12 executions (5 reruns x 2 step attempts),
each rerun exactly 10s apart - the join deadline, not a product bug.

Raise the liveness bound to 60s (join returns immediately when the
child exits, so the passing case is unaffected) and kill the child on
timeout so a hung spawn can't leak into later tests.
2026-06-09 23:13:35 -07:00
17447920f9 fix(ci): rebalance backend test splits with measured durations + raise unit-test step timeout (#13583)
Unit Tests - Python 3.12 - Group 3 has been failing at 98-99% on the
nightly: the job hits the nick-fields/retry 40-minute per-attempt timeout
and pytest is SIGTERM'd mid-test, so it looks like one flaky last test
when it is actually a deterministic timeout (and the internal retry plus
run-level retries can never succeed).

Root cause is twofold:

1. .test_durations was last regenerated ~May 2025 and covered only 2,219
   of ~9,500 current unit tests, so pytest-split weighted 77% of the
   suite at the 0.73s average. The expensive client-fixture tests
   (test_webhook.py, test_login.py - each pays a full create_app +
   lifespan boot per test, 60-120s late in a CI run) clustered into
   group 3's tail, making it ~8-10 minutes slower than its siblings
   (33:15 on 3.13, >40min on 3.12 which is additionally slowed by
   astrapy disabling SSL connection reuse on Python 3.12.0-11).
   The weekly store_pytest_durations workflow that should refresh the
   file has been dying at the 6-hour GitHub job limit every week (serial
   full-suite run no longer fits), so the file silently froze.

   This regenerates the file from real per-test wall-clock measured in
   the passing Python 3.13 nightly jobs (run 27246228762 attempt 1, all
   5 groups, parsed from the -vv xdist logs: per-worker start-to-start
   deltas). 9,508 tests now have measured durations; old entries are
   kept where no new measurement exists. Simulated least_duration
   split goes from one outlier group to 5 even groups (~24.6 min each)
   with the >50s tests spread 1-2 per group instead of 7 in one.

2. timeout_minutes 40 -> 50 gives headroom for matrix-cell variance
   (3.12 runs ~20% slower than 3.13) so a slightly slow cell degrades
   gracefully instead of burning 2x40min and failing the whole run.

Follow-ups (not in this PR): fix store_pytest_durations to run with
xdist or split groups so it fits the 6h limit; investigate the in-worker
degradation that makes client-fixture boots cost 8-12s early in a run
but 60-120s after ~30 minutes.
2026-06-09 21:28:02 -07:00
ee659ca38c fix(bundles): floor lfx pin at the minor line's .dev0 so nightlies resolve
The first 1.11.0.dev0 nightly failed its "Test Langflow Main CLI" step:
the fork bump's sync_bundle_lfx_pin.py re-synced every bundle floor to
lfx>=1.11.0, and PEP 440 sorts the nightly's 1.11.0.dev0 BELOW 1.11.0,
so the workspace-built bundles (whose metadata shadows the satisfiable
PyPI lfx-arxiv 0.1.1 during `uv pip install dist/*.whl`) reject the
branch's own lfx while langflow-base pins it exactly — unresolvable.

Floor at lfx>=X.Y.0.dev0,<(X+1).0.0 instead: X.Y.0.dev0 is the lowest
version PEP 440 admits in the minor line, so every devN / rcN / final
satisfies the floor while older lines and the next major stay excluded.
This closes the NIGHTLY.md activation-gate hole structurally — future
minor forks re-sync to a floor their own nightlies already satisfy.

- sync_bundle_lfx_pin.py: lfx_floor_spec emits the .dev0 floor
- port_bundle.py: mirrored _current_lfx_floor kept in step
- bundle pyprojects restamped via the script (arxiv/docling/duckduckgo/ibm)
- test_bundle_lfx_pin.py expectations updated (20/20 passing)
- NIGHTLY.md gate section annotated with the post-activation fix

uv.lock is unaffected (workspace lfx is recorded as an editable source
with no specifier — which is also why uv sync/lock passed in the same
job). The release.yml RC floor-relax sed still matches the new form;
now redundant but harmless. No bundle version bump needed: published
0.1.1 floors >=1.10.0.rc0, satisfiable by the whole 1.11 line.
2026-06-09 18:02:43 -07:00
7a784515e0 fix(lfx): restamp component index version after 1.11.0 fork bump (#13574)
The release-1.11.0 fork bumped lfx to 1.11.0 but left component_index.json's version field at 1.10.0. _read_component_index fails closed on exact version mismatch, so the bundled registry loads as None and the upgrade-gate tests fail (UpgradeFlowError: 'bundled component registry is empty or missing') across the LFX test matrix. That failure blocks the nightly's release-nightly-build job, so no canonical 1.11.0.devN is published and check-nightly-status blocks CI everywhere.

Surgical restamp: version -> 1.11.0 and recomputed sha256 (same orjson OPT_SORT_KEYS hashing and OPT_SORT_KEYS|OPT_INDENT_2 serialization as scripts/build_component_index.py). Entries unchanged. Verified the reader validation passes and the three failing tests go green.
2026-06-09 15:18:21 -07:00
fb64e45e75 chore: bump version to 1.11.0 2026-06-09 13:29:01 -07:00
13a937c5b7 feat(ci): nightly → stable bundles via canonical pre-releases + decision record [gated] (#13528)
* docs: record nightly→stable bundle cutover plan (gated on lfx 1.10.0)

Add src/bundles/NIGHTLY.md documenting why langflow-nightly currently
renames the bundles (lfx and lfx-nightly ship the same lfx/ import, so a
stable bundle would co-install both and collide) and the deferred cutover
(Approach A: canonical pre-releases; B: lfx as a bundle extra), gated on
stable lfx 1.10.0 being published to PyPI.

Also expand two docstrings in scripts/ci/update_lfx_version.py to state
the deeper install-conflict reason, not just the resolve failure. No
behavior change.

* feat(ci): nightly Approach A — canonical pre-releases, drop nightly bundles [DRAFT/gated] (#13529)

feat(ci): nightly Approach A — canonical pre-releases, drop nightly bundles

DRAFT reference implementation of the nightly→stable-bundle cutover documented
in src/bundles/NIGHTLY.md. Publishes the nightly under CANONICAL package names as
.devN pre-releases instead of separate *-nightly distributions, so the stable
lfx-* bundles resolve against a single canonical lfx (no dual-lfx install
collision) and no nightly bundle packages are produced.

- tag scripts (pypi/lfx/sdk_nightly_tag.py): count .devN against the canonical
  PyPI histories instead of the *-nightly projects
- update scripts: stop renaming to *-nightly; set .devN versions; re-pin
  inter-package deps to exact canonical dev versions; delete the bundle
  rename/repin (update_lfx_dep_in_bundles, rename_bundles_for_nightly)
- release_nightly.yml: publish canonical pre-releases; remove bundle build,
  dist-nightly-bundles artifact, publish-nightly-bundles job + its gate; verify
  canonical names; main wheel glob dist/langflow-*.whl
- nightly_build.yml: drop the bundle git-add in the tag commit
- NIGHTLY.md: Approach A marked implemented + activation gate + A1/A2 follow-ups

Held as DRAFT: do not activate until stable lfx 1.10.0 is published AND the
nightly base is the next minor (release-1.11.0). A 1.10.0.devN core sorts below
1.10.0 and would fail the bundles' >=1.10.0 floor. Stacked on #13528.

(.secrets.baseline: incidental line-number shifts for the two workflows + prune
of pre-existing stale Pokédex Agent.json entries.)

* docs(ci): drop internal 'Approach A' label from nightly cutover comments

Comment- and docstring-only change across scripts/ci/* and the two nightly
workflows; no logic change. The two workflow edits stay single-line so
.secrets.baseline line numbers are unaffected. src/bundles/NIGHTLY.md keeps
its A/B decision-record framing intentionally.

* feat(ci): make nightly consumers work with canonical pre-releases

Follow-ups from the nightly cutover that are part of its blast radius (the
nightly now publishes canonical `.devN` pre-releases, not `*-nightly`
distributions):

- version.py: derive the "Nightly" label from the `.dev` version marker, since
  the canonical `langflow`/`langflow-base` distribution matches first in the
  lookup. Keeps the startup banner and telemetry `package` field identifying
  nightlies. Adds a canonical-dev test; updates the base-dev assertion.
- ci.yml check-nightly-status: query the canonical `langflow` project and pick
  the latest `.devN` release date instead of `langflow-nightly`'s `.info.version`.
- db-migration-validation.yml: install the nightly as `langflow[postgresql]==<dev>`
  (pre-release) instead of `langflow-nightly[...]`; verify via version("langflow").
- src/lfx/README.md: nightly install is `uv pip install --pre lfx`.
- NIGHTLY.md: rewrite the follow-ups section (these are addressed; Docker image,
  A2 meta-package, and website docs remain deferred by design).

The `langflowai/langflow-nightly` Docker image name is intentionally unchanged.

* fix(ci): correct nightly verify uv tree parsing + stale base-dep regex

Addresses review of #13528:

- release_nightly.yml LFX verify: `uv tree | grep lfx | head -n1` matches the
  bundle `lfx-ibm` first → 'Name lfx-ibm does not match lfx'. Root the tree with
  `uv tree --package lfx` so the first line is the lfx package itself.
- release_nightly.yml base verify: under canonical naming `langflow-base` prints
  as a top-level `langflow-base v<ver>` line, so the old $2/$3 field parse read
  name="v0.10.0" and version="". Use `uv tree --package langflow-base` and $1/$2.
- update_lf_base_dependency.py update_base_dep: regex only accepted ~=/==, so its
  CLI entry point couldn't match the current root dep `langflow-base[complete]>=0.10.0`.
  Add >= (parity with update_uv_dependency.py). The active nightly path uses
  update_uv_dependency.py and was unaffected.

* docs(nightly): point NIGHTLY.md status at the activation gate, not draft state

Per review of #13528: this file ships inside #13528 (#13529 was folded in), so
the 'stacked on prep #13528' + 'held as a draft' framing is stale and misleading.
Reword the status block to state the real guard is the activation gate (stable
lfx 1.10.0 published AND next-minor base), not merge/draft state. Also reword the
follow-ups heading 'decide before un-drafting' -> 'decide before activating'.
2026-06-09 13:23:55 -07:00
0195a132e2 Merge release-1.10.0 into main
Non-squash union back-merge, ahead of cutting release-1.11.0 / release-1.10.1.
- Preserves main's settings-mixin refactor (#13141): release-1.10.0's 40 new
  settings ported into the per-group mixins, verified field-for-field and
  behaviorally against release's monolith.
- Keeps main's model-handling (#13191, auto-merged).
- CI workflows, docling deps, component index, starter projects, AGENTS.md,
  .secrets.baseline resolved to release-1.10.0. main: 1.9.6 -> 1.10.0.
2026-06-09 13:16:48 -07:00
8ee3493bb7 fix(observability): make grafana-loki reference stack instructions work end to end (#13454)
The reference stack README pointed LANGFLOW_LOG_FILE and LANGFLOW_LOG_DIR at
different directories, so following it produced an empty Grafana dashboard:
Langflow wrote to one path while Promtail scraped another. It also documented a
stdout-scrape alternative the shipped Promtail config does not implement.

Make the two paths consistent, require an absolute log path, correct the stdout
note, and add a no-Langflow smoke test that writes a sample record and confirms
it reaches Loki.
2026-06-09 17:14:46 +00:00
9690e69e86 fix(security): remove the disabled Python Code Structured tool component (#13560)
* fix(security): remove the disabled Python Code Structured tool component

Follow-up to #13538, which neutered PythonCodeStructuredTool to a
non-executable stub "for one release cycle, full removal later." This
completes that removal.

- Delete the component and its registration in lfx.components.tools.
- Drop its entry from the component index (num_components 355 -> 354,
  sha256 recomputed surgically) and from stable_hash_history.json.
- Remove its 18 i18n keys from every locale file.
- Replace the dedicated stub unit test with a removal test in
  test_dynamic_import_integration.py.
- Add a regressions entry to regressions/1.10.x.yaml.

The unauthenticated public-build RCE fix (report H1-3754930) is
unaffected: PythonCodeStructuredTool stays in
CODE_EXECUTION_COMPONENT_TYPES, so build_public_tmp still rejects any
saved or crafted flow that carries the type. instantiate_class execs the
node's stored `code` field regardless of whether the class still exists,
so the type-name block -- not the class -- is what closes the path.

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

* docs: document removal

* docs: typo

* Apply suggestion from @mendonk

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
2026-06-09 10:16:36 -07:00
d7804149d8 docs: LF assistant ampersand and dot selectors (#13544)
* docs-lf-assistant-dot-selector

* docs-add-lfx-matrix-to-1.10-version
2026-06-09 13:04:49 +00:00
2524604a19 fix(ci): make Biome lint non-blocking for release workflow calls (correct implementation using allow-failure input)
- Revert invalid continue-on-error syntax on reusable workflow uses: job
- Add allow-failure input to ci.yml lint-frontend call
- Define allow-failure input parameter in lint-js.yml workflow_call
- Implement conditional exit-code swallow in lint-js.yml when allow-failure=true
- When release=true, Biome errors are non-blocking for release pipeline
- When release=false/unset, Biome failures block PR merge (existing ci_success gate)
2026-06-08 17:22:21 -04:00
801edf3bab Revert "fix(ci): make Biome lint non-blocking for release workflow calls (#13547)"
This reverts commit a1adb1aa6f.
2026-06-08 17:21:24 -04:00