Update types and attributes
This commit is contained in:
parent
77b3089663
commit
30ee500c60
14 changed files with 101 additions and 61 deletions
|
|
@ -16,6 +16,7 @@ from langflow.api.utils import (
|
|||
)
|
||||
from langflow.api.v1.schemas import (
|
||||
InputValueRequest,
|
||||
Log,
|
||||
ResultDataResponse,
|
||||
StreamData,
|
||||
VertexBuildResponse,
|
||||
|
|
@ -138,6 +139,7 @@ async def build_vertex(
|
|||
start_time = time.perf_counter()
|
||||
next_runnable_vertices = []
|
||||
top_level_vertices = []
|
||||
messages = []
|
||||
try:
|
||||
start_time = time.perf_counter()
|
||||
cache = await chat_service.get_cache(flow_id)
|
||||
|
|
@ -157,9 +159,9 @@ async def build_vertex(
|
|||
next_runnable_vertices,
|
||||
top_level_vertices,
|
||||
result_dict,
|
||||
params,
|
||||
log_message,
|
||||
valid,
|
||||
artifacts,
|
||||
_,
|
||||
vertex,
|
||||
) = await graph.build_vertex(
|
||||
lock=lock,
|
||||
|
|
@ -172,14 +174,17 @@ async def build_vertex(
|
|||
|
||||
except Exception as exc:
|
||||
logger.exception(f"Error building vertex: {exc}")
|
||||
params = format_exception_message(exc)
|
||||
log_message = format_exception_message(exc)
|
||||
valid = False
|
||||
result_data_response = ResultDataResponse(results={})
|
||||
artifacts = {}
|
||||
|
||||
# If there's an error building the vertex
|
||||
# we need to clear the cache
|
||||
await chat_service.clear_cache(flow_id)
|
||||
|
||||
log_object = Log(message=log_message)
|
||||
result_data_response.logs.append(log_object)
|
||||
|
||||
# Log the vertex build
|
||||
if not vertex.will_stream:
|
||||
background_tasks.add_task(
|
||||
|
|
@ -187,21 +192,21 @@ async def build_vertex(
|
|||
flow_id=flow_id,
|
||||
vertex_id=vertex_id,
|
||||
valid=valid,
|
||||
params=params,
|
||||
logs=result_data_response.logs,
|
||||
data=result_data_response,
|
||||
artifacts=artifacts,
|
||||
)
|
||||
|
||||
timedelta = time.perf_counter() - start_time
|
||||
duration = format_elapsed_time(timedelta)
|
||||
result_data_response.duration = duration
|
||||
result_data_response.timedelta = timedelta
|
||||
vertex.add_build_time(timedelta)
|
||||
inactivated_vertices = None
|
||||
inactivated_vertices = list(graph.inactivated_vertices)
|
||||
graph.reset_inactivated_vertices()
|
||||
graph.reset_activated_vertices()
|
||||
await chat_service.set_cache(flow_id, graph)
|
||||
async with chat_service._cache_locks[flow_id] as lock:
|
||||
vertex.add_build_time(timedelta)
|
||||
inactivated_vertices = None
|
||||
inactivated_vertices = list(graph.inactivated_vertices)
|
||||
graph.reset_inactivated_vertices()
|
||||
graph.reset_activated_vertices()
|
||||
await chat_service.set_cache(flow_id=flow_id, data=graph, lock=lock)
|
||||
|
||||
# graph.stop_vertex tells us if the user asked
|
||||
# to stop the build of the graph at a certain vertex
|
||||
|
|
@ -215,7 +220,6 @@ async def build_vertex(
|
|||
next_vertices_ids=next_runnable_vertices,
|
||||
top_level_vertices=top_level_vertices,
|
||||
valid=valid,
|
||||
params=params,
|
||||
id=vertex.id,
|
||||
data=result_data_response,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
from langflow.utils.schemas import ChatOutputResponse
|
||||
from typing_extensions import TypedDict
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_serializer
|
||||
|
|
@ -233,9 +235,14 @@ class VerticesOrderResponse(BaseModel):
|
|||
vertices_to_run: List[str]
|
||||
|
||||
|
||||
class Log(TypedDict):
|
||||
message: str
|
||||
|
||||
|
||||
class ResultDataResponse(BaseModel):
|
||||
results: Optional[Any] = Field(default_factory=dict)
|
||||
artifacts: Optional[Any] = Field(default_factory=dict)
|
||||
logs: List[Log | None] = Field(default_factory=list)
|
||||
messages: List[ChatOutputResponse | None] = Field(default_factory=list)
|
||||
timedelta: Optional[float] = None
|
||||
duration: Optional[str] = None
|
||||
|
||||
|
|
@ -246,11 +253,9 @@ class VertexBuildResponse(BaseModel):
|
|||
next_vertices_ids: Optional[List[str]] = None
|
||||
top_level_vertices: Optional[List[str]] = None
|
||||
valid: bool
|
||||
params: Optional[Any] = Field(default_factory=dict)
|
||||
"""JSON string of the params."""
|
||||
data: ResultDataResponse
|
||||
"""Mapping of vertex ids to result dict containing the param name and result value."""
|
||||
timestamp: Optional[datetime] = Field(default_factory=datetime.utcnow)
|
||||
timestamp: Optional[datetime] = Field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
"""Timestamp of the build."""
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import ast
|
||||
import json
|
||||
from typing import AsyncIterator, Callable, Dict, Iterator, List, Optional, Union
|
||||
|
||||
import yaml
|
||||
from langchain_core.messages import AIMessage
|
||||
from loguru import logger
|
||||
|
|
@ -422,9 +423,9 @@ class ChatVertex(Vertex):
|
|||
flow_id=self.graph.flow_id,
|
||||
vertex_id=self.id,
|
||||
valid=True,
|
||||
params=self._built_object_repr(),
|
||||
logs=self._built_object_repr(),
|
||||
data=self.result,
|
||||
artifacts=self.artifacts,
|
||||
messages=self.artifacts,
|
||||
)
|
||||
|
||||
self._validate_built_object()
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ class MessageModel(BaseModel):
|
|||
sender_name: str
|
||||
session_id: str
|
||||
message: str
|
||||
artifacts: dict
|
||||
files: list[str] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
populate_by_name = True
|
||||
|
||||
@validator("artifacts", pre=True)
|
||||
@validator("files", pre=True)
|
||||
def validate_target_args(cls, v):
|
||||
if isinstance(v, str):
|
||||
return json.loads(v)
|
||||
|
|
@ -58,7 +58,7 @@ class MessageModel(BaseModel):
|
|||
sender_name=record.sender_name,
|
||||
message=record.text,
|
||||
session_id=record.session_id,
|
||||
artifacts=record.artifacts or {},
|
||||
files=record.files or [],
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -67,16 +67,15 @@ class VertexBuildModel(BaseModel):
|
|||
id: Optional[str] = Field(default=None, alias="id")
|
||||
flow_id: str
|
||||
valid: bool
|
||||
params: Any
|
||||
logs: Any
|
||||
data: dict
|
||||
artifacts: dict
|
||||
timestamp: datetime = Field(default_factory=datetime.now)
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
populate_by_name = True
|
||||
|
||||
@field_serializer("data", "artifacts")
|
||||
@field_serializer("data")
|
||||
def serialize_dict(v):
|
||||
if isinstance(v, dict):
|
||||
# check if the value of each key is a BaseModel or a list of BaseModels
|
||||
|
|
@ -88,7 +87,7 @@ class VertexBuildModel(BaseModel):
|
|||
return json.dumps(v)
|
||||
return v
|
||||
|
||||
@validator("params", pre=True)
|
||||
@validator("logs", pre=True)
|
||||
def validate_params(cls, v):
|
||||
if isinstance(v, str):
|
||||
try:
|
||||
|
|
@ -97,7 +96,7 @@ class VertexBuildModel(BaseModel):
|
|||
return v
|
||||
return v
|
||||
|
||||
@field_serializer("params")
|
||||
@field_serializer("logs")
|
||||
def serialize_params(v):
|
||||
if isinstance(v, list) and all(isinstance(i, BaseModel) for i in v):
|
||||
return json.dumps([i.model_dump() for i in v])
|
||||
|
|
@ -109,15 +108,11 @@ class VertexBuildModel(BaseModel):
|
|||
return json.loads(v)
|
||||
return v
|
||||
|
||||
@validator("artifacts", pre=True)
|
||||
def validate_artifacts(cls, v):
|
||||
if isinstance(v, str):
|
||||
return json.loads(v)
|
||||
return v
|
||||
|
||||
|
||||
class VertexBuildResponseModel(VertexBuildModel):
|
||||
@field_serializer("data", "artifacts")
|
||||
messages: list[MessageModel] = []
|
||||
|
||||
@field_serializer("data")
|
||||
def serialize_dict(v):
|
||||
return v
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class MonitorService(Service):
|
|||
valid: Optional[bool] = None,
|
||||
order_by: Optional[str] = "timestamp",
|
||||
):
|
||||
query = "SELECT id, flow_id, valid, params, data, artifacts, timestamp FROM vertex_builds"
|
||||
query = "SELECT id, flow_id, valid, logs, data, timestamp FROM vertex_builds"
|
||||
conditions = []
|
||||
if flow_id:
|
||||
conditions.append(f"flow_id = '{flow_id}'")
|
||||
|
|
|
|||
|
|
@ -138,9 +138,9 @@ async def log_vertex_build(
|
|||
flow_id: str,
|
||||
vertex_id: str,
|
||||
valid: bool,
|
||||
params: Any,
|
||||
logs: Any,
|
||||
data: "ResultDataResponse",
|
||||
artifacts: Optional[dict] = None,
|
||||
messages: Optional[dict] = None,
|
||||
):
|
||||
try:
|
||||
monitor_service = get_monitor_service()
|
||||
|
|
@ -149,9 +149,9 @@ async def log_vertex_build(
|
|||
"flow_id": flow_id,
|
||||
"id": vertex_id,
|
||||
"valid": valid,
|
||||
"params": params,
|
||||
"logs": logs,
|
||||
"data": data.model_dump(),
|
||||
"artifacts": artifacts or {},
|
||||
"messages": messages or {},
|
||||
"timestamp": monitor_service.get_timestamp(),
|
||||
}
|
||||
monitor_service.add_row(table_name="vertex_builds", data=row)
|
||||
|
|
|
|||
|
|
@ -90,9 +90,9 @@ async def build_vertex(
|
|||
flow_id=flow_id,
|
||||
vertex_id=vertex_id,
|
||||
valid=valid,
|
||||
params=params,
|
||||
logs=params,
|
||||
data=result_dict,
|
||||
artifacts=artifacts,
|
||||
messages=artifacts,
|
||||
)
|
||||
|
||||
# Emit the vertex build response
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ class ChatOutputResponse(BaseModel):
|
|||
session_id: Optional[str] = None
|
||||
stream_url: Optional[str] = None
|
||||
component_id: Optional[str] = None
|
||||
files: List[str] = []
|
||||
|
||||
@classmethod
|
||||
def from_message(
|
||||
|
|
|
|||
|
|
@ -204,16 +204,21 @@ export default function GenericNode({
|
|||
}, [flowPool[data.id], data.id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (validationStatus?.params) {
|
||||
if (validationStatus?.logs) {
|
||||
// if it is not a string turn it into a string
|
||||
let newValidationString = validationStatus.params;
|
||||
let newValidationString = "";
|
||||
if (validationStatus?.logs && Array.isArray(validationStatus.logs)) {
|
||||
newValidationString = validationStatus.logs
|
||||
.map((log) => log.message)
|
||||
.join("\n");
|
||||
}
|
||||
if (typeof newValidationString !== "string") {
|
||||
newValidationString = JSON.stringify(validationStatus.params);
|
||||
newValidationString = JSON.stringify(validationStatus.logs);
|
||||
}
|
||||
|
||||
setValidationString(newValidationString);
|
||||
}
|
||||
}, [validationStatus, validationStatus?.params]);
|
||||
}, [validationStatus, validationStatus?.logs]);
|
||||
|
||||
const [showNode, setShowNode] = useState(data.showNode ?? true);
|
||||
|
||||
|
|
|
|||
|
|
@ -64,11 +64,11 @@ export default function ChatView({
|
|||
const chatMessages: ChatMessageType[] = chatOutputResponses
|
||||
.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp))
|
||||
//
|
||||
.filter((output) => output.data.artifacts?.message !== null)
|
||||
.filter((output) => output.messages && output.messages.length > 0)
|
||||
.map((output, index) => {
|
||||
try {
|
||||
const { sender, message, sender_name, stream_url } = output.data
|
||||
.artifacts as ChatOutputType;
|
||||
const { sender, message, sender_name, stream_url } = output
|
||||
.messages[0] as ChatOutputType;
|
||||
|
||||
const is_ai = sender === "Machine" || sender === null;
|
||||
return {
|
||||
|
|
@ -202,7 +202,9 @@ export default function ChatView({
|
|||
chatValue={chatValue}
|
||||
noInput={!inputTypes.includes("ChatInput")}
|
||||
lockChat={lockChat}
|
||||
sendMessage={({repeat,files}) => sendMessage({repeat,files})}
|
||||
sendMessage={({ repeat, files }) =>
|
||||
sendMessage({ repeat, files })
|
||||
}
|
||||
setChatValue={(value) => {
|
||||
setChatValue(value);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { Edge, Node, Viewport } from "reactflow";
|
||||
import { ChatOutputType, chatInputType } from "../chat";
|
||||
import { Log } from "../components";
|
||||
import { FlowType } from "../flow";
|
||||
//kind and class are just representative names to represent the actual structure of the object received by the API
|
||||
export type APIDataType = { [key: string]: APIKindType };
|
||||
|
|
@ -150,7 +152,8 @@ export type VertexBuildTypeAPI = {
|
|||
top_level_vertices: Array<string>;
|
||||
run_id: string;
|
||||
valid: boolean;
|
||||
params: string;
|
||||
logs: Log[];
|
||||
messages: ChatOutputType[] | chatInputType[];
|
||||
data: VertexDataTypeAPI;
|
||||
timestamp: string;
|
||||
};
|
||||
|
|
@ -160,6 +163,7 @@ export type VertexBuildTypeAPI = {
|
|||
export type VertexDataTypeAPI = {
|
||||
results: { [key: string]: { [key: string]: string } };
|
||||
artifacts: { [key: string]: string };
|
||||
messages: ChatOutputType[] | chatInputType[];
|
||||
timedelta?: number;
|
||||
duration?: string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ export type chatInputType = {
|
|||
export type FlowPoolObjectType = {
|
||||
timestamp: string;
|
||||
valid: boolean;
|
||||
params: any;
|
||||
// list of chat outputs or list of chat inputs
|
||||
messages: Array<ChatOutputType | chatInputType> | [];
|
||||
data: { artifacts: any; results: any | ChatOutputType | chatInputType };
|
||||
id: string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -187,7 +187,13 @@ export type FloatComponentType = {
|
|||
id?: string;
|
||||
};
|
||||
|
||||
export type FilePreviewType={loading:boolean,file:File,error:boolean,id:string,path?:string}
|
||||
export type FilePreviewType = {
|
||||
loading: boolean;
|
||||
file: File;
|
||||
error: boolean;
|
||||
id: string;
|
||||
path?: string;
|
||||
};
|
||||
|
||||
export type TooltipComponentType = {
|
||||
children: ReactElement;
|
||||
|
|
@ -475,7 +481,13 @@ export type chatInputType = {
|
|||
};
|
||||
lockChat: boolean;
|
||||
noInput: boolean;
|
||||
sendMessage: ({repeat,files}:{repeat:number,files?:string[]}) => void;
|
||||
sendMessage: ({
|
||||
repeat,
|
||||
files,
|
||||
}: {
|
||||
repeat: number;
|
||||
files?: string[];
|
||||
}) => void;
|
||||
setChatValue: (value: string) => void;
|
||||
};
|
||||
|
||||
|
|
@ -673,10 +685,14 @@ export type crashComponentPropsType = {
|
|||
resetErrorBoundary: (args) => void;
|
||||
};
|
||||
|
||||
export type Log = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
export type validationStatusType = {
|
||||
id: string;
|
||||
data: object | any;
|
||||
params: string;
|
||||
logs: Log[];
|
||||
progress?: number;
|
||||
valid: boolean;
|
||||
duration?: string;
|
||||
|
|
@ -716,7 +732,13 @@ export type IOFieldViewProps = {
|
|||
export type UndrawCardComponentProps = { flow: FlowType };
|
||||
|
||||
export type chatViewProps = {
|
||||
sendMessage: ({repeat,files}:{repeat:number,files?:string[]}) => void;
|
||||
sendMessage: ({
|
||||
repeat,
|
||||
files,
|
||||
}: {
|
||||
repeat: number;
|
||||
files?: string[];
|
||||
}) => void;
|
||||
chatValue: string;
|
||||
setChatValue: (value: string) => void;
|
||||
lockChat: boolean;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { FlowState } from "../../tabs";
|
|||
|
||||
export type chatInputType = {
|
||||
result: string;
|
||||
files?:string[];
|
||||
files?: string[];
|
||||
};
|
||||
|
||||
export type ChatOutputType = {
|
||||
|
|
@ -20,13 +20,13 @@ export type ChatOutputType = {
|
|||
sender: string;
|
||||
sender_name: string;
|
||||
stream_url?: string;
|
||||
files?:string[];
|
||||
files?: string[];
|
||||
};
|
||||
|
||||
export type FlowPoolObjectType = {
|
||||
timestamp: string;
|
||||
valid: boolean;
|
||||
params: any;
|
||||
messages: Array<ChatOutputType | chatInputType> | [];
|
||||
data: {
|
||||
artifacts: any | ChatOutputType | chatInputType;
|
||||
results: any | ChatOutputType | chatInputType;
|
||||
|
|
@ -44,7 +44,7 @@ export type FlowPoolObjectTypeNew = {
|
|||
timestamp: string;
|
||||
valid: boolean;
|
||||
data: {
|
||||
logs?:any | ChatOutputType | chatInputType;
|
||||
logs?: any | ChatOutputType | chatInputType;
|
||||
results: any | ChatOutputType | chatInputType;
|
||||
};
|
||||
duration?: string;
|
||||
|
|
@ -123,7 +123,7 @@ export type FlowStoreType = {
|
|||
startNodeId?: string;
|
||||
stopNodeId?: string;
|
||||
input_value?: string;
|
||||
files?:string[];
|
||||
files?: string[];
|
||||
}) => Promise<void>;
|
||||
getFlow: () => { nodes: Node[]; edges: Edge[]; viewport: Viewport };
|
||||
updateVerticesBuild: (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue