Refactor workflow routing and greeting management in Brain classes

- Update WorkflowBrain to handle greeting playback more effectively, ensuring that the initial greeting completes before transitioning to the first node.
- Introduce new methods for managing greeting states and conditions, enhancing the interaction flow for user turns.
- Refactor WorkflowLLMRouter to improve routing logic and ensure proper handling of conditional paths.
- Enhance tests to verify the correct behavior of greeting management and routing under various scenarios, including waiting for audio playback to finish.
- Update frontend components to reflect changes in edge handling and improve user experience in workflow configurations.
This commit is contained in:
Xin Wang
2026-07-17 22:01:42 +08:00
parent 34c0d12d2a
commit 162a3d8bec
15 changed files with 826 additions and 147 deletions

View File

@@ -41,6 +41,7 @@ import {
} from "@/components/ui/tooltip";
import { edgeTypes } from "./ConditionEdge";
import { hasDefaultPath, newEdgeData } from "./edge-rules";
import {
ActiveNodeContext,
EdgeActionContext,
@@ -201,9 +202,7 @@ export function WorkflowCanvas({
const onConnect = useCallback(
(connection: Connection) => {
const sourceType = nodes.find((node) => node.id === connection.source)?.type;
const priority =
edges.filter((edge) => edge.source === connection.source).length * 10 + 10;
if (!connection.source || !connection.target) return;
setEdges((eds) =>
addEdge(
{
@@ -211,20 +210,13 @@ export function WorkflowCanvas({
id: `e-${connection.source}-${connection.target}-${Date.now()}`,
type: "condition",
animated: true,
data:
sourceType === "agent"
? {
mode: "llm",
priority,
condition: "当前阶段任务已经完成",
}
: { mode: "always", priority },
data: newEdgeData(eds, connection.source),
},
eds,
),
);
},
[nodes, edges, setEdges],
[setEdges],
);
// 连线约束:不能连入开始节点(无入边句柄),不能自连。
@@ -278,8 +270,6 @@ export function WorkflowCanvas({
setNodes((ns) => [...ns, { id, type: spec.type, position, data }]);
if (source) {
setEdges((currentEdges) => {
const priority =
currentEdges.filter((edge) => edge.source === source.id).length * 10 + 10;
return addEdge(
{
id: `e-${source.id}-${id}-${Date.now()}`,
@@ -287,14 +277,7 @@ export function WorkflowCanvas({
target: id,
type: "condition",
animated: true,
data:
source.type === "agent"
? {
mode: "llm",
priority,
condition: "当前阶段任务已经完成",
}
: { mode: "always", priority },
data: newEdgeData(currentEdges, source.id),
},
currentEdges,
);
@@ -363,9 +346,16 @@ export function WorkflowCanvas({
patch: WorkflowGraph["edges"][number]["data"],
) => {
setEdges((es) =>
es.map((e) =>
e.id === id ? { ...e, data: { ...(e.data ?? {}), ...patch } } : e,
),
es.map((e) => {
if (e.id !== id) return e;
if (
patch.mode === "always" &&
hasDefaultPath(es, e.source, e.id)
) {
return e;
}
return { ...e, data: { ...(e.data ?? {}), ...patch } };
}),
);
},
[setEdges],
@@ -392,7 +382,7 @@ export function WorkflowCanvas({
) {
return false;
}
return source.type === "agent" || outgoingCount === 0;
return true;
},
[edges, nodes, specsByType],
);
@@ -751,7 +741,11 @@ export function WorkflowCanvas({
<EdgeSettingsPanel
key={editingEdge.id}
edge={editingEdge}
sourceType={nodes.find((node) => node.id === editingEdge.source)?.type}
hasOtherDefaultPath={hasDefaultPath(
edges,
editingEdge.source,
editingEdge.id,
)}
onChange={(patch) =>
updateEdgeData(editingEdge.id, patch)
}
@@ -769,4 +763,3 @@ export function WorkflowCanvas({
</NodeSpecsContext.Provider>
);
}