refactor(workflow-file): phase1 migrate workflow file deps with compatibility bridge

Implement phase 1 of the file module migration by moving workflow-facing file primitives to core.workflow.file while keeping core.file as a temporary compatibility layer.

What this commit changes
- Add core.workflow.file package (constants/enums/models/helpers/file_manager/tool_file_parser).
- Add protocol-based runtime binding in core.workflow.file.runtime and core.workflow.file.protocols.
- Add application adapter core.app.workflow.file_runtime and bind runtime in extensions.ext_storage.init_app.
- Bind runtime in tests via tests/conftest.py.
- Migrate workflow-only imports from core.file.* to core.workflow.file.* across workflow runtime/nodes/entry/encoder and workflow node factory.
- Update workflow unit tests to patch/import the new workflow file namespace.
- Remove workflow-external-imports ignore_imports entries related to core.file from .importlinter.

Compatibility guarantee for phase split
- Keep core.file import path available in this phase by replacing core/file/*.py with forwarding bridge modules that re-export core.workflow.file symbols.
- Preserve runtime behavior and isinstance(File) identity consistency while non-workflow modules are still on legacy import paths.

Notes
- This commit intentionally does not remove core.file. Full repository replacement and bridge removal are handled in phase 2.
This commit is contained in:
WH-2099
2026-02-11 14:58:39 +08:00
parent f233e2036f
commit c56d650e83
55 changed files with 783 additions and 571 deletions

View File

@ -71,9 +71,9 @@ class LoopNode(LLMUsageTrackingMixin, Node[LoopNodeData]):
if self.node_data.loop_variables:
value_processor: dict[Literal["constant", "variable"], Callable[[LoopVariableData], Segment | None]] = {
"constant": lambda var: self._get_segment_for_constant(var.var_type, var.value),
"variable": lambda var: self.graph_runtime_state.variable_pool.get(var.value)
if isinstance(var.value, list)
else None,
"variable": lambda var: (
self.graph_runtime_state.variable_pool.get(var.value) if isinstance(var.value, list) else None
),
}
for loop_variable in self.node_data.loop_variables:
if loop_variable.value_type not in value_processor: