diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index ea1aace65..c9f2897df 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -1,6 +1,6 @@ import time -from fastapi import APIRouter, Depends, HTTPException, Query, WebSocket, WebSocketException, status, Body +from fastapi import APIRouter, Body, Depends, HTTPException, Query, WebSocket, WebSocketException, status from fastapi.responses import StreamingResponse from langflow.api.utils import build_input_keys_response, format_elapsed_time from langflow.api.v1.schemas import ( @@ -12,14 +12,14 @@ from langflow.api.v1.schemas import ( VertexBuildResponse, VerticesOrderResponse, ) +from langflow.graph.graph.base import Graph from langflow.graph.vertex.base import StatelessVertex from langflow.processing.process import process_tweaks_on_graph -from langflow.services.database.models.flow import Flow -from langflow.graph.graph.base import Graph from langflow.services.auth.utils import get_current_active_user, get_current_user_by_jwt from langflow.services.cache.service import BaseCacheService from langflow.services.cache.utils import update_build_status from langflow.services.chat.service import ChatService +from langflow.services.database.models.flow import Flow from langflow.services.deps import get_cache_service, get_chat_service, get_session from loguru import logger from sqlmodel import Session @@ -255,7 +255,7 @@ async def get_vertices( """Check the flow_id is in the flow_data_store.""" try: flow: Flow = session.get(Flow, flow_id) - if not flow: + if not flow or not flow.data: raise ValueError("Invalid flow ID") graph = Graph.from_payload(flow.data) chat_service.set_cache(flow_id, graph) @@ -267,6 +267,7 @@ async def get_vertices( except Exception as exc: logger.error(f"Error checking build status: {exc}") + logger.exception(exc) raise HTTPException(status_code=500, detail=str(exc)) from exc diff --git a/src/backend/langflow/api/v1/validate.py b/src/backend/langflow/api/v1/validate.py index 51d0f0d76..1cebeedb6 100644 --- a/src/backend/langflow/api/v1/validate.py +++ b/src/backend/langflow/api/v1/validate.py @@ -1,4 +1,6 @@ from fastapi import APIRouter, HTTPException +from loguru import logger + from langflow.api.v1.base import ( Code, CodeValidationResponse, @@ -8,7 +10,6 @@ from langflow.api.v1.base import ( ) from langflow.template.field.base import TemplateField from langflow.utils.validate import validate_code -from loguru import logger # build router router = APIRouter(prefix="/validate", tags=["Validate"]) @@ -81,7 +82,7 @@ def add_new_variables_to_template(input_variables, prompt_request): show=True, advanced=False, multiline=True, - input_types=["Document", "BaseOutputParser"], + input_types=["Document", "BaseOutputParser", "Text"], value="", # Set the value to empty string ) if variable in prompt_request.frontend_node.template: diff --git a/src/backend/langflow/components/chains/LLMChain.py b/src/backend/langflow/components/chains/LLMChain.py index ec88e128a..309f69215 100644 --- a/src/backend/langflow/components/chains/LLMChain.py +++ b/src/backend/langflow/components/chains/LLMChain.py @@ -1,14 +1,8 @@ from typing import Callable, Optional, Union from langchain.chains import LLMChain - from langflow import CustomComponent -from langflow.field_typing import ( - BaseLanguageModel, - BaseMemory, - BasePromptTemplate, - Chain, -) +from langflow.field_typing import BaseLanguageModel, BaseMemory, BasePromptTemplate, Chain class LLMChainComponent(CustomComponent): diff --git a/src/backend/langflow/graph/graph/base.py b/src/backend/langflow/graph/graph/base.py index ef747ec33..1037150a9 100644 --- a/src/backend/langflow/graph/graph/base.py +++ b/src/backend/langflow/graph/graph/base.py @@ -1,5 +1,5 @@ -from typing import Dict, Generator, List, Type, Union from collections import defaultdict, deque +from typing import Dict, Generator, List, Type, Union from langchain.chains.base import Chain from loguru import logger @@ -256,7 +256,7 @@ class Graph: return f"Graph:\nNodes: {vertex_ids}\nConnections:\n{edges_repr}" def layered_topological_sort(self): - in_degree = {vertex: 0 for vertex in self.vertices} # Initialize in-degrees + in_degree = {vertex.id: 0 for vertex in self.vertices} # Initialize in-degrees graph = defaultdict(list) # Adjacency list representation # Build graph and compute in-degrees @@ -265,7 +265,7 @@ class Graph: in_degree[edge.target_id] += 1 # Queue for vertices with no incoming edges - queue = deque(vertex for vertex in self.vertices if in_degree[vertex] == 0) + queue = deque(vertex.id for vertex in self.vertices if in_degree[vertex.id] == 0) layers = [] current_layer = 0 @@ -273,9 +273,9 @@ class Graph: layers.append([]) # Start a new layer layer_size = len(queue) for _ in range(layer_size): - vertex = queue.popleft() - layers[current_layer].append(vertex.id) - for neighbor in graph[vertex]: + vertex_id = queue.popleft() + layers[current_layer].append(vertex_id) + for neighbor in graph[vertex_id]: in_degree[neighbor] -= 1 # 'remove' edge if in_degree[neighbor] == 0: queue.append(neighbor) diff --git a/src/backend/langflow/services/chat/service.py b/src/backend/langflow/services/chat/service.py index 82730c6ba..0d7f9ca6c 100644 --- a/src/backend/langflow/services/chat/service.py +++ b/src/backend/langflow/services/chat/service.py @@ -5,15 +5,14 @@ from typing import Any, Dict, List import orjson from fastapi import WebSocket, status -from loguru import logger -from starlette.websockets import WebSocketState - from langflow.api.v1.schemas import ChatMessage, ChatResponse, FileResponse from langflow.interface.utils import pil_to_base64 -from langflow.services import ServiceType, service_manager from langflow.services.base import Service from langflow.services.chat.cache import Subject from langflow.services.chat.utils import process_graph +from langflow.services.deps import get_cache_service +from loguru import logger +from starlette.websockets import WebSocketState from .cache import cache_service @@ -54,7 +53,7 @@ class ChatService(Service): self.chat_history = ChatHistory() self.chat_cache = cache_service self.chat_cache.attach(self.update) - self.cache_service = service_manager.get(ServiceType.CACHE_SERVICE) + self.cache_service = get_cache_service() def on_chat_history_update(self): """Send the last chat message to the client.""" @@ -240,7 +239,7 @@ class ChatService(Service): """ Get the cache for a client. """ - return self.chat_cache.get(client_id) + return self.cache_service.get(client_id) def dict_to_markdown_table(my_dict): diff --git a/src/backend/langflow/services/database/models/base.py b/src/backend/langflow/services/database/models/base.py index 18b56ff90..17dd947d9 100644 --- a/src/backend/langflow/services/database/models/base.py +++ b/src/backend/langflow/services/database/models/base.py @@ -1,4 +1,5 @@ import orjson +from pydantic import ConfigDict from sqlmodel import SQLModel @@ -19,7 +20,4 @@ def orjson_dumps(v, *, default=None, sort_keys=False, indent_2=True): class SQLModelSerializable(SQLModel): - class Config: - orm_mode = True - json_loads = orjson.loads - json_dumps = orjson_dumps + model_config = ConfigDict(from_attributes=True)