Add Dify integration and enhance workflow node specifications

- Introduce new fields `dify_api_url` and `dify_api_key` in `AssistantConfig` for Dify API integration.
- Update `requirements.txt` to include `dify-client-python` for Dify SDK support.
- Modify `config_resolver` to handle Dify connection information.
- Add a new `globalNode` type in workflow specifications to provide unified settings across workflows.
- Enhance node specifications with additional constraints and default values for better configuration management.
- Update frontend components to support the new `globalNode` type and its properties, improving workflow editor functionality.
This commit is contained in:
Xin Wang
2026-07-11 22:26:31 +08:00
parent dfb9c5bd11
commit 00270a5c01
23 changed files with 1270 additions and 414 deletions

View File

@@ -3,6 +3,7 @@
对应 dograh 的 pipecat_engine.py,极简实现:
- 单个 startCall 入口,开场白来自该节点;
- agentNode 用各自的 prompt 驱动多轮对话;
- globalNode 不参与连线,按节点开关向会话节点注入统一提示词;
- 每轮助手回复后,用一次轻量 LLM「路由」判断是否满足某条出边的 condition,
满足则切换当前节点(linear = 单边;branching = 多边按条件分流);
- 到达 endCall 播放结束语并停止路由。
@@ -27,6 +28,10 @@ class WorkflowEngine:
(nid for nid, n in self.nodes.items() if n.get("type") == "startCall"),
None,
)
self.global_id: str | None = next(
(nid for nid, n in self.nodes.items() if n.get("type") == "globalNode"),
None,
)
# ---- 结构查询 ----
def node_type(self, nid: str | None) -> str | None:
@@ -80,10 +85,25 @@ class WorkflowEngine:
return self.data(self.start_id).get("greeting") or ""
def system_prompt_for(self, nid: str | None) -> str:
"""节点系统提示:仅用该节点自己的 prompt(开始节点也是会话节点)。"""
"""组合当前节点提示与可选的全局提示(开始节点也是会话节点)。"""
header = f"[当前节点:{self.name(nid)}]"
prompt = str(self.data(nid).get("prompt") or "").strip()
return f"{header}\n{prompt}" if prompt else header
node_data = self.data(nid)
prompt = str(node_data.get("prompt") or "").strip()
node_type = self.node_type(nid)
default_add_global = node_type in {"startCall", "agentNode"}
add_global = bool(node_data.get("addGlobalPrompt", default_add_global))
global_prompt = (
str(self.data(self.global_id).get("prompt") or "").strip()
if add_global and self.global_id
else ""
)
sections = [header]
if global_prompt:
sections.append(f"[全局规则]\n{global_prompt}")
if prompt:
sections.append(f"[当前节点任务]\n{prompt}")
return "\n\n".join(sections)
# ---- 路由:决定下一节点 ----
async def route(