Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c62df86
Support tool mode in dynamic outputs
erichare Nov 6, 2025
10f5932
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 6, 2025
b764428
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 6, 2025
f35eac4
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 6, 2025
e77cf5c
Tool mode and ruff fixes
erichare Nov 6, 2025
86f8fcb
Template updates
erichare Nov 6, 2025
cc300f9
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 6, 2025
b508b17
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 6, 2025
b18ecd5
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 6, 2025
ec7f30c
Merge branch 'main' into fix-file-component-toolmode
erichare Nov 12, 2025
22dc1fa
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 12, 2025
2d1310a
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 12, 2025
8766a6e
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 12, 2025
25f24d0
Update test_mcp_servers_file.py
erichare Nov 18, 2025
78c0a8f
Merge branch 'main' into fix-file-component-toolmode
erichare Nov 18, 2025
17d6e6f
Revert "Update test_mcp_servers_file.py"
erichare Nov 18, 2025
e84ccc9
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 18, 2025
c224f64
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 18, 2025
7eb7557
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 18, 2025
7d45999
add possibility for the agent to access the processed output file
Cristhianzl Nov 24, 2025
46f462a
merge fix
Cristhianzl Nov 24, 2025
59459d0
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 24, 2025
5d7e885
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 24, 2025
3c13d86
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 24, 2025
1730e21
Merge branch 'main' into fix-file-component-toolmode
carlosrcoelho Nov 24, 2025
363f088
Merge branch 'main' into fix-file-component-toolmode
erichare Nov 24, 2025
9f8c9b5
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 24, 2025
01e2578
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 24, 2025
f3e74a9
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 24, 2025
0ac1338
Merge branch 'main' into fix-file-component-toolmode
erichare Nov 24, 2025
6bdcf1c
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 24, 2025
32b9506
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 24, 2025
6a87a83
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Tool mode and ruff fixes
  • Loading branch information
erichare committed Nov 6, 2025
commit e77cf5cef28eaf426cbde630c0bfc384633cbc93
40 changes: 40 additions & 0 deletions src/backend/tests/unit/components/data/test_file_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,43 @@ def test_dynamic_outputs_have_tool_mode_enabled(self):
result = component.update_outputs(frontend_node, "advanced_mode", field_value=False)
for output in result["outputs"]:
assert output.tool_mode is True, f"Output {output.name} should have tool_mode=True"

def test_file_path_str_input_exists_for_tool_mode(self):
"""Test that file_path_str input exists for tool mode."""
component = FileComponent()

# Find the file_path_str input
file_path_str_input = None
for input_field in component.inputs:
if input_field.name == "file_path_str":
file_path_str_input = input_field
break

assert file_path_str_input is not None, "file_path_str input should exist"
assert file_path_str_input.tool_mode is True, "file_path_str should have tool_mode=True"

# Check that the path FileInput has tool_mode=False
path_input = None
for input_field in component.inputs:
if input_field.name == "path":
path_input = input_field
break

assert path_input is not None, "path input should exist"
assert path_input.tool_mode is False, "path FileInput should have tool_mode=False"

def test_read_file_using_file_path_str(self, tmp_path):
"""Test reading a file using file_path_str parameter (tool mode)."""
# Create a test file
test_file = tmp_path / "test.txt"
test_content = "Hello from tool mode!"
test_file.write_text(test_content)

# Create component and set file_path_str
component = FileComponent()
component.file_path_str = str(test_file)

# Load the file
result = component.load_files_message()

assert result.text == test_content, f"Expected '{test_content}', got '{result.text}'"
44 changes: 44 additions & 0 deletions src/lfx/src/lfx/components/data/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,19 @@ class FileComponent(BaseFileComponent):
for input_item in _base_inputs:
if isinstance(input_item, FileInput) and input_item.name == "path":
input_item.real_time_refresh = True
input_item.tool_mode = False # Disable tool mode for file upload input
break

inputs = [
*_base_inputs,
StrInput(
name="file_path_str",
display_name="File Path",
info="Path to the file to read. Used when component is called as a tool.",
show=False,
advanced=True,
tool_mode=True,
),
BoolInput(
name="advanced_mode",
display_name="Advanced Parser",
Expand Down Expand Up @@ -260,6 +269,41 @@ def update_outputs(self, frontend_node: dict[str, Any], field_name: str, field_v

# ------------------------------ Core processing ----------------------------------

def _validate_and_resolve_paths(self) -> list[BaseFileComponent.BaseFile]:
"""Override to handle file_path_str input from tool mode.

When called as a tool, the file_path_str parameter will be set,
and we should use that instead of the path FileInput.
"""
# Check if file_path_str is provided (from tool mode)
# file_path_str will be set when component is called as a tool
file_path_str = getattr(self, "file_path_str", None)
if file_path_str:
# Use the string path from tool mode
from pathlib import Path

from lfx.schema.data import Data

resolved_path = Path(self.resolve_path(file_path_str))
if not resolved_path.exists():
msg = f"File or directory not found: {file_path_str}"
self.log(msg)
if not self.silent_errors:
raise ValueError(msg)
return []

data_obj = Data(data={self.SERVER_FILE_PATH_FIELDNAME: str(resolved_path)})
return [
BaseFileComponent.BaseFile(
data_obj,
resolved_path,
delete_after_processing=False
)
]

# Otherwise use the default implementation
return super()._validate_and_resolve_paths()

def _is_docling_compatible(self, file_path: str) -> bool:
"""Lightweight extension gate for Docling-compatible types."""
docling_exts = (
Expand Down