mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
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>
61 lines
2.3 KiB
Python
61 lines
2.3 KiB
Python
"""Translate a WorkflowGenerator graph into Dify Builder MutationIntents.
|
|
|
|
The generator emits ReactFlow nodes ({id, type:"custom", data:{type:<real>,...}})
|
|
and edges. We emit one create_node per node (config = node.data minus the
|
|
redundant "type" key -- apply_create_node re-sets it) followed by one connect
|
|
per edge, so every connect endpoint already exists at apply time. The start
|
|
node is renamed to the conventional id "start" so it reconciles with a draft
|
|
that already has one (the handler's present-filter drops the duplicate)."""
|
|
|
|
from typing import Any
|
|
|
|
from core.dify_builder.models import MutationIntent
|
|
|
|
_START_ID = "start"
|
|
|
|
|
|
def to_intents(graph: dict[str, Any]) -> list[MutationIntent]:
|
|
nodes = graph.get("nodes") or []
|
|
edges = graph.get("edges") or []
|
|
|
|
# rename map: the generator start id -> canonical "start"
|
|
# Only map the first start node; additional starts keep their original ids
|
|
remap: dict[str, str] = {}
|
|
for node in nodes:
|
|
data = node.get("data") or {}
|
|
if data.get("type") == "start" and node.get("id") and not remap:
|
|
remap[str(node["id"])] = _START_ID
|
|
|
|
creates: list[MutationIntent] = []
|
|
for node in nodes:
|
|
data = node.get("data") or {}
|
|
node_type = data.get("type")
|
|
node_id = node.get("id")
|
|
if not node_type or not node_id:
|
|
continue
|
|
config = {k: v for k, v in data.items() if k != "type"}
|
|
creates.append(MutationIntent(op="create_node", args={
|
|
"node_type": str(node_type),
|
|
"config": config,
|
|
"node_id": remap.get(str(node_id), str(node_id)),
|
|
}))
|
|
|
|
connects: list[MutationIntent] = []
|
|
for edge in edges:
|
|
src, tgt = edge.get("source"), edge.get("target")
|
|
if not src or not tgt:
|
|
continue
|
|
args: dict[str, Any] = {
|
|
"from_node": remap.get(str(src), str(src)),
|
|
"to_node": remap.get(str(tgt), str(tgt)),
|
|
}
|
|
source_handle = edge.get("sourceHandle")
|
|
if source_handle:
|
|
args["source_handle"] = source_handle
|
|
target_handle = edge.get("targetHandle")
|
|
if target_handle:
|
|
args["target_handle"] = target_handle
|
|
connects.append(MutationIntent(op="connect", args=args))
|
|
|
|
return creates + connects
|