From f0c507a6604b87b8fb941f1117f55fca3cab1aec Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 20 Jun 2023 16:14:16 -0300 Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=90=9B=20fix(loading.py):=20include?= =?UTF-8?q?=20"config"=20in=20the=20list=20of=20keys=20to=20check=20for=20?= =?UTF-8?q?*kwargs=20=E2=9C=A8=20feat(constants.py):=20add=20default=20con?= =?UTF-8?q?fig=20for=20CTransformers=20=F0=9F=9A=80=20feat(llms.py):=20add?= =?UTF-8?q?=20method=20to=20format=20ctransformers=20field=20in=20LLMFront?= =?UTF-8?q?endNode=20The=20fix=20in=20loading.py=20ensures=20that=20the=20?= =?UTF-8?q?*kwargs=20are=20converted=20to=20a=20dictionary=20when=20the=20?= =?UTF-8?q?key=20contains=20"config".=20The=20addition=20of=20the=20defaul?= =?UTF-8?q?t=20config=20for=20CTransformers=20in=20constants.py=20provides?= =?UTF-8?q?=20a=20default=20configuration=20for=20the=20CTransformers=20mo?= =?UTF-8?q?del.=20The=20new=20method=20in=20llms.py=20formats=20the=20ctra?= =?UTF-8?q?nsformers=20field=20in=20the=20LLMFrontendNode.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/interface/loading.py | 10 ++++++++-- .../template/frontend_node/constants.py | 17 +++++++++++++++++ .../langflow/template/frontend_node/llms.py | 10 ++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/backend/langflow/interface/loading.py b/src/backend/langflow/interface/loading.py index a765d3b9b..85ace0b41 100644 --- a/src/backend/langflow/interface/loading.py +++ b/src/backend/langflow/interface/loading.py @@ -53,8 +53,8 @@ def convert_params_to_sets(params): def convert_kwargs(params): # if *kwargs are passed as a string, convert to dict - # first find any key that has kwargs in it - kwargs_keys = [key for key in params.keys() if "kwargs" in key] + # first find any key that has kwargs or config in it + kwargs_keys = [key for key in params.keys() if "kwargs" in key or "config" in key] for key in kwargs_keys: if isinstance(params[key], str): params[key] = json.loads(params[key]) @@ -82,10 +82,16 @@ def instantiate_based_on_type(class_object, base_type, node_type, params): return instantiate_utility(node_type, class_object, params) elif base_type == "chains": return instantiate_chains(node_type, class_object, params) + elif base_type == "llms": + return instantiate_llm(node_type, class_object, params) else: return class_object(**params) +def instantiate_llm(node_type, class_object, params): + return class_object(**params) + + def instantiate_chains(node_type, class_object, params): if "retriever" in params and hasattr(params["retriever"], "as_retriever"): params["retriever"] = params["retriever"].as_retriever() diff --git a/src/backend/langflow/template/frontend_node/constants.py b/src/backend/langflow/template/frontend_node/constants.py index 20b8a0c61..f9894a317 100644 --- a/src/backend/langflow/template/frontend_node/constants.py +++ b/src/backend/langflow/template/frontend_node/constants.py @@ -32,3 +32,20 @@ You are a good listener and you can talk about anything. HUMAN_PROMPT = "{input}" QA_CHAIN_TYPES = ["stuff", "map_reduce", "map_rerank", "refine"] + +CTRANSFORMERS_DEFAULT_CONFIG = { + "top_k": 40, + "top_p": 0.95, + "temperature": 0.8, + "repetition_penalty": 1.1, + "last_n_tokens": 64, + "seed": -1, + "max_new_tokens": 256, + "stop": None, + "stream": False, + "reset": True, + "batch_size": 8, + "threads": -1, + "context_length": -1, + "gpu_layers": 0, +} diff --git a/src/backend/langflow/template/frontend_node/llms.py b/src/backend/langflow/template/frontend_node/llms.py index 272e42c7f..fcd28df6c 100644 --- a/src/backend/langflow/template/frontend_node/llms.py +++ b/src/backend/langflow/template/frontend_node/llms.py @@ -1,7 +1,9 @@ +import json from typing import Optional from langflow.template.field.base import TemplateField from langflow.template.frontend_node.base import FrontendNode +from langflow.template.frontend_node.constants import CTRANSFORMERS_DEFAULT_CONFIG class LLMFrontendNode(FrontendNode): @@ -31,6 +33,13 @@ class LLMFrontendNode(FrontendNode): field.show = True field.advanced = not field.required + @staticmethod + def format_ctransformers_field(field: TemplateField): + if field.name == "config": + field.show = True + field.advanced = True + field.value = json.dumps(CTRANSFORMERS_DEFAULT_CONFIG, indent=2) + @staticmethod def format_field(field: TemplateField, name: Optional[str] = None) -> None: display_names_dict = { @@ -38,6 +47,7 @@ class LLMFrontendNode(FrontendNode): } FrontendNode.format_field(field, name) LLMFrontendNode.format_openai_field(field) + LLMFrontendNode.format_ctransformers_field(field) if name and "azure" in name.lower(): LLMFrontendNode.format_azure_field(field) if name and "llama" in name.lower(): From fc2e6c112eb8a6a5390ced06d6bebcae7585af96 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 23 Jun 2023 09:28:25 -0300 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=90=9B=20fix(chat.py):=20delete=20flo?= =?UTF-8?q?w=20from=20cache=20if=20it=20already=20exists=20before=20initia?= =?UTF-8?q?lizing=20build=20The=20code=20now=20checks=20if=20the=20flow=20?= =?UTF-8?q?already=20exists=20in=20the=20cache=20and=20deletes=20it=20befo?= =?UTF-8?q?re=20initializing=20the=20build.=20This=20ensures=20that=20the?= =?UTF-8?q?=20cache=20is=20always=20up=20to=20date=20and=20avoids=20any=20?= =?UTF-8?q?inconsistencies=20that=20may=20arise=20from=20having=20outdated?= =?UTF-8?q?=20data=20in=20the=20cache.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 262defed6..ae9fb8b30 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -39,6 +39,11 @@ async def init_build(graph_data: dict): try: flow_id = graph_data.get("id") + # Delete from cache if already exists + if flow_id in chat_manager.in_memory_cache: + with chat_manager.in_memory_cache._lock: + chat_manager.in_memory_cache.delete(flow_id) + logger.debug(f"Deleted flow {flow_id} from cache") if flow_id is None: raise ValueError("No ID provided") flow_data_store[flow_id] = graph_data From 8ccdeb9dd541a0da24788f4b1728054300c6cdcb Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 23 Jun 2023 09:54:15 -0300 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=90=9B=20fix(chat.py):=20fix=20stream?= =?UTF-8?q?=5Fbuild=20function=20to=20return=20StreamData=20objects=20inst?= =?UTF-8?q?ead=20of=20strings=20=E2=9C=A8=20feat(chat.py):=20add=20progres?= =?UTF-8?q?s=20information=20to=20the=20stream=5Fbuild=20function=20The=20?= =?UTF-8?q?stream=5Fbuild=20function=20now=20returns=20StreamData=20object?= =?UTF-8?q?s=20instead=20of=20strings,=20which=20improves=20the=20readabil?= =?UTF-8?q?ity=20of=20the=20code.=20The=20function=20also=20now=20includes?= =?UTF-8?q?=20progress=20information=20in=20the=20response,=20which=20allo?= =?UTF-8?q?ws=20the=20client=20to=20track=20the=20progress=20of=20the=20bu?= =?UTF-8?q?ild=20process.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 65 +++++++++++++++++--------- src/backend/langflow/api/v1/schemas.py | 8 ++++ 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index ae9fb8b30..a730758d2 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -1,4 +1,3 @@ -import json from fastapi import ( APIRouter, HTTPException, @@ -7,7 +6,7 @@ from fastapi import ( status, ) from fastapi.responses import StreamingResponse -from langflow.api.v1.schemas import BuiltResponse, InitResponse +from langflow.api.v1.schemas import BuiltResponse, InitResponse, StreamData from langflow.chat.manager import ChatManager from langflow.graph.graph.base import Graph @@ -39,14 +38,18 @@ async def init_build(graph_data: dict): try: flow_id = graph_data.get("id") + if flow_id is None: + raise ValueError("No ID provided") + # Check if already building + if flow_id in flow_data_store and flow_data_store[flow_id].get("building"): + return InitResponse(flowId=flow_id) + # Delete from cache if already exists if flow_id in chat_manager.in_memory_cache: with chat_manager.in_memory_cache._lock: chat_manager.in_memory_cache.delete(flow_id) logger.debug(f"Deleted flow {flow_id} from cache") - if flow_id is None: - raise ValueError("No ID provided") - flow_data_store[flow_id] = graph_data + flow_data_store[flow_id] = {"graph_data": graph_data, "building": False} return InitResponse(flowId=flow_id) except Exception as exc: @@ -76,26 +79,44 @@ async def stream_build(flow_id: str): """Stream the build process based on stored flow data.""" async def event_stream(flow_id): - final_response = json.dumps({"end_of_stream": True}) + final_response = {"end_of_stream": True} try: if flow_id not in flow_data_store: error_message = "Invalid session ID" - yield f"data: {json.dumps({'error': error_message})}\n\n" + yield str(StreamData(event="error", data={"error": error_message})) + return + + if flow_data_store[flow_id].get("building"): + error_message = "Already building" + yield str(StreamData(event="error", data={"error": error_message})) return graph_data = flow_data_store[flow_id].get("data") if not graph_data: error_message = "No data provided" - yield f"data: {json.dumps({'error': error_message})}\n\n" + yield str(StreamData(event="error", data={"error": error_message})) return logger.debug("Building langchain object") - graph = Graph.from_payload(graph_data) - for node in graph.generator_build(): + try: + # Some error could happen when building the graph + graph = Graph.from_payload(graph_data) + except Exception as exc: + logger.exception(exc) + error_message = str(exc) + yield str(StreamData(event="error", data={"error": error_message})) + return + + number_of_nodes = len(graph.nodes) + for i, vertex in enumerate(graph.generator_build(), 1): try: - node.build() - params = node._built_object_repr() + log_dict = { + "log": f"Building node {vertex.vertex_type}", + } + yield str(StreamData(event="log", data=log_dict)) + vertex.build() + params = vertex._built_object_repr() valid = True logger.debug( f"Building node {params[:50]}{'...' if len(params) > 50 else ''}" @@ -104,21 +125,21 @@ async def stream_build(flow_id: str): params = str(exc) valid = False - response = json.dumps( - { - "valid": valid, - "params": params, - "id": node.id, - } - ) - yield f"data: {response}\n\n" + response = { + "valid": valid, + "params": params, + "id": vertex.id, + "progress": round(i / number_of_nodes, 2), + } + + yield str(StreamData(event="message", data=response)) chat_manager.set_cache(flow_id, graph.build()) except Exception as exc: logger.error("Error while building the flow: %s", exc) - yield f"error: {json.dumps({'error': str(exc)})}\n\n" + yield str(StreamData(event="error", data={"error": str(exc)})) finally: - yield f"data: {final_response}\n\n" + yield str(StreamData(event="message", data=final_response)) try: return StreamingResponse(event_stream(flow_id), media_type="text/event-stream") diff --git a/src/backend/langflow/api/v1/schemas.py b/src/backend/langflow/api/v1/schemas.py index 714f0df7f..263221d75 100644 --- a/src/backend/langflow/api/v1/schemas.py +++ b/src/backend/langflow/api/v1/schemas.py @@ -101,3 +101,11 @@ class InitResponse(BaseModel): class BuiltResponse(BaseModel): built: bool + + +class StreamData(BaseModel): + event: str + data: dict + + def __str__(self) -> str: + return f"event: {self.event}\ndata: {json.dumps(self.data)}\n\n" From 5da374b71364dd2367b9914b93af90e3177e656a Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 28 Jun 2023 22:29:46 -0300 Subject: [PATCH 4/7] =?UTF-8?q?=E2=9C=A8=20feat(schemas.py):=20add=20Build?= =?UTF-8?q?Status=20enum=20to=20represent=20the=20status=20of=20a=20build?= =?UTF-8?q?=20The=20BuildStatus=20enum=20is=20added=20to=20represent=20the?= =?UTF-8?q?=20different=20statuses=20that=20a=20build=20can=20have:=20SUCC?= =?UTF-8?q?ESS,=20FAILURE,=20and=20IN=5FPROGRESS.=20This=20enum=20will=20b?= =?UTF-8?q?e=20used=20to=20provide=20a=20more=20structured=20and=20consist?= =?UTF-8?q?ent=20way=20of=20handling=20build=20statuses=20in=20the=20appli?= =?UTF-8?q?cation.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/schemas.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/backend/langflow/api/v1/schemas.py b/src/backend/langflow/api/v1/schemas.py index ed5bf8b3b..2cf62a504 100644 --- a/src/backend/langflow/api/v1/schemas.py +++ b/src/backend/langflow/api/v1/schemas.py @@ -1,3 +1,4 @@ +from enum import Enum from pathlib import Path from typing import Any, Dict, List, Optional, Union from langflow.database.models.flow import FlowCreate, FlowRead @@ -5,6 +6,14 @@ from pydantic import BaseModel, Field, validator import json +class BuildStatus(Enum): + """Status of the build.""" + + SUCCESS = "success" + FAILURE = "failure" + IN_PROGRESS = "in_progress" + + class GraphData(BaseModel): """Data inside the exported flow.""" From 48d40bfdd30abaf8c218b4c353e0d2b7f8ce819b Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 28 Jun 2023 22:29:56 -0300 Subject: [PATCH 5/7] =?UTF-8?q?=E2=9C=A8=20feat(chat.py):=20add=20status?= =?UTF-8?q?=20field=20to=20flow=5Fdata=5Fstore=20to=20track=20build=20stat?= =?UTF-8?q?us=20of=20flows=20The=20import=20statement=20for=20the=20BuildS?= =?UTF-8?q?tatus=20enum=20in=20the=20schemas=20module=20has=20been=20updat?= =?UTF-8?q?ed=20to=20ensure=20the=20correct=20import.=20Additionally,=20a?= =?UTF-8?q?=20new=20"status"=20field=20has=20been=20added=20to=20the=20flo?= =?UTF-8?q?w=5Fdata=5Fstore=20dictionary=20to=20track=20the=20build=20stat?= =?UTF-8?q?us=20of=20flows.=20The=20status=20is=20set=20to=20BuildStatus.I?= =?UTF-8?q?N=5FPROGRESS=20when=20a=20flow=20is=20being=20built,=20BuildSta?= =?UTF-8?q?tus.SUCCESS=20when=20the=20build=20is=20successful,=20and=20Bui?= =?UTF-8?q?ldStatus.FAILURE=20when=20there=20is=20an=20error=20during=20th?= =?UTF-8?q?e=20build=20process.=20This=20allows=20for=20better=20tracking?= =?UTF-8?q?=20and=20management=20of=20flow=20builds.=20=F0=9F=90=9B=20fix(?= =?UTF-8?q?chat.py):=20change=20import=20statement=20for=20BuildStatus=20i?= =?UTF-8?q?n=20schemas=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index a730758d2..b992afe9a 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -6,7 +6,7 @@ from fastapi import ( status, ) from fastapi.responses import StreamingResponse -from langflow.api.v1.schemas import BuiltResponse, InitResponse, StreamData +from langflow.api.v1.schemas import BuildStatus, BuiltResponse, InitResponse, StreamData from langflow.chat.manager import ChatManager from langflow.graph.graph.base import Graph @@ -49,7 +49,10 @@ async def init_build(graph_data: dict): with chat_manager.in_memory_cache._lock: chat_manager.in_memory_cache.delete(flow_id) logger.debug(f"Deleted flow {flow_id} from cache") - flow_data_store[flow_id] = {"graph_data": graph_data, "building": False} + flow_data_store[flow_id] = { + "graph_data": graph_data, + "status": BuildStatus.IN_PROGRESS, + } return InitResponse(flowId=flow_id) except Exception as exc: @@ -61,8 +64,9 @@ async def init_build(graph_data: dict): async def build_status(flow_id: str): """Check the flow_id is in the flow_data_store.""" try: - built = flow_id in flow_data_store and not isinstance( - flow_data_store[flow_id], dict + built = ( + flow_id in flow_data_store + and flow_data_store[flow_id]["status"] == BuildStatus.SUCCESS ) return BuiltResponse( @@ -86,7 +90,7 @@ async def stream_build(flow_id: str): yield str(StreamData(event="error", data={"error": error_message})) return - if flow_data_store[flow_id].get("building"): + if flow_data_store[flow_id].get("status") == BuildStatus.IN_PROGRESS: error_message = "Already building" yield str(StreamData(event="error", data={"error": error_message})) return @@ -124,6 +128,7 @@ async def stream_build(flow_id: str): except Exception as exc: params = str(exc) valid = False + flow_data_store[flow_id]["status"] = BuildStatus.FAILURE response = { "valid": valid, @@ -135,8 +140,10 @@ async def stream_build(flow_id: str): yield str(StreamData(event="message", data=response)) chat_manager.set_cache(flow_id, graph.build()) + flow_data_store[flow_id]["status"] = BuildStatus.SUCCESS except Exception as exc: logger.error("Error while building the flow: %s", exc) + flow_data_store[flow_id]["status"] = BuildStatus.FAILURE yield str(StreamData(event="error", data={"error": str(exc)})) finally: yield str(StreamData(event="message", data=final_response)) From 85b7ff1d31ef6f17c54a47c23ce2d8b7785f65b8 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 28 Jun 2023 22:45:37 -0300 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=94=A7=20chore(chat.py):=20update=20i?= =?UTF-8?q?nit=5Fbuild=20endpoint=20to=20include=20flow=5Fid=20as=20a=20pa?= =?UTF-8?q?th=20parameter=20The=20unnecessary=20imports=20have=20been=20re?= =?UTF-8?q?moved=20from=20the=20chat.py=20file=20to=20improve=20code=20cle?= =?UTF-8?q?anliness=20and=20readability.=20The=20init=5Fbuild=20endpoint?= =?UTF-8?q?=20in=20the=20chat.py=20file=20has=20been=20updated=20to=20incl?= =?UTF-8?q?ude=20the=20flow=5Fid=20as=20a=20path=20parameter=20instead=20o?= =?UTF-8?q?f=20extracting=20it=20from=20the=20graph=5Fdata=20dictionary.?= =?UTF-8?q?=20This=20change=20allows=20for=20a=20more=20explicit=20and=20c?= =?UTF-8?q?onsistent=20API=20design.=20=F0=9F=94=A7=20chore(chat.py):=20re?= =?UTF-8?q?move=20unnecessary=20imports=20and=20reformat=20code=20for=20be?= =?UTF-8?q?tter=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 18 +++++++----------- src/frontend/src/controllers/API/index.ts | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index b992afe9a..fd0232189 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -1,10 +1,4 @@ -from fastapi import ( - APIRouter, - HTTPException, - WebSocket, - WebSocketException, - status, -) +from fastapi import APIRouter, HTTPException, WebSocket, WebSocketException, status from fastapi.responses import StreamingResponse from langflow.api.v1.schemas import BuildStatus, BuiltResponse, InitResponse, StreamData @@ -32,16 +26,18 @@ async def chat(client_id: str, websocket: WebSocket): await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) -@router.post("/build/init", response_model=InitResponse, status_code=201) -async def init_build(graph_data: dict): +@router.post("/build/init/{flow_id}", response_model=InitResponse, status_code=201) +async def init_build(graph_data: dict, flow_id: str): """Initialize the build by storing graph data and returning a unique session ID.""" try: - flow_id = graph_data.get("id") if flow_id is None: raise ValueError("No ID provided") # Check if already building - if flow_id in flow_data_store and flow_data_store[flow_id].get("building"): + if ( + flow_id in flow_data_store + and flow_data_store[flow_id]["status"] == BuildStatus.IN_PROGRESS + ): return InitResponse(flowId=flow_id) # Delete from cache if already exists diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 2651a0058..cfae748d8 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -311,7 +311,7 @@ export async function getBuildStatus( export async function postBuildInit( flow: FlowType ): Promise> { - return await axios.post(`/api/v1/build/init`, flow); + return await axios.post(`/api/v1/build/init/${flow.id}`, flow); } // fetch(`/upload/${id}`, { From ce34ac4825449584bd937c72732f7cdcbff7a4d4 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 28 Jun 2023 22:50:55 -0300 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=90=9B=20fix(test=5Fwebsocket.py):=20?= =?UTF-8?q?fix=20the=20endpoint=20URL=20in=20the=20test=5Finit=5Fbuild=20t?= =?UTF-8?q?est=20The=20endpoint=20URL=20in=20the=20test=5Finit=5Fbuild=20t?= =?UTF-8?q?est=20has=20been=20fixed=20to=20"api/v1/build/init/test"=20to?= =?UTF-8?q?=20match=20the=20correct=20URL=20pattern.=20This=20ensures=20th?= =?UTF-8?q?at=20the=20test=20is=20accurately=20testing=20the=20intended=20?= =?UTF-8?q?functionality.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_websocket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_websocket.py b/tests/test_websocket.py index f571671e8..0199ff14b 100644 --- a/tests/test_websocket.py +++ b/tests/test_websocket.py @@ -7,7 +7,7 @@ import pytest def test_init_build(client): response = client.post( - "api/v1/build/init", json={"id": "test", "data": {"key": "value"}} + "api/v1/build/init/test", json={"id": "test", "data": {"key": "value"}} ) assert response.status_code == 201 assert response.json() == {"flowId": "test"}