fix: resolve import errors and test failures after segment 4 merge

- Update BaseNodeData import path to dify_graph.entities.base_node_data
- Change NodeType.COMMAND/FILE_UPLOAD to BuiltinNodeTypes constants
- Fix system_oauth_encryption -> system_encryption rename in commands
- Remove tests for deleted agent runner modules
- Fix Avatar: named import + string size API in collaboration files
- Add missing skill feature deps: @monaco-editor/react, react-arborist,
  @tanstack/react-virtual
- Fix frontend test mocks: add useUserProfile, useLeaderRestoreListener,
  next/navigation mock, and nodeOutputVars to expected payload

Made-with: Cursor
This commit is contained in:
Novice
2026-03-23 13:59:09 +08:00
parent 5041d96bb1
commit a28f22e59d
40 changed files with 449 additions and 1720 deletions

View File

@ -422,7 +422,10 @@ class TestAdvancedChatAppGeneratorInternals:
pause_state_config = SimpleNamespace(session_factory="session-factory", state_owner_user_id="owner")
response = generator._generate(
workflow=SimpleNamespace(features={"feature": True}),
workflow=SimpleNamespace(
features={"feature": True},
get_feature=lambda key: SimpleNamespace(enabled=False),
),
user=SimpleNamespace(id="user"),
invoke_from=InvokeFrom.WEB_APP,
application_generate_entity=application_generate_entity,
@ -517,7 +520,10 @@ class TestAdvancedChatAppGeneratorInternals:
)
response = generator._generate(
workflow=SimpleNamespace(features={}),
workflow=SimpleNamespace(
features={},
get_feature=lambda key: SimpleNamespace(enabled=False),
),
user=SimpleNamespace(id="user"),
invoke_from=InvokeFrom.WEB_APP,
application_generate_entity=application_generate_entity,

View File

@ -125,7 +125,20 @@ class TestAdvancedChatGenerateTaskPipeline:
)
)
event = SimpleNamespace(text="hi", from_variable_selector=None)
event = SimpleNamespace(
text="hi",
from_variable_selector=None,
tool_call=None,
tool_result=None,
chunk_type=None,
node_id=None,
model_provider=None,
model_name=None,
model_icon=None,
model_icon_dark=None,
model_usage=None,
model_duration=None,
)
responses = list(pipeline._handle_text_chunk_event(event))
@ -389,7 +402,20 @@ class TestAdvancedChatGenerateTaskPipeline:
pipeline._message_cycle_manager = SimpleNamespace(message_to_stream_response=lambda **kwargs: "chunk")
event = SimpleNamespace(text="hi", from_variable_selector=["a"])
event = SimpleNamespace(
text="hi",
from_variable_selector=["a"],
tool_call=None,
tool_result=None,
chunk_type=None,
node_id=None,
model_provider=None,
model_name=None,
model_icon=None,
model_icon_dark=None,
model_usage=None,
model_duration=None,
)
queue_message = SimpleNamespace(event=event)
responses = list(

View File

@ -134,13 +134,10 @@ class TestAgentChatAppRunnerRun:
runner.run(generate_entity, mocker.MagicMock(), mocker.MagicMock(), mocker.MagicMock())
@pytest.mark.parametrize(
("mode", "expected_runner"),
[
(LLMMode.CHAT, "CotChatAgentRunner"),
(LLMMode.COMPLETION, "CotCompletionAgentRunner"),
],
"mode",
[LLMMode.CHAT, LLMMode.COMPLETION],
)
def test_run_chain_of_thought_modes(self, runner, mocker, mode, expected_runner):
def test_run_chain_of_thought_modes(self, runner, mocker, mode):
app_record = mocker.MagicMock(id="app1", tenant_id="tenant")
app_config = mocker.MagicMock(app_id="app1", tenant_id="tenant", prompt_template=mocker.MagicMock())
app_config.agent = AgentEntity(provider="p", model="m", strategy=AgentEntity.Strategy.CHAIN_OF_THOUGHT)
@ -184,7 +181,7 @@ class TestAgentChatAppRunnerRun:
)
runner_cls = mocker.MagicMock()
mocker.patch(f"core.app.apps.agent_chat.app_runner.{expected_runner}", runner_cls)
mocker.patch("core.app.apps.agent_chat.app_runner.AgentAppRunner", runner_cls)
runner_instance = mocker.MagicMock()
runner_cls.return_value = runner_instance
@ -196,7 +193,8 @@ class TestAgentChatAppRunnerRun:
runner_instance.run.assert_called_once()
runner._handle_invoke_result.assert_called_once()
def test_run_invalid_llm_mode_raises(self, runner, mocker):
def test_run_uses_agent_app_runner_regardless_of_mode(self, runner, mocker):
"""After refactoring, AgentAppRunner is used for all strategies and LLM modes."""
app_record = mocker.MagicMock(id="app1", tenant_id="tenant")
app_config = mocker.MagicMock(app_id="app1", tenant_id="tenant", prompt_template=mocker.MagicMock())
app_config.agent = AgentEntity(provider="p", model="m", strategy=AgentEntity.Strategy.CHAIN_OF_THOUGHT)
@ -226,7 +224,7 @@ class TestAgentChatAppRunnerRun:
model_schema = mocker.MagicMock()
model_schema.features = []
model_schema.model_properties = {ModelPropertyKey.MODE: "invalid"}
model_schema.model_properties = {ModelPropertyKey.MODE: LLMMode.CHAT}
llm_instance = mocker.MagicMock()
llm_instance.model_type_instance.get_model_schema.return_value = model_schema
@ -239,8 +237,16 @@ class TestAgentChatAppRunnerRun:
side_effect=[app_record, conversation, message],
)
with pytest.raises(ValueError):
runner.run(generate_entity, mocker.MagicMock(), conversation, message)
runner_cls = mocker.MagicMock()
mocker.patch("core.app.apps.agent_chat.app_runner.AgentAppRunner", runner_cls)
runner_instance = mocker.MagicMock()
runner_cls.return_value = runner_instance
runner_instance.run.return_value = []
mocker.patch.object(runner, "_handle_invoke_result")
runner.run(generate_entity, mocker.MagicMock(), conversation, message)
runner_instance.run.assert_called_once()
def test_run_function_calling_strategy_selected_by_features(self, runner, mocker):
app_record = mocker.MagicMock(id="app1", tenant_id="tenant")
@ -286,7 +292,7 @@ class TestAgentChatAppRunnerRun:
)
runner_cls = mocker.MagicMock()
mocker.patch("core.app.apps.agent_chat.app_runner.FunctionCallAgentRunner", runner_cls)
mocker.patch("core.app.apps.agent_chat.app_runner.AgentAppRunner", runner_cls)
runner_instance = mocker.MagicMock()
runner_cls.return_value = runner_instance
@ -366,10 +372,11 @@ class TestAgentChatAppRunnerRun:
with pytest.raises(ValueError):
runner.run(generate_entity, mocker.MagicMock(), mocker.MagicMock(id="conv"), mocker.MagicMock(id="msg"))
def test_run_invalid_agent_strategy_raises(self, runner, mocker):
def test_run_any_strategy_uses_agent_app_runner(self, runner, mocker):
"""After refactoring, any agent strategy uses AgentAppRunner."""
app_record = mocker.MagicMock(id="app1", tenant_id="tenant")
app_config = mocker.MagicMock(app_id="app1", tenant_id="tenant", prompt_template=mocker.MagicMock())
app_config.agent = mocker.MagicMock(strategy="invalid", provider="p", model="m")
app_config.agent = mocker.MagicMock(strategy="custom", provider="p", model="m")
generate_entity = mocker.MagicMock(
app_config=app_config,
@ -409,5 +416,13 @@ class TestAgentChatAppRunnerRun:
side_effect=[app_record, conversation, message],
)
with pytest.raises(ValueError):
runner.run(generate_entity, mocker.MagicMock(), conversation, message)
runner_cls = mocker.MagicMock()
mocker.patch("core.app.apps.agent_chat.app_runner.AgentAppRunner", runner_cls)
runner_instance = mocker.MagicMock()
runner_cls.return_value = runner_instance
runner_instance.run.return_value = []
mocker.patch.object(runner, "_handle_invoke_result")
runner.run(generate_entity, mocker.MagicMock(), conversation, message)
runner_instance.run.assert_called_once()

View File

@ -2,7 +2,7 @@ from unittest.mock import MagicMock
from core.app.apps.base_app_queue_manager import PublishFrom
from core.app.apps.workflow_app_runner import WorkflowBasedAppRunner
from dify_graph.enums import NodeType
from dify_graph.enums import BuiltinNodeTypes
from dify_graph.graph_events import NodeRunStreamChunkEvent
@ -21,7 +21,7 @@ def test_skip_empty_final_chunk() -> None:
empty_final_event = NodeRunStreamChunkEvent(
id="exec",
node_id="node",
node_type=NodeType.LLM,
node_type=BuiltinNodeTypes.LLM,
selector=["node", "text"],
chunk="",
is_final=True,
@ -33,7 +33,7 @@ def test_skip_empty_final_chunk() -> None:
normal_event = NodeRunStreamChunkEvent(
id="exec",
node_id="node",
node_type=NodeType.LLM,
node_type=BuiltinNodeTypes.LLM,
selector=["node", "text"],
chunk="hi",
is_final=False,