fix(dify-builder): ground model on all model-bearing nodes, carry branch handles, clean test lint

Final consolidated fix wave from whole-branch review of the Real Build +
Edit Cognition slice:

- _ground now overwrites the model dict on ANY create_node whose config
  carries a model dict (llm, question-classifier, parameter-extractor),
  not just "llm", so a drifted/hallucinated provider/name on those other
  node types no longer flows through ungrounded.
- to_intents now carries a generator edge's sourceHandle/targetHandle
  into the connect intent's args (source_handle/target_handle) so
  branching nodes (if-else, question-classifier) wire onto the correct
  port instead of collapsing onto the default handle; edges without
  handles still produce bare {from_node, to_node} args.
- Cleared the 17 ruff errors (PT018/E302/E306/E501) across the slice's
  test files by splitting composite asserts, adding missing blank
  lines, and wrapping long lines -- no assertions weakened, no noqa.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Charles YaoandClaude Opus 4.8 committed 2026-08-29 14:22:19 -07:00
1 parent a07dc0e766
commit cd5fb6bbf0
7 files changed
+130 -18

No files matched your search

@@ -6,19 +6,27 @@ def test_list_tenant_resources_normalizes_all_three_kinds():
class _Model:
def __init__(self, m): self.model = m
class _ProvResp:
def __init__(self, p, ms): self.provider, self.models = p, [_Model(m) for m in ms]
class _DS:
def __init__(self, i, n): self.id, self.name = i, n
tool_record = {
"provider_name": "google", "tool_name": "search",
"tool_label": "Google Search", "description": "",
}
with patch.object(resources, "_list_models", return_value=[_ProvResp("anthropic", ["claude-opus-4-8"])]), \
patch.object(resources, "_list_datasets", return_value=[_DS("kb-1", "Company KB")]), \
patch.object(resources, "_list_tools", return_value=[{"provider_name": "google", "tool_name": "search", "tool_label": "Google Search", "description": ""}]):
patch.object(resources, "_list_tools", return_value=[tool_record]):
out = resources.list_tenant_resources("t1")
assert out.models[0].id == "anthropic/claude-opus-4-8"
assert out.datasets[0].id == "kb-1" and out.datasets[0].label == "Company KB"
assert out.tools[0].id == "google/search" and out.tools[0].label == "Google Search"
assert out.datasets[0].id == "kb-1"
assert out.datasets[0].label == "Company KB"
assert out.tools[0].id == "google/search"
assert out.tools[0].label == "Google Search"
def test_each_source_degrades_to_empty():
@@ -36,14 +44,20 @@ def test_mixed_failure_partial_success():
class _DS:
def __init__(self, i, n): self.id, self.name = i, n
tool_record = {
"provider_name": "google", "tool_name": "search",
"tool_label": "Google Search", "description": "",
}
with patch.object(resources, "_list_models", side_effect=RuntimeError("boom")), \
patch.object(resources, "_list_datasets", return_value=[_DS("kb-1", "Company KB")]), \
patch.object(resources, "_list_tools", return_value=[{"provider_name": "google", "tool_name": "search", "tool_label": "Google Search", "description": ""}]):
patch.object(resources, "_list_tools", return_value=[tool_record]):
out = resources.list_tenant_resources("t1")
assert out.models == []
assert len(out.datasets) == 1 and out.datasets[0].id == "kb-1"
assert len(out.tools) == 1 and out.tools[0].id == "google/search"
assert len(out.datasets) == 1
assert out.datasets[0].id == "kb-1"
assert len(out.tools) == 1
assert out.tools[0].id == "google/search"
def test_malformed_tool_record_degrades():
@@ -55,4 +69,5 @@ def test_malformed_tool_record_degrades():
out = resources.list_tenant_resources("t1")
assert out.tools == []
assert out.models == [] and out.datasets == []
assert out.models == []
assert out.datasets == []