The build_component_index.py script was generating component_index.json
without a trailing newline, causing CI failures when autofix.ci tried to
add the missing newline. This fix ensures the generated JSON file always
ends with a newline character, following POSIX text file standards.
Fixes the 'No newline at end of file' error in the update-component-index
workflow job.
* feat: add telemetry service to lfx MCP server
Replace the no-op telemetry stub with a real async implementation
that sends lightweight analytics to Scarf via GET query params.
- New schema.py with MCPToolPayload and standard payload types
- TelemetryService with async queue, httpx client, DO_NOT_TRACK support
- @_tracked decorator on all 31 MCP tools for automatic tracking
- Failure-safe: suppress(BaseException) ensures telemetry never breaks tools
- Worker guards against task_done without get, flush has 5s timeout
* fix: address telemetry review feedback
- Replace str(exc)[:200] with type(exc).__name__ to avoid leaking
sensitive user data in GET query params sent to Scarf
- Manage telemetry lifecycle via FastMCP lifespan hook instead of
lazy module-level singleton that never called stop()
- Change duration tracking from int(seconds) to milliseconds to
preserve sub-second granularity
- Update tests to exercise start/stop lifecycle, DO_NOT_TRACK gating,
enqueue behavior, and teardown after start
---------
Co-authored-by: Eric Hare <ericrhare@gmail.com>
* docs: add PyTorch macOS AMD64 + Python 3.13 investigation (LE-172)
Investigate why the experimental CI job fails on macOS x86_64 + Python 3.13.
Root cause: PyTorch dropped macOS Intel wheel builds after v2.2.2 (before
Python 3.13 existed). The altk and langchain-huggingface extras pull in
torch without platform guards, causing installation failures.
Includes analysis of dependency chains, lockfile resolution behavior,
and 4 actionable options (A-D) with tradeoffs for the team to decide on.
* fix: exclude torch-dependent extras on macOS x86_64 (LE-172)
Add platform exclusion markers to altk and langchain-huggingface extras
to prevent torch from being pulled in on macOS Intel where no wheel exists.
This matches the existing pattern used for easyocr and docling extras.
PyTorch dropped macOS x86_64 binary support after v2.2.2, so these
features cannot work on Intel Macs regardless.
* fix: preserve nested dictionaries in MCP tool parameters (#9881)
When MCP tool schemas define object-type fields without explicit properties,
the system now treats them as free-form dictionaries (dict[str, Any]) instead
of creating empty Pydantic models. This preserves nested data structures that
were previously being lost during validation.
Before this fix:
Input: {'msg': {'linear': {'x': 1}}}
Output: {'msg': {}} # nested data lost!
After this fix:
Input: {'msg': {'linear': {'x': 1}}}
Output: {'msg': {'linear': {'x': 1}}} # preserved!
Changes:
- Modified parse_type() in json_schema.py to detect objects without properties
and use dict[str, Any] instead of creating empty BaseModel subclasses
- Added regression test test_nested_dict_preservation_issue_9881()
- All existing tests pass (94 passed, 7 skipped)
Fixes#9881
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
The build-if-needed job (used for workflow_dispatch) was not building
the langflow-sdk package. Since lfx depends on langflow-sdk>=0.1.0
and langflow-sdk is not yet published to PyPI, all test jobs failed
during lfx installation with 'No solution found'.
Changes:
- Build langflow-sdk wheel in build-if-needed job
- Upload SDK artifact and output sdk-artifact-name
- Update SDK download conditions with build-if-needed fallback
- Update SDK+LFX combined/individual install conditions to properly
route through the combined installer when both are available
The build-if-needed job (used by workflow_dispatch) was missing the
lfx package build, causing all cross-platform tests to fail with:
'No solution found: lfx>=0.4.0 required but only <=0.3.4 available'
Changes:
- Build lfx wheel in build-if-needed job
- Upload lfx artifact (adhoc-dist-lfx)
- Add lfx-artifact-name to job outputs
- Update all test jobs to fallback to build-if-needed outputs
for lfx artifact (matching existing base/main pattern)
* feat: add mcp_base_url to config endpoint for MCP server URL override
Add LANGFLOW_MCP_BASE_URL setting that the frontend uses as a fallback
when building MCP server URLs in the UI configuration JSON. This allows
deployments behind reverse proxies to specify the correct external URL.
Priority chain: mcp_base_url > api.defaults.baseURL > window.location.origin
* test: add tests for mcp_base_url config and URL fallback priority
* fix: enforce ownership check and pass user_id in workflow job creation
- Add _assert_job_owner helper that raises 403 for non-owners (legacy jobs with user_id=None are allowed through)
- Move ownership check before job type check in stop_workflow to avoid leaking job.type to non-owners
- Pass user_id to create_job in both sync and background execution paths
- Add user_id parameter to JobService.create_job signature
* test: add ownership and legacy job coverage for workflow endpoints
- Add TestWorkflowIDORProtection class with tests for 403 on cross-user access
- Add test for stop_workflow with legacy user_id=None job (should not return 403)
* fix: pass user_id to create_job in knowledge_bases ingestion endpoint
Prevents IDOR vulnerability where ingestion jobs created without user_id
would bypass ownership checks, matching the fix applied to workflow jobs.
* refactor: move job ownership check to JobService layer
Moves _assert_job_owner from workflow.py into JobService.assert_job_owner
so any future job-consuming endpoint can reuse the check without duplicating
logic. Both get_workflow_status and stop_workflow now delegate to the service.
* test: fix mocks for assert_job_owner after service layer refactor
MagicMock blocks attributes starting with 'assert' by default.
Added explicit mock_service.assert_job_owner = MagicMock() to each
test that mocks get_job_service so the ownership check is a no-op
for tests not focused on IDOR behavior.
* refactor: enforce job ownership at SQL level, remove assert_job_owner
Move IDOR ownership check from application layer into the DB query.
`get_job_by_job_id` now accepts an optional `user_id` and filters by
`job_id AND (user_id = ? OR user_id IS NULL)`, so unauthorized access
returns 404 instead of 403. Removes `JobService.assert_job_owner`.
- Strengthen legacy-job test assertions (!=403 → ==200)
- Add missing GET test for non-WORKFLOW job type → 404
* add var to block custom component execution
* [autofix.ci] apply automated fixes
* swaps generic check for a specific legacy name check for prompt
* [autofix.ci] apply automated fixes
* Add missing endpoint checks
* fix language
* Add flow validation and tests
* [autofix.ci] apply automated fixes
* Add a few more tests and validation to other endpoints
* clean up test and import logic
* [autofix.ci] apply automated fixes
* ensure flow is saved after upgrade
* Use hash instead of code
* Fix review issues: type safety, error handling, and test coverage
- Change ComponentCache hash fields to None default (was {}) to make
"not yet loaded" explicit in the type system and eliminate the error-prone
`or None` pattern at 8+ callsites
- Narrow frontend 403 suppression to only match custom component errors,
preventing unrelated auth/permission 403s from being swallowed
- Add console.warn logging to waitForNodeUpdates timeout, saveFlow catch,
and 403 suppression paths for debuggability
- Document security invariants (build_vertex cache-hit, nodes-without-code)
- Add server-side logging to MCP validation failures
- Add TestBuildCodeHashLookups test class (9 tests) for _build_code_hash_lookups
* remove divider when new cust comp button is removed
* syntax fix in ui
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
* DRY
* [autofix.ci] apply automated fixes
* fix imports
* add field order to script updates
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* fix: harden custom component lockdown across api, lfx, and editor
- enforce custom-component validation before lfx and backend flow execution
- normalize legacy built-in aliases like Prompt and URL during validation and refresh
- surface blocked custom nodes in the editor without mutating persisted edited state
- prevent empty-flow save/build hangs when custom components are disabled
- add regression coverage for api, lfx, starter project refresh, and frontend guards
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* Add legacy type mapping back for prompt component
* Fix missing import and add real run tests
* fix(flow): Centralize custom component validation
Route payload and prebuilt graph checks through one shared validator so
backend and lfx execution surfaces enforce the same custom-component
policy.
Keep Graph.from_payload as the fresh-build guard, revalidate cached and
script-loaded graphs before execution, and extend coverage for MCP,
workflow reconstruction, agentic flows, and real lfx runs.
Co-Authored-By: OpenAI Codex <noreply@openai.com>
* remove useless function
* remove double validation cases
* remove outdated hash history refs
* fix(frontend): preserve custom component recovery paths
Clear dismissed state after successful bulk restores and make the toolbar Code entrypoint follow config transitions.
Add regressions for bulk restore cleanup, toolbar config changes, and single-node restore of dismissed outdated components.
* fix(frontend): Block uploaded custom components in editor
Surface uploaded CustomComponent nodes as blocked when custom
components are disabled so the editor warns before build
and refresh paths hit backend rejections.
Recompute component warnings when config loads and tighten
the disabled-mode guard so allowed custom components are
not treated as blocked.
* Add parser to legacy type analysis
* fix: update components on render consolidate config reads
Replace scattered useGetConfig reads with useUtilityStore
for a single source of truth.
- chat.py: use elif so request data validation skips stale DB flow;
reorder build_public_tmp to check public access before validation
- flow_validation.py: surface loader failures instead of swallowing them
- use-get-types.ts: recompute componentsToUpdate after templates load
- Frontend: read allowCustomComponents from utilityStore in code area,
sidebar, and node toolbar components
* Add tiny guard to not update on zero length nodes
* DRY ref for compute update function
* Remove redundant validations (for now)
* refactor: replace string-matching error classification with CustomComponentValidationError
Introduce CustomComponentValidationError(ValueError) so API handlers can
catch validation errors by type instead of matching error message strings.
This eliminates the fragile is_custom_component_validation_error_message
function and makes error routing explicit across all endpoints.
- Add CustomComponentValidationError in flow_validation.py
- check_flow_and_raise now raises CustomComponentValidationError
- Replace all is_custom_component_validation_error_message call sites
with except CustomComponentValidationError in chat.py, endpoints.py,
openai_responses.py, mcp_utils.py, and flow_executor.py
- Add except RuntimeError -> 503 in build_flow for startup race
- Remove redundant validation in session/service.py load_session
- Update all test assertions to use the new exception type
* Add beta flag to env var
* Use raw graph data to extract and better exc handling
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* [autofix.ci] apply automated fixes (attempt 3/3)
* obfuscate exceptoin details
* log error message
* ruff
* fix be test
* [autofix.ci] apply automated fixes
* fix tests
* [autofix.ci] apply automated fixes
* tests
* [autofix.ci] apply automated fixes
* enhance hash checks to allow cust components to run
* Add comment
* Add comment
* [autofix.ci] apply automated fixes
* ruff
* Update more tests
* [autofix.ci] apply automated fixes
* be tests
* be tests
* [autofix.ci] apply automated fixes
* revert changes to fe tests that were causing failures'
* comp index?
* comp index?
* comp index?
* changes FE tests to expect 5 necessary updates after prompt comp was added to checks
* update one more fe test with new error message
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: OpenAI Codex <noreply@openai.com>
docs: enhance Agentics documentation with embedded video and full paper citations
- Add embedded YouTube tutorial video at the top of the page
- Add introductory text for the video
- Group research papers under Publications section
- Add full academic citations for both Agentics papers
- Remove redundant schema table from introduction
- Improve overall readability and structure
Co-authored-by: Alfio Gliozzo <gliozzo@us.ibm.com>
Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
* fix: add SSRF protection to URL component (PVR0699081)
Add Server-Side Request Forgery (SSRF) protection to the URL component
by integrating the existing validate_url_for_ssrf function. This prevents
the component from being used to access internal resources like localhost,
private IP ranges, and cloud metadata endpoints.
The fix uses warn_only=True for backwards compatibility, matching the
behavior of the API Request component. Full blocking will be enabled
in the next major version (2.0).
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* fix: enforce SSRF blocking and add env variables to .env.example
- Change warn_only=False to actually block internal URLs when SSRF protection is enabled
- Add LANGFLOW_SSRF_PROTECTION_ENABLED and LANGFLOW_SSRF_ALLOWED_HOSTS to .env.example
- Update tests to reflect blocking mode
When LANGFLOW_SSRF_PROTECTION_ENABLED=true, requests to private IPs,
localhost, and cloud metadata endpoints will be blocked.
* fix: correct .env.example to show empty default for SSRF protection
The default is false, so .env.example should be empty (not true).
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* fix: add SSRF protection to URL component (PVR0699081)
Add Server-Side Request Forgery (SSRF) protection to the URL component
by integrating the existing validate_url_for_ssrf function. This prevents
the component from being used to access internal resources like localhost,
private IP ranges, and cloud metadata endpoints.
The fix uses warn_only=True for backwards compatibility, matching the
behavior of the API Request component. Full blocking will be enabled
in the next major version (2.0).
* fix: enforce SSRF blocking and add env variables to .env.example
- Change warn_only=False to actually block internal URLs when SSRF protection is enabled
- Add LANGFLOW_SSRF_PROTECTION_ENABLED and LANGFLOW_SSRF_ALLOWED_HOSTS to .env.example
- Update tests to reflect blocking mode
When LANGFLOW_SSRF_PROTECTION_ENABLED=true, requests to private IPs,
localhost, and cloud metadata endpoints will be blocked.
* fix: correct .env.example to show empty default for SSRF protection
The default is false, so .env.example should be empty (not true).
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* feat: add Langflow MCP Client settings page
Add a new settings page that shows coding agents how to connect to
Langflow via the lfx.mcp client. Includes setup instructions and
JSON config for Bob (IBM) and Claude Code.
* fix: clipboard guard and per-button copied state in MCP client page
- Guard navigator.clipboard availability before calling writeText
- Track copied state per button (command vs json) so visual feedback
matches the action the user took
* feat: add flow events queue for MCP agent activity polling
In-memory event queue service with cursor-based polling endpoint
at GET/POST /api/v1/flows/{flow_id}/events. Enables the frontend
to detect when MCP agents modify flows in near real-time.
* feat: emit flow events from MCP tools and add notify_done tool
Each mutating MCP tool now posts an event to the flow events queue
after successful PATCH. Adds notify_done tool for explicit settle
signaling to the frontend.
* feat: add frontend flow event polling with canvas locking and toast
- useFlowEvents hook with adaptive polling (5s idle, 1s active)
- Canvas locks with "Agent is working..." badge during agent activity
- Flow reloads and summary toast on settle
* test: add tests for flow events hook and MCP event emission
- 9 frontend tests for useFlowEvents hook (polling, accumulation, settle, errors)
- 4 lfx tests for LangflowClient.post_event (payload, defaults, error suppression)
- 7 lfx tests for MCP tool event emission (add/remove/configure/connect/disconnect/notify_done)
* fix: add flow ownership check and fix thread-safety in event queue
Endpoints now verify the authenticated user owns the flow before
allowing event reads or writes. Also copies the event list inside
the lock to prevent concurrent mutation during iteration.
* fix: log warnings on event posting and polling failures
Replace silent error suppression with logger.warning (backend) and
console.warn (frontend) so failures are diagnosable while keeping
best-effort semantics.
* fix: show toast only on successful flow reload after agent settle
Move toast into reloadFlow's onSuccess callback so users aren't told
about changes that failed to load. Also fixes stale closure by adding
missing useEffect dependencies.
* test: improve coverage for flow events
- Add cursor-ahead-of-events tests for get_since settle logic
- Add flow ownership 404 test for events endpoints
- Add event emission tests for freeze/unfreeze/layout/update_flow_from_spec
- Use real flow IDs (from created flows) in API tests
* test: add edge case coverage for flow events
- flow_settled before cursor should not trigger settlement
- create_flow_from_spec emits flow_settled after batch
- Polling resumes at idle interval after settle
- Simultaneous events + settled in single poll
* fix: UX improvements for agent activity polling
- Clear events after settle to prevent stale toast messages
- Truncate toast to 3 summaries max ("and N more")
- Block keyboard shortcuts (undo/redo/copy/paste/cut) during agent lock
- Poll immediately on mount (no 5s blind spot)
- Add concurrency guard to prevent overlapping polls
- Guard against setState on unmounted component
* test: add Playwright E2E test for agent events banner
Verifies that posting events via the API triggers the "Agent is
working..." banner on the canvas, and that a flow_settled event
dismisses it.
* refactor: consolidate lfx event tests into parameterized tests
- Server tests: 10 identical copy-paste classes -> 1 parameterized test
covering 9 tools, assertions check event type not exact summary
- Client tests: merge redundant exception tests, test multiple error
types in one test
- Keep distinct tests for create_flow_from_spec and notify_done since
they have unique behavior (batch settle vs explicit settle)
* fix: UX improvements for agent events banner
- Show latest event summary in banner (e.g. "Agent: Added Memory")
- Slide-in entrance and slide-out exit animations
- Minimum 2s display time so banner doesn't flash
- Freeze banner text during exit animation
- Text eases in when new events arrive
* fix: canvas reload, locking, and toast formatting
- Use applyFlowToCanvas for proper canvas reload on settle
- Zoom to fit after reload instead of zooming to 200%
- Lock icon shows "Agent Working" during agent activity
- ReactFlow nodesDraggable/nodesConnectable respect agent lock
- Toast shows grouped summary (e.g. "Agent removed 3 components")
- Events preserved for consumer, cleared via clearEvents callback
* fix: handle AUTO_LOGIN nullable user_id, remove double processFlows, fix pluralization
- _verify_flow_owner now accepts flows with user_id=None (AUTO_LOGIN)
- Remove redundant processFlows call (applyFlowToCanvas handles it)
- Toast says "connections" not "components" for connection events
* refactor: minor cleanup from code review
- Remove unused FlowEventType export (only used internally)
- Simplify nested ternary in toast pluralization
* chore: remove test artifact
* fix: harden flow events service and address review findings
- Rewrite FlowEventsService to use diskcache for cross-worker
event visibility (replaces in-memory dict)
- Add Literal constraint and max_length to FlowEventCreate API model
- Restore manual lock toggle (disabled during agent activity),
serialize saves to prevent race conditions
- Add AbortController to post-settle flow reload to prevent
stale responses from overwriting wrong canvas
- Clear agent-working state on terminal poll errors (401/403/404)
so UI doesn't get permanently stuck
- Make notify_done report warning status on delivery failure
- Emit settle event on create_flow_from_spec rollback
- Fix E2E test banner text assertion to match actual render
- Add 14 new tests: cross-worker visibility, validation 422s,
terminal error unlock, notify_done warning, rollback settle
* fix: resolve CI failures in MemoizedCanvasControls and notify_done tests
- Add waitFor() to lock toggle tests for async handleToggleLock
- Patch logger in notify_done failure test to avoid I/O on closed file
- Replace any[] with unknown[] in test mock type
* fix: address remaining review feedback from erichare
- Fix stale closure in banner effect using bannerVisibleRef
- Add runtime event type validation in FlowEventsService.append()
- Document diskcache ephemeral storage and multi-tab limitations
* feat: add Langflow MCP Client settings page
Add a new settings page that shows coding agents how to connect to
Langflow via the lfx.mcp client. Includes setup instructions and
JSON config for Bob (IBM) and Claude Code.
* fix: clipboard guard and per-button copied state in MCP client page
- Guard navigator.clipboard availability before calling writeText
- Track copied state per button (command vs json) so visual feedback
matches the action the user took
- Analyze 45-60 min CI bottleneck for pre-release builds
- Document that both PyPI publishing and Docker builds wait for CI
- Recommend skip_ci parameter with safeguards for urgent releases
- Show 50% time savings (100 min → 50 min) for pre-releases
- Include risk assessment and implementation guidelines
Addresses LE-517
* feat: add pure flow-builder utilities to lfx
Add flow_builder subpackage with pure functions for manipulating
flow JSON dicts — component ops, edge creation with ReactFlow
handle format, topological layout, and dynamic field detection.
* feat: add MCP server for operating Langflow via REST API
FastMCP server exposing 15 tools across auth, flow, component,
connection, and execution groups. Agents can create flows, add
and configure components, wire connections, and run flows against
a Langflow server through MCP tool calls.
* feat: add langflow-mcp-client console script entry point
* fix: use dict comprehension in setup.py to fix PERF403 lint
* fix: address PR review feedback on MCP client
- Add asyncio.Lock to prevent race condition in _client() under
concurrent access
- Handle 204 No Content responses in delete() instead of calling
resp.json() on empty body
- Fix weak assertion in test_default_values
* feat: auto-enable tool_mode when connecting component_as_tool
describe_component_type now shows component_as_tool as an output
for any component with tool_mode-capable outputs. When an agent
connects via component_as_tool, tool_mode is auto-enabled — no
extra step needed.
* refactor: move MCP server from langflow-base to lfx
The MCP server has no langflow dependencies — only httpx, mcp,
and lfx.graph.flow_builder. Moving it to lfx.mcp makes it usable
without installing langflow. Entry point: lfx-mcp.
* feat: improve MCP server UX for agents
- describe_component_type separates advanced fields from core ones
- search_component_types accepts output_type filter
- list_flows accepts query filter and includes ASCII graph repr
- get_flow_info includes ASCII graph repr
- add duplicate_flow tool
- add list_starter_projects tool
* feat: add use_starter_project tool and tests for new features
- use_starter_project creates a flow from a starter template by name
(starter projects aren't fetchable by ID via /flows/)
- Tests for duplicate_flow, starter projects, graph repr, advanced
fields, and output_type search
* docs: improve MCP tool descriptions for agent clarity
- Add server-level instructions with typical workflow guide
- Remove internal implementation details from tool descriptions
- Add cross-references between related tools
- Mention component_as_tool and graph diagrams where relevant
* docs: address subagent review feedback on tool descriptions
- Document return values for create_flow, add_component
- Clarify empty-query behavior for search_component_types
- Distinguish get_component_info (instance) vs describe_component_type (type)
- Explain connection type compatibility in instructions
- Clarify configure_component trigger field behavior
- State disconnect_components default when filters omitted
* feat: add batch tool for multi-action requests
Execute multiple actions in one call with $N.field references
to chain results. An agent can build a complete flow in a single
request instead of 6+ round trips.
* feat: add create_flow_from_spec tool for compact text-based flow creation
Accepts a compact text spec with nodes, edges (using real port names),
and config sections. Agents generate a simple string instead of
constructing nested JSON. Tool mode auto-enabled for component_as_tool.
Handles Prompt Template dynamic variables by parsing {var} from
template text and creating input fields. Cleans up flows on failure.
Type coercion for numeric/boolean config values.
* feat: add build_flow validation and create_flow_from_spec
build_flow validates flows by building the graph server-side.
create_flow_from_spec accepts a compact text spec with nodes,
edges, and config. Validates by default (optional).
Handles Prompt Template dynamic {variables}, auto-enables tool_mode
for component_as_tool, cleans up on failure, coerces config types.
* fix: isolate session state and harden MCP server
* fix: move test_flow_builder into tests/unit so CI collects coverage
* fix: address PR review feedback
- Fix test fixture to use contextvars instead of stale module attributes
- Raise ValueError on malformed spec lines instead of silently dropping
- Disambiguate duplicate component types in flow_graph_repr
- Narrow except Exception to ImportError in flow_graph_repr
- Add action-index context to batch error messages
- Fix stale/inaccurate docstrings (group count, "| ", field_name, category, build_flow)
- Mention create_flow_from_spec in MCP instructions
* feat: stream run_flow events via MCP progress notifications
run_flow now consumes Langflow's SSE stream and relays token events
to the MCP client via report_progress. Falls back to a regular POST
if the stream yields no result.
* test: add streaming integration tests for run_flow and stream_post
* chore: rebuild component index
* [autofix.ci] apply automated fixes
* fix: handle Message dicts in str field param processing, add MCP logger
param_handler's str case called unescape_string on list elements without
type checking. On subsequent agent calls, chat history stores Message dicts
in the list, causing 'dict' object has no attribute 'replace'.
Added _coerce_str_value that extracts .text from Message/Data/dict objects.
Added lfx logger to MCP server with streaming fallback warning.
* feat: add flow builder tools, propose_field_edit, and flow_to_spec_summary
- builder.py: builds flow dicts from text specs using local component
registry with granular error handling per build phase
- flow_builder_tools.py: 9 Langflow components for agent tooling
(search, describe, get_field_value, propose_field_edit, add_component,
remove_component, connect_components, configure_component, build_flow)
- propose_field_edit generates validated JSON Patches with dry-run
- flow_to_spec_summary converts flow dicts to compact summaries with IDs
- Module-level event queue for real-time UI updates during streaming
* [autofix.ci] apply automated fixes
* feat: add get_build_results and get_component_output MCP tools
Exposes per-component build data from the vertex_builds table:
- get_build_results: returns all component outputs, validity, and errors
from the last run -- useful for debugging which component failed
- get_component_output: inspect a specific component's output from the
last run to trace where the pipeline broke
* feat: add flow management, iteration, and discovery MCP tools
Response improvements:
- spec_summary (component IDs + connection ports) in get_flow_info/list_flows
- Merged components() tool: search or describe in one call
Flow management tools:
- validate_flow: polls build results with timeout, structured per-component errors
- rename_flow: update name/description
- export_flow: serialize to JSON with sensitive field redaction
- update_flow_from_spec: declarative update with reference validation
Component iteration tools:
- freeze_component / unfreeze_component: skip re-execution during iteration
- layout_flow_tool: re-layout after modifications
Security: export_flow redacts API keys via redact_node before exposing to LLM.
Includes 18 integration tests covering all new tools.
* refactor: extract shared _node_id and validate_spec_references
- _utils.py: shared node_id helper (was duplicated in component.py and layout.py)
- spec.py: validate_spec_references extracted from three copies in
create_flow_from_spec, update_flow_from_spec, and build_flow_from_spec
* fix: add trailing slash to /api_key endpoint in MCP client login
The FastAPI endpoint redirects /api_key to /api_key/ (307) and httpx
drops the POST body on redirect, causing API key creation to fail
silently during login.
* fix: isolate session state and harden MCP server
contextvars alone lose state between stdio tool calls. Add module-level
fallback so login credentials persist across calls while still
supporting per-session isolation for SSE transport.
* feat: improve MCP server UX for agents
- describe_component_type separates advanced fields from core ones
- search_component_types accepts output_type filter
- list_flows accepts query filter and includes ASCII graph repr
- get_flow_info includes ASCII graph repr
- add duplicate_flow tool
- add list_starter_projects tool
* feat: add use_starter_project tool and tests for new features
- use_starter_project creates a flow from a starter template by name
(starter projects aren't fetchable by ID via /flows/)
- Tests for duplicate_flow, starter projects, graph repr, advanced
fields, and output_type search
* docs: improve MCP tool descriptions for agent clarity
- Add server-level instructions with typical workflow guide
- Remove internal implementation details from tool descriptions
- Add cross-references between related tools
- Mention component_as_tool and graph diagrams where relevant
* docs: address subagent review feedback on tool descriptions
- Document return values for create_flow, add_component
- Clarify empty-query behavior for search_component_types
- Distinguish get_component_info (instance) vs describe_component_type (type)
- Explain connection type compatibility in instructions
- Clarify configure_component trigger field behavior
- State disconnect_components default when filters omitted
* feat: add batch tool for multi-action requests
Execute multiple actions in one call with $N.field references
to chain results. An agent can build a complete flow in a single
request instead of 6+ round trips.
* feat: add create_flow_from_spec tool for compact text-based flow creation
Accepts a compact text spec with nodes, edges (using real port names),
and config sections. Agents generate a simple string instead of
constructing nested JSON. Tool mode auto-enabled for component_as_tool.
Handles Prompt Template dynamic variables by parsing {var} from
template text and creating input fields. Cleans up flows on failure.
Type coercion for numeric/boolean config values.
* feat: add build_flow validation and create_flow_from_spec
build_flow validates flows by building the graph server-side.
create_flow_from_spec accepts a compact text spec with nodes,
edges, and config. Validates by default (optional).
Handles Prompt Template dynamic {variables}, auto-enables tool_mode
for component_as_tool, cleans up on failure, coerces config types.
* fix: address PR review feedback
- Fix test fixture to use contextvars instead of stale module attributes
- Raise ValueError on malformed spec lines instead of silently dropping
- Disambiguate duplicate component types in flow_graph_repr
- Narrow except Exception to ImportError in flow_graph_repr
- Add action-index context to batch error messages
- Fix stale/inaccurate docstrings (group count, "| ", field_name, category, build_flow)
- Mention create_flow_from_spec in MCP instructions
* feat: stream run_flow events via MCP progress notifications
run_flow now consumes Langflow's SSE stream and relays token events
to the MCP client via report_progress. Falls back to a regular POST
if the stream yields no result.
* test: add streaming integration tests for run_flow and stream_post
* chore: rebuild component index
* [autofix.ci] apply automated fixes
* fix: handle Message dicts in str field param processing, add MCP logger
param_handler's str case called unescape_string on list elements without
type checking. On subsequent agent calls, chat history stores Message dicts
in the list, causing 'dict' object has no attribute 'replace'.
Added _coerce_str_value that extracts .text from Message/Data/dict objects.
Added lfx logger to MCP server with streaming fallback warning.
* feat: add flow builder tools, propose_field_edit, and flow_to_spec_summary
- builder.py: builds flow dicts from text specs using local component
registry with granular error handling per build phase
- flow_builder_tools.py: 9 Langflow components for agent tooling
(search, describe, get_field_value, propose_field_edit, add_component,
remove_component, connect_components, configure_component, build_flow)
- propose_field_edit generates validated JSON Patches with dry-run
- flow_to_spec_summary converts flow dicts to compact summaries with IDs
- Module-level event queue for real-time UI updates during streaming
* [autofix.ci] apply automated fixes
* feat: add get_build_results and get_component_output MCP tools
Exposes per-component build data from the vertex_builds table:
- get_build_results: returns all component outputs, validity, and errors
from the last run -- useful for debugging which component failed
- get_component_output: inspect a specific component's output from the
last run to trace where the pipeline broke
* feat: add flow management, iteration, and discovery MCP tools
Response improvements:
- spec_summary (component IDs + connection ports) in get_flow_info/list_flows
- Merged components() tool: search or describe in one call
Flow management tools:
- validate_flow: polls build results with timeout, structured per-component errors
- rename_flow: update name/description
- export_flow: serialize to JSON with sensitive field redaction
- update_flow_from_spec: declarative update with reference validation
Component iteration tools:
- freeze_component / unfreeze_component: skip re-execution during iteration
- layout_flow_tool: re-layout after modifications
Security: export_flow redacts API keys via redact_node before exposing to LLM.
Includes 18 integration tests covering all new tools.
* refactor: extract shared _node_id and validate_spec_references
- _utils.py: shared node_id helper (was duplicated in component.py and layout.py)
- spec.py: validate_spec_references extracted from three copies in
create_flow_from_spec, update_flow_from_spec, and build_flow_from_spec
* fix: update test fixture to use contextvars-based server API
The mcp_client fixture was accessing mcp_server_module._client and
._registry directly, but these were replaced with contextvars
(_client_var, _shared_client, _set_client, etc.) in the server
module refactor.
* [autofix.ci] apply automated fixes
* fix: address review feedback on MCP server PR
- Move flow_builder_tools out of components/ into mcp/ (fixes test_get_all)
- Extract _set_frozen() helper to deduplicate freeze/unfreeze
- Add missing tools to batch _TOOL_MAP
- Fix sensitive field detection to use word-boundary matching
- Unify redaction logic via shared is_sensitive_field()
- Log skipped non-JSON SSE lines in stream_post
- Rebuild component index
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
* fix: gracefully handle server refresh failure in configure_component
When a real_time_refresh field (e.g. model_name) is configured before
its dependency (e.g. api_key), the server-side refresh fails. Instead
of propagating a raw RuntimeError, the value is saved locally and a
warning is returned telling the agent to set the credential first.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Keval718 <kevalvirat@gmail.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
chore: remove mypy from CI and dev dependencies
mypy hasn't caught issues in a long time due to its lenient config
(follow_imports=skip, ignore_missing_imports=true). We evaluated ty as
a replacement but it lacks Pydantic and SQLModel support, producing too
many false positives. Removing the type checker until a viable
alternative matures.
* fix: redact sensitive information from log output
Mask or remove API keys, passwords, tokens, auth settings, and
configuration values from logger calls and print statements to prevent
clear-text exposure of credentials in logs.
* fix: address code review feedback on sensitive info redaction
- Restore full API key display in Windows fallback banner (masking
defeated the purpose of showing the key for the only time)
- Revert test helper masking in locust setup (developers need full
credentials for load testing)
- Add missing await on logger.adebug in agentic_mcp
- Remove redundant duplicate log line in openai_responses
* fix: replace unnecessary dict comprehension with dict() call
---------
Co-authored-by: Janardan Singh Kavia <janardankavia@ibm.com>
* feat: add token usage tracking for LLM and Agent components
Track input/output/total tokens across LLM providers (OpenAI, Anthropic,
Ollama) and display them on both node badges and chat messages.
Backend: thread-safe callback handler for agent token accumulation,
usage_metadata extraction for Ollama/LangChain standard, pipeline
integration from component through vertex to API response.
Frontend: token count formatting utility, Coins icon badge on nodes
with tooltip breakdown, chat message status with token display.
* feat: accumulate token usage across serial LLMs on chat messages
Add upstream token usage accumulation so chat messages display the
total tokens from all LLMs in the pipeline, not just the last one.
Output vertex node badges hide token counts since the accumulated
total is shown on the chat message instead.
* chore: add CLAUDE.local.md to .gitignore
* chore: update starter project templates for token usage tracking
* fix: enable token usage tracking for streaming LLM responses
Enable stream_usage=True on OpenAI and Anthropic model constructors so
the API includes token counts in streaming chunks.
Fix _handle_stream to propagate the AIMessage back to _get_chat_result
when not connected to a chat output, so usage can be extracted from the
invoke fallback path.
Accumulate usage across multiple streaming chunks instead of overwriting,
since Anthropic splits input/output tokens across separate events.
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* refactor: centralize token usage extraction into shared module
Extract duplicated token usage logic from Component, LCModelComponent,
TokenUsageCallbackHandler, and Vertex into a shared lfx.schema.token_usage
module. Replace loose dict typing with the existing Usage Pydantic model
throughout the token tracking pipeline. Declare _token_usage on Component
__init__ instead of dynamically injecting it.
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* [autofix.ci] apply automated fixes
* feat: add validation for token_usage field in ResultDataResponse
* feat: enable stream_usage in OpenAI model tests
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
* refactor: consolidate token usage extraction into single source of truth
Eliminate ~75 lines of duplicated LLMResult token extraction logic between
the token usage feature (TokenUsageCallbackHandler) and the traces feature
(NativeCallbackHandler) by adding a shared extract_usage_from_llm_result()
function. Also fix missing usage property mapping in chat history hook so
token counts display correctly in playground messages.
* feat: add token usage tracking to all LLM components
Add token usage extraction to the 7 remaining components that make LLM
calls but weren't tracking token consumption:
- Smart Router: direct extract_usage_from_message after invoke
- Guardrails: accumulate_usage across multiple guardrail checks
- Batch Run: accumulate_usage across batch responses
- Smart Transform: extract after ainvoke (already done in prior commit)
- Structured Output: via token_usage_callback on get_chat_result
- LLM Selector: direct extract for judge + callback for selected model
- NotDiamond: via token_usage_callback on get_chat_result
Also adds a backward-compatible token_usage_callback parameter to
get_chat_result() so components using that shared helper can capture
the AIMessage before it's reduced to .content.
* [autofix.ci] apply automated fixes
* fix: update mock_get_chat_result signatures to accept token_usage_callback
The structured output test mocks define explicit parameter lists for
get_chat_result but were missing the new token_usage_callback kwarg,
causing CI failure. Add **kwargs to all mock definitions.
* fix: address PR review findings for token usage UI and data flow
- Remove bare "bg" Tailwind class and replace hard-coded bg-neutral-700
with semantic bg-success-background on success tooltip (C2/C3)
- Propagate usage properties regardless of source.id presence so agent
inner messages still show token counts (H9)
- Make PropertiesType.source optional to match the new data flow
- Restore "in" preposition in "Finished in X.Xs" chat message (M10)
- Fix misleading "optional dependency" comment in native_callback.py (C1)
* fix: structured output token usage not captured due to config key mismatch
get_chat_result() reads "get_langchain_callbacks" as a callable, but
structured output was passing "callbacks" as a list — the token handler
was silently dropped. Fix by matching the expected key names and
injecting TokenUsageCallbackHandler via the LangChain callback chain
instead of the token_usage_callback parameter (which doesn't fire for
structured output chains that return Pydantic models, not AIMessages).
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes (attempt 2/3)
* chore: update component index
* test: add E2E tests for token usage tracking
* [autofix.ci] apply automated fixes
* test: add missing unit tests from PR review
Adds the 4 recommended test scenarios identified in Cristhianzl's review
of PR #11891 (token usage tracking):
- TestStreamingTokenAccumulation: verifies extract_usage_from_chunk() +
accumulate_usage() correctly accumulates across multiple streaming chunks
(OpenAI, Anthropic, and usage_metadata formats)
- TestChatOutputTokenUsageAccumulation: verifies message_response() sets
upstream token usage on the message and updates the stored message when
applicable
- TestAgentTokenCallbackWiring: verifies TokenUsageCallbackHandler is wired
into run_agent() callbacks and its result is stored on _token_usage
- TestResultDataResponseTokenUsageValidator: verifies the field_validator
converts Usage Pydantic models to dicts and passes through None/dict values
* [autofix.ci] apply automated fixes
* Revert "[autofix.ci] apply automated fixes"
This reverts commit c618b12498.
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
* fix: move hover action bar above message to prevent overlap with header row
Position the EditMessageButton toolbar using \`bottom-full\` instead of \`-top-4\` so it always sits fully above the message container. This prevents the button bar from overlapping the 'Finished in' usage/time row in bot messages.
* [autofix.ci] apply automated fixes
* feat: add token usage tooltip to bot message and fix node status background
- Wrap "Finished in" stat in a ShadTooltip showing last run time, duration, input/output token breakdown
- Fix node status success background color from bg-success-background to bg-zinc-700
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* feat: add list (llms) endpoint and wxo implemetation
* use provider_data/provider_result fields instead of top-level llms field
* feat(wxo): make LLM user-configurable and add attach_tool operation
Replace hardcoded DEFAULT_WXO_AGENT_LLM with a required user-supplied
`llm` field on both API and adapter create/update payloads, threaded
through mapper → service → plan → agent call. LLM-only updates (no
tool operations) are now supported.
Add `attach_tool` adapter operation to attach an existing provider tool
to a deployment without connection bindings. At the API layer, bind
operations now accept empty `app_ids` to create/attach a flow version
as an unbound raw tool; the mapper translates this by emitting the raw
tool payload while skipping the provider bind operation, preserving the
adapter-layer invariant that bind always requires non-empty app_ids.
Pre-seed raw_tool_app_ids from declared raw payloads so unbound tools
are created even without a referencing bind operation. Add overlap
validation for conflicting operations on the same tool_id (attach+bind,
remove+bind/unbind, bind/unbind app_id overlap, duplicate attach/remove).
* fix(wxo): improve LLM listing and update code review feedback
Add dedicated LIST_LLMS error prefix so LLM-listing failures are
distinguishable from deployment-list errors in user-facing messages.
Fix test URL path in _with_wxo_wrappers to match the real
WxOClient.get_models_raw endpoint (/models, not /v1/models).
Clarify API contract and intent via docstrings: document that
operations defaults to empty for LLM-only updates, that
build_update_payload_from_spec treats None as "not provided",
and that duplicate models are intentionally passed through.
* fix(wxo): make snapshot update contracts explicit and strict
Split update snapshot semantics into created/added/removed/referenced bindings, remove fallback masking, and enforce strict reconciliation for added flow-version bindings.
Also fix rollback update handling to avoid MissingGreenlet by passing scalar deployment identifiers after rollback, with updated tests across mapper, sync, route, and service coverage.
* harden resource_name_prefix presence validation for update path
* improve ux for missing field error messages
* fix: restore exclude_unset semantics, consolidate has_tool_work, fix format_first_error for model validators
- Restore model_dump(exclude_unset=True) in build_update_payload_from_spec
so explicitly-set None fields (e.g. description=null) are distinguishable
from omitted fields.
- Add has_tool_work property on WatsonxDeploymentUpdatePayload and use it
in the service layer instead of duplicating the routing logic inline.
- Fix format_first_error() to pass through model-validator value_error
messages instead of sanitizing them to generic "Invalid payload."
- Add missing llm field to pre-existing update schema tests.
* Add explicit is not none check to spec update name
* [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>