From 8ac3f4579e7eee2710f6356b7812d9407561c998 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 2 Mar 2024 15:19:34 -0300 Subject: [PATCH] Refactor activated_vertices to activated_layers --- src/backend/langflow/api/v1/chat.py | 4 +- src/backend/langflow/api/v1/schemas.py | 2 +- src/backend/langflow/graph/graph/base.py | 51 +++++++++++++++++++----- src/frontend/src/stores/flowStore.ts | 14 +++---- src/frontend/src/types/api/index.ts | 2 +- src/frontend/src/utils/buildUtils.ts | 42 ++++++------------- 6 files changed, 63 insertions(+), 52 deletions(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 399098d47..8782efb29 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -156,13 +156,13 @@ async def build_vertex( inactivated_vertices = None inactivated_vertices = list(graph.inactivated_vertices) graph.reset_inactivated_vertices() - activated_vertices = list(graph.activated_vertices) + activated_layers = graph.activated_layers graph.reset_activated_vertices() chat_service.set_cache(flow_id, graph) build_response = VertexBuildResponse( inactivated_vertices=inactivated_vertices, - activated_vertices=activated_vertices, + activated_layers=activated_layers, valid=valid, params=params, id=vertex.id, diff --git a/src/backend/langflow/api/v1/schemas.py b/src/backend/langflow/api/v1/schemas.py index 88610d637..f570923e1 100644 --- a/src/backend/langflow/api/v1/schemas.py +++ b/src/backend/langflow/api/v1/schemas.py @@ -230,7 +230,7 @@ class ResultDataResponse(BaseModel): class VertexBuildResponse(BaseModel): id: Optional[str] = None inactivated_vertices: Optional[List[str]] = None - activated_vertices: Optional[List[str]] = None + activated_layers: Optional[List[List[str]]] = None valid: bool params: Optional[str] """JSON string of the params.""" diff --git a/src/backend/langflow/graph/graph/base.py b/src/backend/langflow/graph/graph/base.py index 90a6e4f9a..95ab6db6b 100644 --- a/src/backend/langflow/graph/graph/base.py +++ b/src/backend/langflow/graph/graph/base.py @@ -58,7 +58,7 @@ class Graph: self._vertices = self._graph_data["nodes"] self._edges = self._graph_data["edges"] self.inactivated_vertices: set = set() - self.activated_vertices: set = set() + self.activated_layers: List[List[str]] = [] self.edges: List[ContractEdge] = [] self.vertices: List[Vertex] = [] self._build_graph() @@ -80,20 +80,26 @@ class Graph: self.state_manager.update_state(name, record) def activate_state_vertices(self, name: str, caller: str): + layers = [] for vertex_id in self._is_state_vertices: + if vertex_id == caller: + continue vertex = self.get_vertex(vertex_id) if ( - name in vertex._raw_params["name"] + isinstance(vertex._raw_params["name"], str) + and name in vertex._raw_params["name"] and vertex_id != caller and isinstance(vertex, StateVertex) ): - successors = self.get_all_successors(vertex) - self.activated_vertices.add(vertex_id) - for successor in successors: - self.activated_vertices.add(successor.id) + layers.append([vertex_id]) + successors = self.get_all_successors(vertex, flat=False) + for layer in successors: + + layers.append([v.id for v in layer]) + self.activated_layers = layers def reset_activated_vertices(self): - self.activated_vertices = set() + self.activated_layers = [] def append_state( self, name: str, record: Union[str, Record], caller: Optional[str] = None @@ -555,18 +561,41 @@ class Graph: for source_id in self.predecessor_map.get(vertex.id, []) ] - def get_all_successors(self, vertex, recursive=True): + def get_all_successors(self, vertex, recursive=True, flat=True): # Recursively get the successors of the current vertex + # successors = vertex.successors + # if not successors: + # return [] + # successors_result = [] + # for successor in successors: + # # Just return a list of successors + # if recursive: + # next_successors = self.get_all_successors(successor) + # successors_result.extend(next_successors) + # successors_result.append(successor) + # return successors_result + # The above is the version without the flat parameter + # The below is the version with the flat parameter + # the flat parameter will define if each layer of successors + # becomes one list or if the result is a list of lists + # if flat is True, the result will be a list of vertices + # if flat is False, the result will be a list of lists of vertices + # each list will represent a layer of successors successors = vertex.successors if not successors: return [] successors_result = [] for successor in successors: - # Just return a list of successors if recursive: next_successors = self.get_all_successors(successor) - successors_result.extend(next_successors) - successors_result.append(successor) + if flat: + successors_result.extend(next_successors) + else: + successors_result.append(next_successors) + if flat: + successors_result.append(successor) + else: + successors_result.append([successor]) return successors_result def get_successors(self, vertex): diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index f93b72858..d7780c857 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -223,12 +223,10 @@ const useFlowStore = create((set, get) => ({ selection.nodes.some((node) => node.data.type === "ChatInput") && checkChatInput(get().nodes) ) { - useAlertStore - .getState() - .setErrorData({ - title: "Error pasting components", - list: ["You can only have one ChatInput component in the flow"], - }); + useAlertStore.getState().setErrorData({ + title: "Error pasting components", + list: ["You can only have one ChatInput component in the flow"], + }); return; } let minimumX = Infinity; @@ -451,8 +449,8 @@ const useFlowStore = create((set, get) => ({ if (vertexBuildData && vertexBuildData.inactivated_vertices) { get().removeFromVerticesBuild(vertexBuildData.inactivated_vertices); } - if (vertexBuildData && vertexBuildData.activated_vertices) { - get().addToVerticesBuild(vertexBuildData.activated_vertices); + if (vertexBuildData && vertexBuildData.activated_layers) { + get().addToVerticesBuild(vertexBuildData.activated_layers.flat()); } get().addDataToFlowPool( { ...vertexBuildData, buildId }, diff --git a/src/frontend/src/types/api/index.ts b/src/frontend/src/types/api/index.ts index 076ecbf45..469ca3d9f 100644 --- a/src/frontend/src/types/api/index.ts +++ b/src/frontend/src/types/api/index.ts @@ -141,7 +141,7 @@ export type VerticesOrderTypeAPI = { export type VertexBuildTypeAPI = { id: string; inactivated_vertices: Array | null; - activated_vertices: Array | null; + activated_layers: Array> | null; valid: boolean; params: string; data: VertexDataTypeAPI; diff --git a/src/frontend/src/utils/buildUtils.ts b/src/frontend/src/utils/buildUtils.ts index 63da6b7e8..b89fc6a5a 100644 --- a/src/frontend/src/utils/buildUtils.ts +++ b/src/frontend/src/utils/buildUtils.ts @@ -32,7 +32,7 @@ function getInactiveVertexData(vertexId: string): VertexBuildTypeAPI { data: inactiveData, params: "Inactive", inactivated_vertices: null, - activated_vertices: null, + activated_layers: null, valid: false, timestamp: new Date().toISOString(), }; @@ -131,41 +131,25 @@ export async function buildVertices({ const handleBuildUpdate = (data: VertexBuildTypeAPI, status: BuildStatus) => { // Handle activated vertices console.log("handleBuildUpdate", data, status); - if (data.activated_vertices && data.activated_vertices.length > 0) { - // Logic to determine the correct placement for activated vertices in dynamicVerticesLayers - // For simplicity, this example adds them to the next layer - // const nextLayerIndex = i + 1; i doesnt exist in this scope - // we don't want to add the activated vertices to the last layer - // because these vertices should be built right away + if (data.activated_layers && data.activated_layers.length > 0) { const thisVertexLayer = dynamicVerticesLayers.findIndex((layer) => layer.includes(data.id) ); - const nextLayerIndex = thisVertexLayer + 1; + let nextLayerIndex = thisVertexLayer + 1; + console.log("nextLayerIndex", nextLayerIndex); console.log("dynamicVerticesLayers", dynamicVerticesLayers); - if (dynamicVerticesLayers[nextLayerIndex]) { - // If the next layer exists, add the activated vertices to it - // dynamicVerticesLayers[nextLayerIndex] = dynamicVerticesLayers[ - // nextLayerIndex - // ].concat(data.activated_vertices); - // instead of adding them all at once, add them one by one - // add one per layer and if the next layer doesn't exist, create it - for (const vertex of data.activated_vertices) { - console.log("vertex", vertex); - if (dynamicVerticesLayers[nextLayerIndex].includes(vertex)) { - continue; - } else if (dynamicVerticesLayers[nextLayerIndex].length > 0) { - dynamicVerticesLayers[nextLayerIndex].push(vertex); - } else { - dynamicVerticesLayers[nextLayerIndex] = [vertex]; - } - console.log("dynamicVerticesLayers", dynamicVerticesLayers); + data.activated_layers.forEach((newLayer) => { + if (!dynamicVerticesLayers[nextLayerIndex]) { + dynamicVerticesLayers[nextLayerIndex] = []; } - } else { - dynamicVerticesLayers.push(data.activated_vertices); - console.log(dynamicVerticesLayers); - } + dynamicVerticesLayers[nextLayerIndex] = [ + ...dynamicVerticesLayers[nextLayerIndex], + ...newLayer, + ]; + nextLayerIndex += 1; + }); } if (onBuildUpdate) onBuildUpdate(data, status, runId); };