merge dev into two_edges

This commit is contained in:
cristhianzl 2024-06-17 10:01:28 -03:00
commit fcf4512210
133 changed files with 2534 additions and 1507 deletions

View file

@ -184,7 +184,7 @@ async def build_vertex(
result_data_response = ResultDataResponse.model_validate(result_dict, from_attributes=True)
except Exception as exc:
logger.exception(f"Error building vertex: {exc}")
logger.exception(f"Error building Component: {exc}")
params = format_exception_message(exc)
valid = False
output_label = vertex.outputs[0]["name"] if vertex.outputs else "output"
@ -241,7 +241,7 @@ async def build_vertex(
)
return build_response
except Exception as exc:
logger.error(f"Error building vertex: {exc}")
logger.error(f"Error building Component: {exc}")
logger.exception(exc)
message = parse_exception(exc)
raise HTTPException(status_code=500, detail=message) from exc
@ -336,7 +336,7 @@ async def build_vertex_stream(
raise ValueError(f"No result found for vertex {vertex_id}")
except Exception as exc:
logger.exception(f"Error building vertex: {exc}")
logger.exception(f"Error building Component: {exc}")
exc_message = parse_exception(exc)
if exc_message == "The message must be an iterator or an async iterator.":
exc_message = "This stream has already been closed."
@ -347,4 +347,4 @@ async def build_vertex_stream(
return StreamingResponse(stream_vertex(), media_type="text/event-stream")
except Exception as exc:
raise HTTPException(status_code=500, detail="Error building vertex") from exc
raise HTTPException(status_code=500, detail="Error building Component") from exc

View file

@ -5,9 +5,6 @@ from uuid import UUID
import sqlalchemy as sa
from fastapi import APIRouter, BackgroundTasks, Body, Depends, HTTPException, Request, UploadFile, status
from loguru import logger
from sqlmodel import Session, select
from langflow.api.utils import update_frontend_node_with_template_values
from langflow.api.v1.schemas import (
ConfigResponse,
@ -41,6 +38,8 @@ from langflow.services.deps import (
)
from langflow.services.session.service import SessionService
from langflow.services.task.service import TaskService
from loguru import logger
from sqlmodel import Session, select
if TYPE_CHECKING:
from langflow.services.cache.base import CacheService
@ -71,29 +70,20 @@ async def get_all(
async def simple_run_flow(
db: Session,
flow: Flow,
input_request: SimplifiedAPIRequest,
session_service: SessionService,
stream: bool = False,
api_key_user: Optional[User] = None,
):
try:
task_result: List[RunOutputs] = []
artifacts = {}
user_id = api_key_user.id if api_key_user else None
flow_id_str = str(flow.id)
if input_request.session_id:
session_data = await session_service.load_session(input_request.session_id, flow_id=flow_id_str)
graph, artifacts = session_data if session_data else (None, None)
if graph is None:
raise ValueError(f"Session {input_request.session_id} not found")
else:
if flow.data is None:
raise ValueError(f"Flow {flow_id_str} has no data")
graph_data = flow.data
graph_data = process_tweaks(graph_data, input_request.tweaks or {}, stream=stream)
graph = Graph.from_payload(graph_data, flow_id=flow_id_str, user_id=str(user_id))
if flow.data is None:
raise ValueError(f"Flow {flow_id_str} has no data")
graph_data = flow.data.copy()
graph_data = process_tweaks(graph_data, input_request.tweaks or {}, stream=stream)
graph = Graph.from_payload(graph_data, flow_id=flow_id_str, user_id=str(user_id))
inputs = [
InputValueRequest(components=[], input_value=input_request.input_value, type=input_request.input_type)
]
@ -115,8 +105,6 @@ async def simple_run_flow(
session_id=input_request.session_id,
inputs=inputs,
outputs=outputs,
artifacts=artifacts,
session_service=session_service,
stream=stream,
)
@ -189,10 +177,8 @@ async def simplified_run_flow(
"""
try:
return await simple_run_flow(
db=db,
flow=flow,
input_request=input_request,
session_service=session_service,
stream=stream,
api_key_user=api_key_user,
)
@ -263,7 +249,6 @@ async def webhook_run_flow(
db=db,
flow=flow,
input_request=input_request,
session_service=session_service,
)
return {"message": "Task started in the background", "status": "in progress"}
except Exception as exc:
@ -542,3 +527,4 @@ def get_config():
except Exception as exc:
logger.exception(exc)
raise HTTPException(status_code=500, detail=str(exc)) from exc
raise HTTPException(status_code=500, detail=str(exc)) from exc

View file

@ -1,5 +1,7 @@
from typing import List
from loguru import logger
from langflow.graph.schema import ResultData, RunOutputs
from langflow.schema import Data
@ -37,9 +39,32 @@ def build_data_from_result_data(result_data: ResultData, get_final_results_only:
"""
messages = result_data.messages
if not messages:
return []
data = []
# Handle results without chat messages (calling flow)
if not messages:
# Result with a single record
if isinstance(result_data.artifacts, dict):
data.append(Data(data=result_data.artifacts))
# List of artifacts
elif isinstance(result_data.artifacts, list):
for artifact in result_data.artifacts:
# If multiple records are found as artifacts, return as-is
if isinstance(artifact, Data):
data.append(artifact)
else:
# Warn about unknown output type
logger.warning(f"Unable to build record output from unknown ResultData.artifact: {str(artifact)}")
# Chat or text output
elif result_data.results:
data.append(Data(data={"result": result_data.results}, text_key="result"))
return data
else:
return []
for message in messages:
message_dict = message if isinstance(message, dict) else message.model_dump()
if get_final_results_only:

View file

@ -89,6 +89,7 @@ class AstraDBMessageWriterComponent(BaseMemoryComponent):
sender_name=sender_name,
metadata=metadata,
session_id=session_id,
type=sender,
)
]

View file

@ -164,4 +164,3 @@ class AstraDBVectorStoreComponent(CustomComponent):
)
return vector_store
return vector_store

View file

@ -21,6 +21,7 @@ from langflow.type_extraction.type_extraction import (
extract_union_types_from_generic_alias,
)
from langflow.utils import validate
from pydantic import BaseModel
if TYPE_CHECKING:
from langflow.graph.graph.base import Graph

View file

@ -5,8 +5,6 @@ from functools import partial
from itertools import chain
from typing import TYPE_CHECKING, Callable, Coroutine, Dict, Generator, List, Optional, Tuple, Type, Union
from loguru import logger
from langflow.graph.edge.base import ContractEdge
from langflow.graph.graph.constants import lazy_load_vertex_dict
from langflow.graph.graph.runnable_vertices_manager import RunnableVerticesManager
@ -21,6 +19,7 @@ from langflow.services.cache.utils import CacheMiss
from langflow.services.chat.service import ChatService
from langflow.services.deps import get_chat_service
from langflow.services.monitor.utils import log_transaction
from loguru import logger
if TYPE_CHECKING:
from langflow.graph.schema import ResultData
@ -729,6 +728,7 @@ class Graph:
files: Optional[list[str]] = None,
user_id: Optional[str] = None,
fallback_to_env_vars: bool = False,
cache: bool = True,
):
"""
Builds a vertex in the graph.
@ -784,19 +784,23 @@ class Graph:
raise ValueError(f"No result found for vertex {vertex_id}")
set_cache_coro = partial(chat_service.set_cache, key=self.flow_id)
next_runnable_vertices, top_level_vertices = await self.get_next_and_top_level_vertices(
lock, set_cache_coro, vertex
lock, set_cache_coro, vertex, cache=cache
)
flow_id = self.flow_id
log_transaction(flow_id, vertex, status="success")
return next_runnable_vertices, top_level_vertices, result_dict, params, valid, artifacts, vertex
except Exception as exc:
logger.exception(f"Error building vertex: {exc}")
logger.exception(f"Error building Component: {exc}")
flow_id = self.flow_id
log_transaction(flow_id, vertex, status="failure", error=str(exc))
raise exc
async def get_next_and_top_level_vertices(
self, lock: asyncio.Lock, set_cache_coro: Callable[["Graph", asyncio.Lock], Coroutine], vertex: Vertex
self,
lock: asyncio.Lock,
set_cache_coro: Callable[["Graph", asyncio.Lock], Coroutine],
vertex: Vertex,
cache: bool = True,
):
"""
Retrieves the next runnable vertices and the top level vertices for a given vertex.
@ -809,7 +813,9 @@ class Graph:
Returns:
Tuple[List[Vertex], List[Vertex]]: A tuple containing the next runnable vertices and the top level vertices.
"""
next_runnable_vertices = await self.run_manager.get_next_runnable_vertices(lock, set_cache_coro, self, vertex)
next_runnable_vertices = await self.run_manager.get_next_runnable_vertices(
lock, set_cache_coro, self, vertex, cache=cache
)
top_level_vertices = self.run_manager.get_top_level_vertices(self, next_runnable_vertices)
return next_runnable_vertices, top_level_vertices
@ -850,13 +856,13 @@ class Graph:
chat_service = get_chat_service()
run_id = uuid.uuid4()
self.set_run_id(run_id)
lock = chat_service._cache_locks[self.run_id]
while to_process:
current_batch = list(to_process) # Copy current deque items to a list
to_process.clear() # Clear the deque for new items
tasks = []
for vertex_id in current_batch:
vertex = self.get_vertex(vertex_id)
lock = chat_service._cache_locks[self.run_id]
task = asyncio.create_task(
self.build_vertex(
lock=lock,
@ -865,6 +871,7 @@ class Graph:
user_id=self.user_id,
inputs_dict={},
fallback_to_env_vars=fallback_to_env_vars,
cache=False,
),
name=f"{vertex.display_name} Run {vertex_task_run_count.get(vertex_id, 0)}",
)
@ -872,8 +879,15 @@ class Graph:
vertex_task_run_count[vertex_id] = vertex_task_run_count.get(vertex_id, 0) + 1
logger.debug(f"Running layer {layer_index} with {len(tasks)} tasks")
next_runnable_vertices = await self._execute_tasks(tasks)
try:
next_runnable_vertices = await self._execute_tasks(tasks)
except Exception as e:
logger.error(f"Error executing tasks in layer {layer_index}: {e}")
break
if not next_runnable_vertices:
break
to_process.extend(next_runnable_vertices)
layer_index += 1
logger.debug("Graph processing complete")
return self
@ -881,25 +895,23 @@ class Graph:
async def _execute_tasks(self, tasks: List[asyncio.Task]) -> List[str]:
"""Executes tasks in parallel, handling exceptions for each task."""
results = []
for i, task in enumerate(asyncio.as_completed(tasks)):
try:
result = await task
if isinstance(result, tuple) and len(result) == 7:
# Get the next runnable vertices
next_runnable_vertices = result[0]
results.extend(next_runnable_vertices)
else:
raise ValueError(f"Invalid result: {result}")
except Exception as e:
# Log the exception along with the task name for easier debugging
# task_name = task.get_name()
# coroutine has not attribute get_name
task_name = tasks[i].get_name()
logger.error(f"Task {task_name} failed with exception: {e}")
completed_tasks = await asyncio.gather(*tasks, return_exceptions=True)
for i, result in enumerate(completed_tasks):
task_name = tasks[i].get_name()
if isinstance(result, Exception):
logger.error(f"Task {task_name} failed with exception: {result}")
# Cancel all remaining tasks
for t in tasks[i:]:
for t in tasks[i + 1 :]:
t.cancel()
raise e
raise result
elif isinstance(result, tuple) and len(result) == 7:
# Get the next runnable vertices
next_runnable_vertices = result[0]
results.extend(next_runnable_vertices)
else:
raise ValueError(f"Invalid result from task {task_name}: {result}")
return results
def topological_sort(self) -> List[Vertex]:
@ -1377,3 +1389,5 @@ class Graph:
predecessor_map[edge.target_id].append(edge.source_id)
successor_map[edge.source_id].append(edge.target_id)
return predecessor_map, successor_map
return predecessor_map, successor_map
return predecessor_map, successor_map

View file

@ -59,6 +59,7 @@ class RunnableVerticesManager:
set_cache_coro: Callable[["Graph", asyncio.Lock], Awaitable[None]],
graph: "Graph",
vertex: "Vertex",
cache: bool = True,
):
"""
Retrieves the next runnable vertices in the graph for a given vertex.
@ -86,7 +87,8 @@ class RunnableVerticesManager:
for v_id in set(next_runnable_vertices): # Use set to avoid duplicates
self.update_vertex_run_state(v_id, is_runnable=False)
self.remove_from_predecessors(v_id)
await set_cache_coro(data=graph, lock=lock) # type: ignore
if cache:
await set_cache_coro(data=graph, lock=lock) # type: ignore
return next_runnable_vertices
@staticmethod

View file

@ -73,6 +73,7 @@ INPUT_COMPONENTS = [
OUTPUT_COMPONENTS = [
InterfaceComponentTypes.ChatOutput,
InterfaceComponentTypes.TextOutput,
InterfaceComponentTypes.DataOutput,
]

View file

@ -8,12 +8,16 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-k39HS",
"name": "text_output",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-njtka",
"inputTypes": ["Text", "Message"],
"inputTypes": [
"Text"
],
"type": "str"
}
},
@ -24,7 +28,7 @@
"stroke": "#555"
},
"target": "ChatOutput-njtka",
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-njtkaœ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-njtkaœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
},
{
"className": "stroke-gray-900 stroke-connection",
@ -33,12 +37,18 @@
"dataType": "Prompt",
"id": "Prompt-uxBqP",
"name": "prompt",
"output_types": ["Prompt"]
"output_types": [
"Prompt"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-k39HS",
"inputTypes": ["Text", "Data", "Prompt"],
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"type": "str"
}
},
@ -58,12 +68,19 @@
"dataType": "ChatInput",
"id": "ChatInput-P3fgL",
"name": "message",
"output_types": ["Message"]
"output_types": [
"Message"
]
},
"targetHandle": {
"fieldName": "user_input",
"id": "Prompt-uxBqP",
"inputTypes": ["Document", "Message", "Record", "Text"],
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"type": "str"
}
},
@ -84,10 +101,16 @@
"display_name": "Prompt",
"id": "Prompt-uxBqP",
"node": {
"base_classes": ["object", "str", "Text"],
"base_classes": [
"object",
"str",
"Text"
],
"beta": false,
"custom_fields": {
"template": ["user_input"]
"template": [
"user_input"
]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -110,7 +133,9 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": ["Prompt"],
"types": [
"Prompt"
],
"value": "__UNDEFINED__"
},
{
@ -119,7 +144,9 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -150,7 +177,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -171,7 +200,12 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Document", "Message", "Record", "Text"],
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -209,7 +243,11 @@
"display_name": "OpenAI",
"id": "OpenAIModel-k39HS",
"node": {
"base_classes": ["object", "Text", "str"],
"base_classes": [
"object",
"Text",
"str"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -247,7 +285,9 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
},
{
@ -256,7 +296,9 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": ["BaseLanguageModel"],
"types": [
"BaseLanguageModel"
],
"value": "__UNDEFINED__"
}
],
@ -278,7 +320,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, SecretStrInput, StrInput\nfrom langflow.template import Output\n\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n info=\"Enable JSON mode for the model output.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n response_format = None\n if json_mode:\n response_format = {\"type\": \"json_object\"}\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n response_format=response_format,\n seed=seed,\n )\n\n return output\n"
},
"input_value": {
"advanced": false,
@ -287,7 +329,11 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text", "Data", "Prompt"],
"input_types": [
"Text",
"Data",
"Prompt"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -307,7 +353,9 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -327,7 +375,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -347,7 +397,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
@ -373,8 +425,10 @@
"dynamic": false,
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": ["Text"],
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -394,7 +448,9 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": true,
"multiline": false,
@ -414,7 +470,9 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -434,7 +492,9 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -454,7 +514,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -490,7 +552,12 @@
"data": {
"id": "ChatOutput-njtka",
"node": {
"base_classes": ["Record", "Text", "str", "object"],
"base_classes": [
"Record",
"Text",
"str",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -515,7 +582,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -537,7 +617,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.inputs import BoolInput, DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -546,7 +626,9 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": ["Text", "Message"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -566,12 +648,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -587,7 +674,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -607,7 +696,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -643,7 +734,12 @@
"data": {
"id": "ChatInput-P3fgL",
"node": {
"base_classes": ["object", "Record", "str", "Text"],
"base_classes": [
"object",
"Record",
"str",
"Text"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -667,7 +763,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -689,7 +798,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n StrInput(\n name=\"sender_name\",\n type=str,\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n StrInput(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\nfrom langflow.field_typing import Text\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n StrInput(\n name=\"sender_name\",\n type=str,\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n StrInput(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -718,12 +827,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -739,7 +853,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -759,7 +875,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -803,4 +921,4 @@
"is_component": false,
"last_tested_version": "1.0.0a4",
"name": "Basic Prompting (Hello, World)"
}
}

View file

@ -13,7 +13,12 @@
"targetHandle": {
"fieldName": "reference_2",
"id": "Prompt-Rse03",
"inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
"inputTypes": [
"Document",
"BaseOutputParser",
"Record",
"Text"
],
"type": "str"
}
},
@ -34,12 +39,16 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-gi29P",
"name": "text_output",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-JPlxl",
"inputTypes": ["Text", "Message"],
"inputTypes": [
"Text"
],
"type": "str"
}
},
@ -50,7 +59,7 @@
"stroke": "#555"
},
"target": "ChatOutput-JPlxl",
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-JPlxlœ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-JPlxlœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
},
{
"className": "stroke-gray-900 stroke-connection",
@ -64,7 +73,12 @@
"targetHandle": {
"fieldName": "reference_1",
"id": "Prompt-Rse03",
"inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
"inputTypes": [
"Document",
"BaseOutputParser",
"Record",
"Text"
],
"type": "str"
}
},
@ -84,12 +98,19 @@
"dataType": "TextInput",
"id": "TextInput-og8Or",
"name": "Text",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "instructions",
"id": "Prompt-Rse03",
"inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
"inputTypes": [
"Document",
"BaseOutputParser",
"Record",
"Text"
],
"type": "str"
}
},
@ -109,12 +130,18 @@
"dataType": "Prompt",
"id": "Prompt-Rse03",
"name": "prompt",
"output_types": ["Prompt"]
"output_types": [
"Prompt"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-gi29P",
"inputTypes": ["Text", "Data", "Prompt"],
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"type": "str"
}
},
@ -136,10 +163,18 @@
"display_name": "Prompt",
"id": "Prompt-Rse03",
"node": {
"base_classes": ["object", "Text", "str"],
"base_classes": [
"object",
"Text",
"str"
],
"beta": false,
"custom_fields": {
"template": ["reference_1", "reference_2", "instructions"]
"template": [
"reference_1",
"reference_2",
"instructions"
]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -162,7 +197,9 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": ["Prompt"],
"types": [
"Prompt"
],
"value": "__UNDEFINED__"
},
{
@ -171,7 +208,9 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -280,7 +319,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -316,7 +357,9 @@
"data": {
"id": "URL-HYPkR",
"node": {
"base_classes": ["Record"],
"base_classes": [
"Record"
],
"beta": false,
"custom_fields": {
"urls": null
@ -336,7 +379,9 @@
"method": "fetch_content",
"name": "data",
"selected": "Data",
"types": ["Data"],
"types": [
"Data"
],
"value": "__UNDEFINED__"
}
],
@ -358,7 +403,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\nimport re\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(http://|https://)?\" # http:// or https://\n r\"(([a-zA-Z0-9\\.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,}))\" # top-level domain\n r\"(:[0-9]{1,5})?\" # optional port\n r\"(\\/.*)?$\" # optional path\n )\n\n if not re.match(url_regex, string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> Data:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls)\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\nimport re\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(http://|https://)?\" # http:// or https://\n r\"(([a-zA-Z0-9\\.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,}))\" # top-level domain\n r\"(:[0-9]{1,5})?\" # optional port\n r\"(\\/.*)?$\" # optional path\n )\n\n if not re.match(url_regex, string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> Data:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
},
"urls": {
"advanced": false,
@ -398,7 +443,12 @@
"data": {
"id": "ChatOutput-JPlxl",
"node": {
"base_classes": ["Text", "Record", "object", "str"],
"base_classes": [
"Text",
"Record",
"object",
"str"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -423,7 +473,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -445,7 +508,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.inputs import BoolInput, DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -454,7 +517,9 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": ["Text", "Message"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -474,12 +539,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -495,7 +565,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -515,7 +587,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -546,7 +620,11 @@
"data": {
"id": "OpenAIModel-gi29P",
"node": {
"base_classes": ["str", "Text", "object"],
"base_classes": [
"str",
"Text",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -584,7 +662,9 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
},
{
@ -593,7 +673,9 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": ["BaseLanguageModel"],
"types": [
"BaseLanguageModel"
],
"value": "__UNDEFINED__"
}
],
@ -615,7 +697,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, SecretStrInput, StrInput\nfrom langflow.template import Output\n\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n info=\"Enable JSON mode for the model output.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n response_format = None\n if json_mode:\n response_format = {\"type\": \"json_object\"}\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n response_format=response_format,\n seed=seed,\n )\n\n return output\n"
},
"input_value": {
"advanced": false,
@ -624,7 +706,11 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text", "Data", "Prompt"],
"input_types": [
"Text",
"Data",
"Prompt"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -644,7 +730,9 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -664,7 +752,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -684,7 +774,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
@ -710,8 +802,10 @@
"dynamic": false,
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": ["Text"],
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -731,7 +825,9 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": true,
"multiline": false,
@ -751,7 +847,9 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -771,7 +869,9 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -791,7 +891,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -827,7 +929,9 @@
"data": {
"id": "URL-2cX90",
"node": {
"base_classes": ["Record"],
"base_classes": [
"Record"
],
"beta": false,
"custom_fields": {
"urls": null
@ -847,7 +951,9 @@
"method": "fetch_content",
"name": "data",
"selected": "Data",
"types": ["Data"],
"types": [
"Data"
],
"value": "__UNDEFINED__"
}
],
@ -869,7 +975,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\nimport re\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(http://|https://)?\" # http:// or https://\n r\"(([a-zA-Z0-9\\.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,}))\" # top-level domain\n r\"(:[0-9]{1,5})?\" # optional port\n r\"(\\/.*)?$\" # optional path\n )\n\n if not re.match(url_regex, string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> Data:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls)\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\nimport re\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(http://|https://)?\" # http:// or https://\n r\"(([a-zA-Z0-9\\.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,}))\" # top-level domain\n r\"(:[0-9]{1,5})?\" # optional port\n r\"(\\/.*)?$\" # optional path\n )\n\n if not re.match(url_regex, string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> Data:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
},
"urls": {
"advanced": false,
@ -909,7 +1015,11 @@
"data": {
"id": "TextInput-og8Or",
"node": {
"base_classes": ["object", "Text", "str"],
"base_classes": [
"object",
"Text",
"str"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -922,12 +1032,16 @@
"field_order": [],
"frozen": false,
"icon": "type",
"output_types": ["Text"],
"output_types": [
"Text"
],
"outputs": [
{
"name": "Text",
"selected": "Text",
"types": ["Text"]
"types": [
"Text"
]
}
],
"template": {
@ -957,7 +1071,10 @@
"fileTypes": [],
"file_path": "",
"info": "Text or Record to be passed as input.",
"input_types": ["Record", "Text"],
"input_types": [
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -977,7 +1094,9 @@
"fileTypes": [],
"file_path": "",
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1021,4 +1140,4 @@
"is_component": false,
"last_tested_version": "1.0.0a0",
"name": "Blog Writer"
}
}

View file

@ -7,12 +7,19 @@
"dataType": "File",
"id": "File-BzIs2",
"name": "data",
"output_types": ["Data"]
"output_types": [
"Data"
]
},
"targetHandle": {
"fieldName": "Document",
"id": "Prompt-9DNZG",
"inputTypes": ["Document", "Message", "Data", "Text"],
"inputTypes": [
"Document",
"Message",
"Data",
"Text"
],
"type": "str"
}
},
@ -28,12 +35,19 @@
"dataType": "ChatInput",
"id": "ChatInput-27Usy",
"name": "message",
"output_types": ["Message"]
"output_types": [
"Message"
]
},
"targetHandle": {
"fieldName": "Question",
"id": "Prompt-9DNZG",
"inputTypes": ["Document", "Message", "Data", "Text"],
"inputTypes": [
"Document",
"Message",
"Data",
"Text"
],
"type": "str"
}
},
@ -49,12 +63,18 @@
"dataType": "Prompt",
"id": "Prompt-9DNZG",
"name": "prompt",
"output_types": ["Prompt"]
"output_types": [
"Prompt"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-8b6nG",
"inputTypes": ["Text", "Data", "Prompt"],
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"type": "str"
}
},
@ -70,12 +90,16 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-8b6nG",
"name": "text_output",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-y4SCS",
"inputTypes": ["Text", "Message"],
"inputTypes": [
"Text"
],
"type": "str"
}
},
@ -83,7 +107,7 @@
"source": "OpenAIModel-8b6nG",
"sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-8b6nGœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œTextœ]}",
"target": "ChatOutput-y4SCS",
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-y4SCSœ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-y4SCSœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
}
],
"nodes": [
@ -93,11 +117,18 @@
"display_name": "Prompt",
"id": "Prompt-9DNZG",
"node": {
"base_classes": ["object", "str", "Text"],
"base_classes": [
"object",
"str",
"Text"
],
"beta": false,
"conditional_paths": [],
"custom_fields": {
"template": ["Document", "Question"]
"template": [
"Document",
"Question"
]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -119,7 +150,9 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": ["Prompt"],
"types": [
"Prompt"
],
"value": "__UNDEFINED__"
},
{
@ -128,7 +161,9 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -142,7 +177,12 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Document", "Message", "Data", "Text"],
"input_types": [
"Document",
"Message",
"Data",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -163,7 +203,12 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Document", "Message", "Data", "Text"],
"input_types": [
"Document",
"Message",
"Data",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -202,7 +247,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -238,7 +285,12 @@
"data": {
"id": "ChatInput-27Usy",
"node": {
"base_classes": ["str", "Record", "Text", "object"],
"base_classes": [
"str",
"Record",
"Text",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -262,7 +314,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -284,7 +349,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n StrInput(\n name=\"sender_name\",\n type=str,\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n StrInput(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\nfrom langflow.field_typing import Text\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n StrInput(\n name=\"sender_name\",\n type=str,\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n StrInput(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -313,12 +378,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -334,7 +404,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -354,7 +426,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -390,7 +464,12 @@
"data": {
"id": "ChatOutput-y4SCS",
"node": {
"base_classes": ["str", "Record", "Text", "object"],
"base_classes": [
"str",
"Record",
"Text",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -414,7 +493,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -436,7 +528,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.inputs import BoolInput, DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -445,7 +537,9 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": ["Text", "Message"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -465,12 +559,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -486,7 +585,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -506,7 +607,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -544,7 +647,9 @@
"display_name": "File",
"id": "File-BzIs2",
"node": {
"base_classes": ["Data"],
"base_classes": [
"Data"
],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -552,7 +657,10 @@
"display_name": "File",
"documentation": "",
"edited": true,
"field_order": ["path", "silent_errors"],
"field_order": [
"path",
"silent_errors"
],
"frozen": false,
"icon": "file-text",
"output_types": [],
@ -563,7 +671,9 @@
"method": "load_file",
"name": "data",
"selected": "Data",
"types": ["Data"],
"types": [
"Data"
],
"value": "__UNDEFINED__"
}
],
@ -660,7 +770,10 @@
"data": {
"id": "OpenAIModel-8b6nG",
"node": {
"base_classes": ["BaseLanguageModel", "Text"],
"base_classes": [
"BaseLanguageModel",
"Text"
],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -688,7 +801,9 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
},
{
@ -697,7 +812,9 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": ["BaseLanguageModel"],
"types": [
"BaseLanguageModel"
],
"value": "__UNDEFINED__"
}
],
@ -720,14 +837,18 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, SecretStrInput, StrInput\nfrom langflow.template import Output\n\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n info=\"Enable JSON mode for the model output.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n response_format = None\n if json_mode:\n response_format = {\"type\": \"json_object\"}\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n response_format=response_format,\n seed=seed,\n )\n\n return output\n"
},
"input_value": {
"advanced": false,
"display_name": "Input",
"dynamic": false,
"info": "",
"input_types": ["Text", "Data", "Prompt"],
"input_types": [
"Text",
"Data",
"Prompt"
],
"list": false,
"load_from_db": false,
"name": "input_value",
@ -788,7 +909,7 @@
"advanced": true,
"display_name": "OpenAI API Base",
"dynamic": false,
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.",
"list": false,
"load_from_db": false,
"name": "openai_api_base",
@ -804,7 +925,9 @@
"display_name": "OpenAI API Key",
"dynamic": false,
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"load_from_db": true,
"name": "openai_api_key",
"password": true,
@ -889,4 +1012,4 @@
"is_component": false,
"last_tested_version": "1.0.0a52",
"name": "Document QA"
}
}

View file

@ -8,12 +8,19 @@
"dataType": "MemoryComponent",
"id": "MemoryComponent-cdA1J",
"name": "text",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "context",
"id": "Prompt-ODkUx",
"inputTypes": ["Document", "Message", "Record", "Text"],
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"type": "str"
}
},
@ -34,12 +41,19 @@
"dataType": "ChatInput",
"id": "ChatInput-t7F8v",
"name": "message",
"output_types": ["Message"]
"output_types": [
"Message"
]
},
"targetHandle": {
"fieldName": "user_message",
"id": "Prompt-ODkUx",
"inputTypes": ["Document", "Message", "Record", "Text"],
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"type": "str"
}
},
@ -60,12 +74,18 @@
"dataType": "Prompt",
"id": "Prompt-ODkUx",
"name": "prompt",
"output_types": ["Prompt"]
"output_types": [
"Prompt"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-9RykF",
"inputTypes": ["Text", "Data", "Prompt"],
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"type": "str"
}
},
@ -85,12 +105,16 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-9RykF",
"name": "text_output",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-P1jEe",
"inputTypes": ["Text", "Message"],
"inputTypes": [
"Text"
],
"type": "str"
}
},
@ -101,7 +125,7 @@
"stroke": "#555"
},
"target": "ChatOutput-P1jEe",
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-P1jEeœ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-P1jEeœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
},
{
"className": "stroke-foreground stroke-connection",
@ -110,12 +134,17 @@
"dataType": "MemoryComponent",
"id": "MemoryComponent-cdA1J",
"name": "text",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "TextOutput-vrs6T",
"inputTypes": ["Record", "Text"],
"inputTypes": [
"Record",
"Text"
],
"type": "str"
}
},
@ -134,7 +163,12 @@
"data": {
"id": "ChatInput-t7F8v",
"node": {
"base_classes": ["Text", "object", "Record", "str"],
"base_classes": [
"Text",
"object",
"Record",
"str"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -158,7 +192,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -180,7 +227,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n StrInput(\n name=\"sender_name\",\n type=str,\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n StrInput(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\nfrom langflow.field_typing import Text\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n StrInput(\n name=\"sender_name\",\n type=str,\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n StrInput(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -209,12 +256,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -230,7 +282,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -250,7 +304,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -286,7 +342,12 @@
"data": {
"id": "ChatOutput-P1jEe",
"node": {
"base_classes": ["Text", "object", "Record", "str"],
"base_classes": [
"Text",
"object",
"Record",
"str"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -310,7 +371,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -332,7 +406,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.inputs import BoolInput, DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -341,7 +415,9 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": ["Text", "Message"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -361,12 +437,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -382,7 +463,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -402,7 +485,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -440,7 +525,11 @@
"display_name": "Chat Memory",
"id": "MemoryComponent-cdA1J",
"node": {
"base_classes": ["str", "Text", "object"],
"base_classes": [
"str",
"Text",
"object"
],
"beta": true,
"custom_fields": {
"n_messages": null,
@ -457,7 +546,9 @@
"field_order": [],
"frozen": false,
"icon": "history",
"output_types": ["Text"],
"output_types": [
"Text"
],
"outputs": [
{
"cache": true,
@ -466,7 +557,9 @@
"method": null,
"name": "text",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -516,12 +609,17 @@
"fileTypes": [],
"file_path": "",
"info": "Order of the messages.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "order",
"options": ["Ascending", "Descending"],
"options": [
"Ascending",
"Descending"
],
"password": false,
"placeholder": "",
"required": false,
@ -537,12 +635,18 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User", "Machine and User"],
"options": [
"Machine",
"User",
"Machine and User"
],
"password": false,
"placeholder": "",
"required": false,
@ -558,7 +662,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -577,7 +683,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID of the chat history.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -615,10 +723,17 @@
"display_name": "Prompt",
"id": "Prompt-ODkUx",
"node": {
"base_classes": ["Text", "str", "object"],
"base_classes": [
"Text",
"str",
"object"
],
"beta": false,
"custom_fields": {
"template": ["context", "user_message"]
"template": [
"context",
"user_message"
]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -641,7 +756,9 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": ["Prompt"],
"types": [
"Prompt"
],
"value": "__UNDEFINED__"
},
{
@ -650,7 +767,9 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -682,7 +801,12 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Document", "Message", "Record", "Text"],
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -702,7 +826,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -723,7 +849,12 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Document", "Message", "Record", "Text"],
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -759,7 +890,11 @@
"data": {
"id": "OpenAIModel-9RykF",
"node": {
"base_classes": ["str", "object", "Text"],
"base_classes": [
"str",
"object",
"Text"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -797,7 +932,9 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
},
{
@ -806,7 +943,9 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": ["BaseLanguageModel"],
"types": [
"BaseLanguageModel"
],
"value": "__UNDEFINED__"
}
],
@ -828,7 +967,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, SecretStrInput, StrInput\nfrom langflow.template import Output\n\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n info=\"Enable JSON mode for the model output.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n response_format = None\n if json_mode:\n response_format = {\"type\": \"json_object\"}\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n response_format=response_format,\n seed=seed,\n )\n\n return output\n"
},
"input_value": {
"advanced": false,
@ -837,7 +976,11 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text", "Data", "Prompt"],
"input_types": [
"Text",
"Data",
"Prompt"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -857,7 +1000,9 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -877,7 +1022,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -897,7 +1044,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
@ -923,8 +1072,10 @@
"dynamic": false,
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": ["Text"],
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -944,7 +1095,9 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": true,
"multiline": false,
@ -964,7 +1117,9 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -984,7 +1139,9 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1004,7 +1161,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1040,7 +1199,11 @@
"data": {
"id": "TextOutput-vrs6T",
"node": {
"base_classes": ["str", "object", "Text"],
"base_classes": [
"str",
"object",
"Text"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -1053,7 +1216,9 @@
"field_order": [],
"frozen": false,
"icon": "type",
"output_types": ["Text"],
"output_types": [
"Text"
],
"template": {
"_type": "CustomComponent",
"code": {
@ -1081,7 +1246,10 @@
"fileTypes": [],
"file_path": "",
"info": "Text or Record to be passed as output.",
"input_types": ["Record", "Text"],
"input_types": [
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1101,7 +1269,9 @@
"fileTypes": [],
"file_path": "",
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1147,4 +1317,4 @@
"is_component": false,
"last_tested_version": "1.0.0a0",
"name": "Memory Chatbot"
}
}

View file

@ -8,12 +8,19 @@
"dataType": "TextInput",
"id": "TextInput-sptaH",
"name": "text",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "document",
"id": "Prompt-amqBu",
"inputTypes": ["Document", "Message", "Record", "Text"],
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"type": "str"
}
},
@ -33,12 +40,17 @@
"dataType": "Prompt",
"id": "Prompt-amqBu",
"name": "text",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "TextOutput-2MS4a",
"inputTypes": ["Record", "Text"],
"inputTypes": [
"Record",
"Text"
],
"type": "str"
}
},
@ -58,12 +70,18 @@
"dataType": "Prompt",
"id": "Prompt-amqBu",
"name": "prompt",
"output_types": ["Prompt"]
"output_types": [
"Prompt"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-uYXZJ",
"inputTypes": ["Text", "Data", "Prompt"],
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"type": "str"
}
},
@ -83,12 +101,19 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-uYXZJ",
"name": "text_output",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "summary",
"id": "Prompt-gTNiz",
"inputTypes": ["Document", "Message", "Record", "Text"],
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"type": "str"
}
},
@ -108,12 +133,16 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-uYXZJ",
"name": "text_output",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-EJkG3",
"inputTypes": ["Text", "Message"],
"inputTypes": [
"Text"
],
"type": "str"
}
},
@ -124,7 +153,7 @@
"stroke": "#555"
},
"target": "ChatOutput-EJkG3",
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-EJkG3œ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-EJkG3œ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
},
{
"className": "stroke-gray-900 stroke-connection",
@ -133,12 +162,17 @@
"dataType": "Prompt",
"id": "Prompt-gTNiz",
"name": "text",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "TextOutput-MUDOR",
"inputTypes": ["Record", "Text"],
"inputTypes": [
"Record",
"Text"
],
"type": "str"
}
},
@ -158,12 +192,18 @@
"dataType": "Prompt",
"id": "Prompt-gTNiz",
"name": "prompt",
"output_types": ["Prompt"]
"output_types": [
"Prompt"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-XawYB",
"inputTypes": ["Text", "Data", "Prompt"],
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"type": "str"
}
},
@ -183,12 +223,16 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-XawYB",
"name": "text_output",
"output_types": ["Text"]
"output_types": [
"Text"
]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-DNmvg",
"inputTypes": ["Text", "Message"],
"inputTypes": [
"Text"
],
"type": "str"
}
},
@ -199,7 +243,7 @@
"stroke": "#555"
},
"target": "ChatOutput-DNmvg",
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-DNmvgœ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-DNmvgœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
}
],
"nodes": [
@ -209,10 +253,16 @@
"display_name": "Prompt",
"id": "Prompt-amqBu",
"node": {
"base_classes": ["object", "str", "Text"],
"base_classes": [
"object",
"str",
"Text"
],
"beta": false,
"custom_fields": {
"template": ["document"]
"template": [
"document"
]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -235,7 +285,9 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": ["Prompt"],
"types": [
"Prompt"
],
"value": "__UNDEFINED__"
},
{
@ -244,7 +296,9 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -276,7 +330,12 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Document", "Message", "Record", "Text"],
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -296,7 +355,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -334,10 +395,16 @@
"display_name": "Prompt",
"id": "Prompt-gTNiz",
"node": {
"base_classes": ["object", "str", "Text"],
"base_classes": [
"object",
"str",
"Text"
],
"beta": false,
"custom_fields": {
"template": ["summary"]
"template": [
"summary"
]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -360,7 +427,9 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": ["Prompt"],
"types": [
"Prompt"
],
"value": "__UNDEFINED__"
},
{
@ -369,7 +438,9 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -401,7 +472,12 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Document", "Message", "Record", "Text"],
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -421,7 +497,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -453,7 +531,12 @@
"data": {
"id": "ChatOutput-EJkG3",
"node": {
"base_classes": ["object", "Record", "Text", "str"],
"base_classes": [
"object",
"Record",
"Text",
"str"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -478,7 +561,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -500,7 +596,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.inputs import BoolInput, DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -509,7 +605,9 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": ["Text", "Message"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -529,12 +627,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -550,7 +653,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -570,7 +675,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -602,7 +709,12 @@
"data": {
"id": "ChatOutput-DNmvg",
"node": {
"base_classes": ["object", "Record", "Text", "str"],
"base_classes": [
"object",
"Record",
"Text",
"str"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -627,7 +739,20 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": ["Message"],
"types": [
"Message"
],
"value": "__UNDEFINED__"
},
{
"cache": true,
"display_name": "Text",
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -649,7 +774,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.inputs import BoolInput, DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n\n def text_response(self) -> Text:\n text = self.message_response().text\n return text\n"
},
"input_value": {
"advanced": false,
@ -658,7 +783,9 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": ["Text", "Message"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -678,12 +805,17 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": ["Machine", "User"],
"options": [
"Machine",
"User"
],
"password": false,
"placeholder": "",
"required": false,
@ -699,7 +831,9 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -719,7 +853,9 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -750,7 +886,11 @@
"data": {
"id": "TextInput-sptaH",
"node": {
"base_classes": ["str", "Text", "object"],
"base_classes": [
"str",
"Text",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -771,7 +911,9 @@
"method": "text_response",
"name": "text",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
}
],
@ -793,7 +935,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\nfrom langflow.inputs import MultilineInput, StrInput\nfrom langflow.template import Output\n\n\nclass TextInput(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Playground.\"\n icon = \"type\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n MultilineInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n advanced=True,\n value=\"{text}\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Text:\n return self.build(input_value=self.input_value, data_template=self.data_template)\n"
"value": "from langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\nfrom langflow.inputs import StrInput\nfrom langflow.template import Output\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Playground.\"\n icon = \"type\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Text:\n return self.build(input_value=self.input_value)\n"
},
"input_value": {
"advanced": false,
@ -802,7 +944,9 @@
"fileTypes": [],
"file_path": "",
"info": "Text to be passed as input.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -838,7 +982,11 @@
"data": {
"id": "TextOutput-2MS4a",
"node": {
"base_classes": ["str", "Text", "object"],
"base_classes": [
"str",
"Text",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -851,7 +999,9 @@
"field_order": [],
"frozen": false,
"icon": "type",
"output_types": ["Text"],
"output_types": [
"Text"
],
"template": {
"_type": "CustomComponent",
"code": {
@ -879,7 +1029,10 @@
"fileTypes": [],
"file_path": "",
"info": "Text or Record to be passed as output.",
"input_types": ["Record", "Text"],
"input_types": [
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -899,7 +1052,9 @@
"fileTypes": [],
"file_path": "",
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -935,7 +1090,11 @@
"data": {
"id": "OpenAIModel-uYXZJ",
"node": {
"base_classes": ["str", "Text", "object"],
"base_classes": [
"str",
"Text",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -973,7 +1132,9 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
},
{
@ -982,7 +1143,9 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": ["BaseLanguageModel"],
"types": [
"BaseLanguageModel"
],
"value": "__UNDEFINED__"
}
],
@ -1004,7 +1167,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, SecretStrInput, StrInput\nfrom langflow.template import Output\n\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n info=\"Enable JSON mode for the model output.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n response_format = None\n if json_mode:\n response_format = {\"type\": \"json_object\"}\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n response_format=response_format,\n seed=seed,\n )\n\n return output\n"
},
"input_value": {
"advanced": false,
@ -1013,7 +1176,11 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text", "Data", "Prompt"],
"input_types": [
"Text",
"Data",
"Prompt"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1033,7 +1200,9 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1053,7 +1222,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1073,7 +1244,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
@ -1099,8 +1272,10 @@
"dynamic": false,
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": ["Text"],
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1120,7 +1295,9 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": true,
"multiline": false,
@ -1140,7 +1317,9 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1160,7 +1339,9 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1180,7 +1361,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1216,7 +1399,11 @@
"data": {
"id": "TextOutput-MUDOR",
"node": {
"base_classes": ["str", "Text", "object"],
"base_classes": [
"str",
"Text",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -1229,7 +1416,9 @@
"field_order": [],
"frozen": false,
"icon": "type",
"output_types": ["Text"],
"output_types": [
"Text"
],
"template": {
"_type": "CustomComponent",
"code": {
@ -1257,7 +1446,10 @@
"fileTypes": [],
"file_path": "",
"info": "Text or Record to be passed as output.",
"input_types": ["Record", "Text"],
"input_types": [
"Record",
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1277,7 +1469,9 @@
"fileTypes": [],
"file_path": "",
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1313,7 +1507,11 @@
"data": {
"id": "OpenAIModel-XawYB",
"node": {
"base_classes": ["str", "Text", "object"],
"base_classes": [
"str",
"Text",
"object"
],
"beta": false,
"custom_fields": {
"input_value": null,
@ -1351,7 +1549,9 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": ["Text"],
"types": [
"Text"
],
"value": "__UNDEFINED__"
},
{
@ -1360,7 +1560,9 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": ["BaseLanguageModel"],
"types": [
"BaseLanguageModel"
],
"value": "__UNDEFINED__"
}
],
@ -1382,7 +1584,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, SecretStrInput, StrInput\nfrom langflow.template import Output\n\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n info=\"Enable JSON mode for the model output.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n response_format = None\n if json_mode:\n response_format = {\"type\": \"json_object\"}\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n response_format=response_format,\n seed=seed,\n )\n\n return output\n"
},
"input_value": {
"advanced": false,
@ -1391,7 +1593,11 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text", "Data", "Prompt"],
"input_types": [
"Text",
"Data",
"Prompt"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1411,7 +1617,9 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1431,7 +1639,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1451,7 +1661,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": true,
"load_from_db": false,
"multiline": false,
@ -1477,8 +1689,10 @@
"dynamic": false,
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": ["Text"],
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1498,7 +1712,9 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": true,
"multiline": false,
@ -1518,7 +1734,9 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1538,7 +1756,9 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1558,7 +1778,9 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": ["Text"],
"input_types": [
"Text"
],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1602,4 +1824,4 @@
"is_component": false,
"last_tested_version": "1.0.0a0",
"name": "Prompt Chaining"
}
}

File diff suppressed because one or more lines are too long

View file

@ -1,15 +1,13 @@
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from loguru import logger
from pydantic import BaseModel
from langflow.graph.graph.base import Graph
from langflow.graph.schema import RunOutputs
from langflow.graph.vertex.base import Vertex
from langflow.schema.graph import InputValue, Tweaks
from langflow.schema.schema import INPUT_FIELD_NAME
from langflow.services.deps import get_settings_service
from langflow.services.session.service import SessionService
from loguru import logger
from pydantic import BaseModel
if TYPE_CHECKING:
from langflow.api.v1.schemas import InputValueRequest
@ -27,18 +25,13 @@ async def run_graph_internal(
session_id: Optional[str] = None,
inputs: Optional[List["InputValueRequest"]] = None,
outputs: Optional[List[str]] = None,
artifacts: Optional[Dict[str, Any]] = None,
session_service: Optional[SessionService] = None,
) -> tuple[List[RunOutputs], str]:
"""Run the graph and generate the result"""
inputs = inputs or []
graph_data = graph._graph_data
if session_id is None and session_service is not None:
session_id_str = session_service.generate_key(session_id=flow_id, data_graph=graph_data)
elif session_id is not None:
session_id_str = session_id
if session_id is None:
session_id_str = flow_id
else:
raise ValueError("session_id or session_service must be provided")
session_id_str = session_id
components = []
inputs_list = []
types = []
@ -53,16 +46,14 @@ async def run_graph_internal(
fallback_to_env_vars = get_settings_service().settings.fallback_to_env_var
run_outputs = await graph.arun(
inputs_list,
components,
types,
outputs or [],
inputs=inputs_list,
inputs_components=components,
types=types,
outputs=outputs or [],
stream=stream,
session_id=session_id_str or "",
fallback_to_env_vars=fallback_to_env_vars,
)
if session_id_str and session_service:
await session_service.update_session(session_id_str, (graph, artifacts))
return run_outputs, session_id_str

View file

@ -4,19 +4,21 @@ from typing import TYPE_CHECKING, List, Optional, Union
import duckdb
from langflow.services.base import Service
from langflow.services.monitor.schema import MessageModel, TransactionModel, VertexBuildModel
from langflow.services.monitor.utils import add_row_to_table, drop_and_create_table_if_schema_mismatch
from loguru import logger
from platformdirs import user_cache_dir
if TYPE_CHECKING:
from langflow.services.settings.manager import SettingsService
from langflow.services.monitor.schema import MessageModel, TransactionModel, VertexBuildModel
class MonitorService(Service):
name = "monitor_service"
def __init__(self, settings_service: "SettingsService"):
from langflow.services.monitor.schema import MessageModel, TransactionModel, VertexBuildModel
self.settings_service = settings_service
self.base_cache_dir = Path(user_cache_dir("langflow"))
self.db_path = self.base_cache_dir / "monitor.duckdb"
@ -45,7 +47,7 @@ class MonitorService(Service):
def add_row(
self,
table_name: str,
data: Union[dict, TransactionModel, MessageModel, VertexBuildModel],
data: Union[dict, "TransactionModel", "MessageModel", "VertexBuildModel"],
):
# Make sure the model passed matches the table
@ -127,7 +129,7 @@ class MonitorService(Service):
return self.exec_query(query, read_only=False)
def add_message(self, message: MessageModel):
def add_message(self, message: "MessageModel"):
self.add_row("messages", message)
def get_messages(

View file

@ -337,6 +337,17 @@ files = [
[package.dependencies]
pycparser = "*"
[[package]]
name = "chardet"
version = "5.2.0"
description = "Universal encoding detector for Python 3"
optional = false
python-versions = ">=3.7"
files = [
{file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
{file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
]
[[package]]
name = "charset-normalizer"
version = "3.3.2"
@ -1158,19 +1169,19 @@ files = [
[[package]]
name = "langchain"
version = "0.2.4"
version = "0.2.5"
description = "Building applications with LLMs through composability"
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
{file = "langchain-0.2.4-py3-none-any.whl", hash = "sha256:a04813215c30f944df006031e2febde872af8fab628dcee825d969e07b6cd621"},
{file = "langchain-0.2.4.tar.gz", hash = "sha256:e704b5b06222d5eba2d02c76f891321d1bac8952ed54e093831b2bdabf99dcd5"},
{file = "langchain-0.2.5-py3-none-any.whl", hash = "sha256:9aded9a65348254e1c93dcdaacffe4d1b6a5e7f74ef80c160c88ff78ad299228"},
{file = "langchain-0.2.5.tar.gz", hash = "sha256:ffdbf4fcea46a10d461bcbda2402220fcfd72a0c70e9f4161ae0510067b9b3bd"},
]
[package.dependencies]
aiohttp = ">=3.8.3,<4.0.0"
async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""}
langchain-core = ">=0.2.6,<0.3.0"
langchain-core = ">=0.2.7,<0.3.0"
langchain-text-splitters = ">=0.2.0,<0.3.0"
langsmith = ">=0.1.17,<0.2.0"
numpy = [
@ -1185,22 +1196,25 @@ tenacity = ">=8.1.0,<9.0.0"
[[package]]
name = "langchain-community"
version = "0.2.4"
version = "0.2.5"
description = "Community contributed LangChain integrations."
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
{file = "langchain_community-0.2.4-py3-none-any.whl", hash = "sha256:8582e9800f4837660dc297cccd2ee1ddc1d8c440d0fe8b64edb07620f0373b0e"},
{file = "langchain_community-0.2.4.tar.gz", hash = "sha256:2bb6a1a36b8500a564d25d76469c02457b1a7c3afea6d4a609a47c06b993e3e4"},
{file = "langchain_community-0.2.5-py3-none-any.whl", hash = "sha256:bf37a334952e42c7676d083cf2d2c4cbfbb7de1949c4149fe19913e2b06c485f"},
{file = "langchain_community-0.2.5.tar.gz", hash = "sha256:476787b8c8c213b67e7b0eceb53346e787f00fbae12d8e680985bd4f93b0bf64"},
]
[package.dependencies]
aiohttp = ">=3.8.3,<4.0.0"
dataclasses-json = ">=0.5.7,<0.7"
langchain = ">=0.2.0,<0.3.0"
langchain-core = ">=0.2.0,<0.3.0"
langchain = ">=0.2.5,<0.3.0"
langchain-core = ">=0.2.7,<0.3.0"
langsmith = ">=0.1.0,<0.2.0"
numpy = ">=1,<2"
numpy = [
{version = ">=1,<2", markers = "python_version < \"3.12\""},
{version = ">=1.26.0,<2.0.0", markers = "python_version >= \"3.12\""},
]
PyYAML = ">=5.3"
requests = ">=2,<3"
SQLAlchemy = ">=1.4,<3"
@ -1208,13 +1222,13 @@ tenacity = ">=8.1.0,<9.0.0"
[[package]]
name = "langchain-core"
version = "0.2.6"
version = "0.2.7"
description = "Building applications with LLMs through composability"
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
{file = "langchain_core-0.2.6-py3-none-any.whl", hash = "sha256:90521c9fc95d8f925e0d2e2d952382676aea6d3f8de611eda1b1810874c31e5d"},
{file = "langchain_core-0.2.6.tar.gz", hash = "sha256:9f0e38da722a558a6e95b6d86de01bd92e84558c47ac8ba599f02eab70a1c873"},
{file = "langchain_core-0.2.7-py3-none-any.whl", hash = "sha256:fd02e153c898486dd728d634684ffc64bc257ff2ba443dc7e53d017ac0bf4658"},
{file = "langchain_core-0.2.7.tar.gz", hash = "sha256:b0b1b6dfbdedb39426fcb8bd3f07e40eec7964856e3fc384c420ca6dba61b34e"},
]
[package.dependencies]
@ -1227,21 +1241,18 @@ tenacity = ">=8.1.0,<9.0.0"
[[package]]
name = "langchain-experimental"
version = "0.0.60"
version = "0.0.61"
description = "Building applications with LLMs through composability"
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
{file = "langchain_experimental-0.0.60-py3-none-any.whl", hash = "sha256:ef3b6b6b84fe2bfe19eba6d1a98005e27d96576514c6415f5afe4ace5bf477d8"},
{file = "langchain_experimental-0.0.60.tar.gz", hash = "sha256:a16cbcd18cda6b86be8f41fed7963c13569295def0d8b4c6324b806d878d442c"},
{file = "langchain_experimental-0.0.61-py3-none-any.whl", hash = "sha256:f9c516f528f55919743bd56fe1689a53bf74ae7f8902d64b9d8aebc61249cbe2"},
{file = "langchain_experimental-0.0.61.tar.gz", hash = "sha256:e9538efb994be5db3045cc582cddb9787c8299c86ffeee9d3779b7f58eef2226"},
]
[package.dependencies]
langchain-community = ">=0.2,<0.3"
langchain-core = ">=0.2,<0.3"
[package.extras]
extended-testing = ["faker (>=19.3.1,<20.0.0)", "jinja2 (>=3,<4)", "pandas (>=2.0.1,<3.0.0)", "presidio-analyzer (>=2.2.352,<3.0.0)", "presidio-anonymizer (>=2.2.352,<3.0.0)", "sentence-transformers (>=2,<3)", "tabulate (>=0.9.0,<0.10.0)", "vowpal-wabbit-next (==0.6.0)"]
langchain-community = ">=0.2.5,<0.3.0"
langchain-core = ">=0.2.7,<0.3.0"
[[package]]
name = "langchain-text-splitters"
@ -3297,4 +3308,4 @@ local = []
[metadata]
lock-version = "2.0"
python-versions = ">=3.10,<3.13"
content-hash = "72f05330f1e734596d160b45cb68ab2ebf7d0824314bec0566bddb5b2043f4e6"
content-hash = "73dc20fcd3c34d40dd31c9251efc8e2d8d3346f2f1bc18be516acf57c86ce460"

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "langflow-base"
version = "0.0.68"
version = "0.0.70"
description = "A Python package with a built-in web application"
authors = ["Langflow <contact@langflow.org>"]
maintainers = [
@ -64,6 +64,7 @@ asyncer = "^0.0.5"
pyperclip = "^1.8.2"
uncurl = "^0.0.11"
sentry-sdk = "^2.5.1"
chardet = "^5.2.0"
[tool.poetry.extras]

View file

@ -99,12 +99,11 @@
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.15",
"daisyui": "^4.0.4",
"eslint": "^8.57.0",
"eslint-plugin-node": "^11.1.0",
"eslint": "^9.5.0",
"postcss": "^8.4.29",
"prettier": "^2.8.8",
"prettier": "^3.3.2",
"prettier-plugin-organize-imports": "^3.2.3",
"prettier-plugin-tailwindcss": "^0.3.0",
"prettier-plugin-tailwindcss": "^0.6.4",
"simple-git-hooks": "^2.11.1",
"tailwindcss": "^3.3.3",
"tailwindcss-dotted-background": "^1.1.0",
@ -799,6 +798,18 @@
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
"node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/@eslint-community/regexpp": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
@ -808,16 +819,52 @@
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
"node_modules/@eslint/config-array": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.16.0.tgz",
"integrity": "sha512-/jmuSd74i4Czf1XXn7wGRWZCuyaUZ330NH1Bek0Pplatt4Sy1S5haN21SCLLdbeKslQ+S0wEJ+++v5YibSi+Lg==",
"dev": true,
"dependencies": {
"@eslint/object-schema": "^2.1.4",
"debug": "^4.3.1",
"minimatch": "^3.0.5"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/config-array/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/@eslint/config-array/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/@eslint/eslintrc": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
"integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
"espree": "^9.6.0",
"globals": "^13.19.0",
"espree": "^10.0.1",
"globals": "^14.0.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
@ -825,7 +872,7 @@
"strip-json-comments": "^3.1.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
@ -842,15 +889,12 @@
}
},
"node_modules/@eslint/eslintrc/node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
},
"engines": {
"node": ">=8"
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@ -869,12 +913,21 @@
}
},
"node_modules/@eslint/js": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
"version": "9.5.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz",
"integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/object-schema": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
"integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
"dev": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@floating-ui/core": {
@ -935,43 +988,6 @@
"react-hook-form": "^7.0.0"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
"deprecated": "Use @eslint/config-array instead",
"dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^2.0.2",
"debug": "^4.3.1",
"minimatch": "^3.0.5"
},
"engines": {
"node": ">=10.10.0"
}
},
"node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/@humanwhocodes/module-importer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
@ -985,12 +1001,18 @@
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@humanwhocodes/object-schema": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
"deprecated": "Use @eslint/object-schema instead",
"dev": true
"node_modules/@humanwhocodes/retry": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
"integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
"dev": true,
"engines": {
"node": ">=18.18"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
@ -3277,9 +3299,9 @@
}
},
"node_modules/@swc/core": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.28.tgz",
"integrity": "sha512-muCdNIqOTURUgYeyyOLYE3ShL8SZO6dw6bhRm6dCvxWzCZOncPc5fB0kjcPXTML+9KJoHL7ks5xg+vsQK+v6ig==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.6.0.tgz",
"integrity": "sha512-Wynbo79uIVBgmq3TPcTMdtXUkqk69IPSVuzo7/Jl1OhR4msC7cUaoRB1216ZanWttrAZ4/g6u17w9XZG4fzp1A==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@ -3294,16 +3316,16 @@
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
"@swc/core-darwin-arm64": "1.5.28",
"@swc/core-darwin-x64": "1.5.28",
"@swc/core-linux-arm-gnueabihf": "1.5.28",
"@swc/core-linux-arm64-gnu": "1.5.28",
"@swc/core-linux-arm64-musl": "1.5.28",
"@swc/core-linux-x64-gnu": "1.5.28",
"@swc/core-linux-x64-musl": "1.5.28",
"@swc/core-win32-arm64-msvc": "1.5.28",
"@swc/core-win32-ia32-msvc": "1.5.28",
"@swc/core-win32-x64-msvc": "1.5.28"
"@swc/core-darwin-arm64": "1.6.0",
"@swc/core-darwin-x64": "1.6.0",
"@swc/core-linux-arm-gnueabihf": "1.6.0",
"@swc/core-linux-arm64-gnu": "1.6.0",
"@swc/core-linux-arm64-musl": "1.6.0",
"@swc/core-linux-x64-gnu": "1.6.0",
"@swc/core-linux-x64-musl": "1.6.0",
"@swc/core-win32-arm64-msvc": "1.6.0",
"@swc/core-win32-ia32-msvc": "1.6.0",
"@swc/core-win32-x64-msvc": "1.6.0"
},
"peerDependencies": {
"@swc/helpers": "*"
@ -3315,9 +3337,9 @@
}
},
"node_modules/@swc/core-darwin-arm64": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.28.tgz",
"integrity": "sha512-sP6g63ybzIdOWNDbn51tyHN8EMt7Mb4RMeHQEsXB7wQfDvzhpWB+AbfK6Gs3Q8fwP/pmWIrWW9csKOc1K2Mmkg==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.6.0.tgz",
"integrity": "sha512-W1Mwk0WRrJ5lAVkYRPxpxOmwu8p9ASXeOmiORhXvE7DYREyI30005xlqSOITU1pfSNKj7G9u3+9DjsOzPPPbBw==",
"cpu": [
"arm64"
],
@ -3331,9 +3353,9 @@
}
},
"node_modules/@swc/core-darwin-x64": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.28.tgz",
"integrity": "sha512-Bd/agp/g7QocQG5AuorOzSC78t8OzeN+pCN/QvJj1CvPhvppjJw6e1vAbOR8vO2vvGi2pvtf3polrYQStJtSiA==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.6.0.tgz",
"integrity": "sha512-EzxLnpPC1zgLb2Y0iVUG6b+/GUv43k6uJUIs52UzxOnBElYP/WeItI3RJ+LUMFzCpZMk/IxB10wofEoeQ1H/Xg==",
"cpu": [
"x64"
],
@ -3347,9 +3369,9 @@
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.28.tgz",
"integrity": "sha512-Wr3TwPGIveS9/OBWm0r9VAL8wkCR0zQn46J8K01uYCmVhUNK3Muxjs0vQBZaOrGu94mqbj9OXY+gB3W7aDvGdA==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.6.0.tgz",
"integrity": "sha512-uP/STDjWZ5N6lc8mxJFsex4NXDaqhfzd8UOrI3LfdV97+4faE4/BC6bVqDNHFFzZi0PHuVBxD6md7IfPjugk6A==",
"cpu": [
"arm"
],
@ -3363,9 +3385,9 @@
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.28.tgz",
"integrity": "sha512-8G1ZwVTuLgTAVTMPD+M97eU6WeiRIlGHwKZ5fiJHPBcz1xqIC7jQcEh7XBkobkYoU5OILotls3gzjRt8CMNyDQ==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.6.0.tgz",
"integrity": "sha512-UgNz6anowcnYzJtZohzpii31FOgouBHJqluiq+p2geX/agbC+KfOKwVXdljn95+Qc4ygBuw/hjKjgF2msOLeVg==",
"cpu": [
"arm64"
],
@ -3379,9 +3401,9 @@
}
},
"node_modules/@swc/core-linux-arm64-musl": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.28.tgz",
"integrity": "sha512-0Ajdzb5Fzvz+XUbN5ESeHAz9aHHSYiQcm+vmsDi0TtPHmsalfnqEPZmnK0zPALPJPLQP2dDo4hELeDg3/c3xgA==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.6.0.tgz",
"integrity": "sha512-xPV6qrnj4nFwXQbIv70C1Kn5z5Th53sirIY76aEonr78qeC6+ywaBZR4uLFNHsljVjyuvVQfTTcl2qraGhu6oQ==",
"cpu": [
"arm64"
],
@ -3395,9 +3417,9 @@
}
},
"node_modules/@swc/core-linux-x64-gnu": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.28.tgz",
"integrity": "sha512-ueQ9VejnQUM2Pt+vT0IAKoF4vYBWUP6n1KHGdILpoGe3LuafQrqu7RoyQ15C7/AYii7hAeNhTFdf6gLbg8cjFg==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.6.0.tgz",
"integrity": "sha512-xTeWn4OT5uQ+DxT2cy94ngK8tF1U/5fMC49/V6FhCS2Wh+Xa/O+OWcOyKvYtk3b0eGYS4iNIRKgzog7fLSFtvQ==",
"cpu": [
"x64"
],
@ -3411,9 +3433,9 @@
}
},
"node_modules/@swc/core-linux-x64-musl": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.28.tgz",
"integrity": "sha512-G5th8Mg0az8CbY4GQt9/m5hg2Y0kGIwvQBeVACuLQB6q2Y4txzdiTpjmFqUUhEvvl7Klyx1IHvNhfXs3zpt7PA==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.6.0.tgz",
"integrity": "sha512-3P01mYD5XbyaVLT0MGZmZE+ZdgmGSvuvIhSejRDBlEXqkFnH79nWds+KsE+91hzVU8XsgzX57Yzv4eO5dlIuPw==",
"cpu": [
"x64"
],
@ -3427,9 +3449,9 @@
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.28.tgz",
"integrity": "sha512-JezwCGavZ7CkNXx4yInI4kpb71L0zxzxA9BFlmnsGKEEjVQcKc3hFpmIzfFVs+eotlBUwDNb0+Yo9m6Cb7lllA==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.6.0.tgz",
"integrity": "sha512-xFuook1efU0ctzMAEeol4eI7J6+k/c/pMJpp/NP/4JJDnhlHwAi2iyiZcID8YZS+ePHgXMLndGdIMHVv/wIPkQ==",
"cpu": [
"arm64"
],
@ -3443,9 +3465,9 @@
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.28.tgz",
"integrity": "sha512-q8tW5J4RkOkl7vYShnWS//VAb2Ngolfm9WOMaF2GRJUr2Y/Xeb/+cNjdsNOqea2BzW049D5vdP7XPmir3/zUZw==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.6.0.tgz",
"integrity": "sha512-VCJa5vTywxzASqvf9OEUM5SZBcNrWbuIkSGM5T9guuBzyrh/tSqVHjzOWL9qpP69uPVj5G/I5bJObLiUKErhvQ==",
"cpu": [
"ia32"
],
@ -3459,9 +3481,9 @@
}
},
"node_modules/@swc/core-win32-x64-msvc": {
"version": "1.5.28",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.28.tgz",
"integrity": "sha512-jap6EiB3wG1YE1hyhNr9KLPpH4PGm+5tVMfN0l7fgKtV0ikgpcEN/YF94tru+z5m2HovqYW009+Evq9dcVGmpg==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.6.0.tgz",
"integrity": "sha512-L7i8WBSIJTQiMONJGHnznDydZmlJIqHjZ3VhBHeTTms8cEAuwkAVgzPwgr5cD9GhmcwdeBI9iYdOuKr1pUx19Q==",
"cpu": [
"x64"
],
@ -4356,12 +4378,6 @@
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
"dev": true
},
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
"dev": true
},
"node_modules/@vitejs/plugin-react-swc": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz",
@ -4392,9 +4408,9 @@
"integrity": "sha512-bwDKqjqNccC/MSujqnYTeAS5dIR8UmGLP0R90mvsJY0FRC8NUWBSTfj34+EIzo2NWc/gV8IZTqv4fXaiZJpCtA=="
},
"node_modules/acorn": {
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
"integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
"bin": {
"acorn": "bin/acorn"
},
@ -4421,9 +4437,12 @@
}
},
"node_modules/acorn-walk": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
"integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
"version": "8.3.3",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz",
"integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==",
"dependencies": {
"acorn": "^8.11.0"
},
"engines": {
"node": ">=0.4.0"
}
@ -5009,9 +5028,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001632",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001632.tgz",
"integrity": "sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==",
"version": "1.0.30001634",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001634.tgz",
"integrity": "sha512-fbBYXQ9q3+yp1q1gBk86tOFs4pyn/yxFm5ZNP18OXJDfA3txImOY9PhfxVggZ4vRHDqoU8NrKU81eN0OtzOgRA==",
"funding": [
{
"type": "opencollective",
@ -5802,18 +5821,6 @@
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
},
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
"dependencies": {
"esutils": "^2.0.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/dom-accessibility-api": {
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
@ -5863,9 +5870,9 @@
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
"node_modules/electron-to-chromium": {
"version": "1.4.799",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.799.tgz",
"integrity": "sha512-3D3DwWkRTzrdEpntY0hMLYwj7SeBk1138CkPE8sBDSj3WzrzOiG2rHm3luw8jucpf+WiyLBCZyU9lMHyQI9M9Q=="
"version": "1.4.803",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.803.tgz",
"integrity": "sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g=="
},
"node_modules/emoji-regex": {
"version": "10.3.0",
@ -6020,41 +6027,37 @@
}
},
"node_modules/eslint": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
"version": "9.5.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.5.0.tgz",
"integrity": "sha512-+NAOZFrW/jFTS3dASCGBxX1pkFD0/fsO+hfAkJ4TyYKwgsXZbqzrw+seCYFCcPCYXvnD67tAnglU7GQTz6kcVw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
"@eslint/js": "8.57.0",
"@humanwhocodes/config-array": "^0.11.14",
"@eslint/config-array": "^0.16.0",
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "9.5.0",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.3.0",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.2.2",
"eslint-visitor-keys": "^3.4.3",
"espree": "^9.6.1",
"esquery": "^1.4.2",
"eslint-scope": "^8.0.1",
"eslint-visitor-keys": "^4.0.0",
"espree": "^10.0.1",
"esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
"file-entry-cache": "^8.0.0",
"find-up": "^5.0.0",
"glob-parent": "^6.0.2",
"globals": "^13.19.0",
"graphemer": "^1.4.0",
"ignore": "^5.2.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"is-path-inside": "^3.0.3",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash.merge": "^4.6.2",
@ -6068,120 +6071,35 @@
"eslint": "bin/eslint.js"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-plugin-es": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz",
"integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==",
"dev": true,
"dependencies": {
"eslint-utils": "^2.0.0",
"regexpp": "^3.0.0"
},
"engines": {
"node": ">=8.10.0"
},
"funding": {
"url": "https://github.com/sponsors/mysticatea"
},
"peerDependencies": {
"eslint": ">=4.19.1"
}
},
"node_modules/eslint-plugin-node": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
"integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
"dev": true,
"dependencies": {
"eslint-plugin-es": "^3.0.0",
"eslint-utils": "^2.0.0",
"ignore": "^5.1.1",
"minimatch": "^3.0.4",
"resolve": "^1.10.1",
"semver": "^6.1.0"
},
"engines": {
"node": ">=8.10.0"
},
"peerDependencies": {
"eslint": ">=5.16.0"
}
},
"node_modules/eslint-plugin-node/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/eslint-plugin-node/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
"url": "https://eslint.org/donate"
}
},
"node_modules/eslint-scope": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz",
"integrity": "sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==",
"dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
"dev": true,
"dependencies": {
"eslint-visitor-keys": "^1.1.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/mysticatea"
}
},
"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
"integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
@ -6258,21 +6176,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint/node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@ -6315,17 +6218,17 @@
}
},
"node_modules/espree": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz",
"integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==",
"dev": true,
"dependencies": {
"acorn": "^8.9.0",
"acorn": "^8.11.3",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.4.1"
"eslint-visitor-keys": "^4.0.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
@ -6601,15 +6504,15 @@
}
},
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
"dev": true,
"dependencies": {
"flat-cache": "^3.0.4"
"flat-cache": "^4.0.0"
},
"engines": {
"node": "^10.12.0 || >=12.0.0"
"node": ">=16.0.0"
}
},
"node_modules/file-saver": {
@ -6706,17 +6609,16 @@
}
},
"node_modules/flat-cache": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
"dev": true,
"dependencies": {
"flatted": "^3.2.9",
"keyv": "^4.5.3",
"rimraf": "^3.0.2"
"keyv": "^4.5.4"
},
"engines": {
"node": "^10.12.0 || >=12.0.0"
"node": ">=16"
}
},
"node_modules/flatted": {
@ -6754,9 +6656,9 @@
}
},
"node_modules/foreground-child": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.0.tgz",
"integrity": "sha512-CrWQNaEl1/6WeZoarcM9LHupTo3RpZO2Pdk1vktwzPiQTsJnAKJmm3TACKeG5UZbWDfaH2AbvYxzP96y0MT7fA==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
"integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
"dependencies": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
@ -6895,7 +6797,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"devOptional": true
"optional": true
},
"node_modules/fsevents": {
"version": "2.3.2",
@ -6997,7 +6899,7 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"devOptional": true,
"optional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -7028,7 +6930,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"devOptional": true,
"optional": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -7038,7 +6940,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"devOptional": true,
"optional": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -7096,12 +6998,6 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
},
"node_modules/graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
"node_modules/has-bigints": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
@ -7482,7 +7378,7 @@
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"devOptional": true,
"optional": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@ -10040,7 +9936,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"devOptional": true,
"optional": true,
"engines": {
"node": ">=0.10.0"
}
@ -10368,15 +10264,15 @@
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
"integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=10.13.0"
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
@ -10403,20 +10299,20 @@
}
},
"node_modules/prettier-plugin-tailwindcss": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.3.0.tgz",
"integrity": "sha512-009/Xqdy7UmkcTBpwlq7jsViDqXAYSOMLDrHAdTMlVZOrKfM2o9Ci7EMWTMZ7SkKBFTG04UM9F9iM2+4i6boDA==",
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.4.tgz",
"integrity": "sha512-3vhbIvlKyAWPaw9bUr2cw6M1BGx2Oy9CCLJyv+nxEiBGCTcL69WcAz2IFMGqx8IXSzQCInGSo2ujAByg9poHLQ==",
"dev": true,
"engines": {
"node": ">=12.17.0"
"node": ">=14.21.3"
},
"peerDependencies": {
"@ianvs/prettier-plugin-sort-imports": "*",
"@prettier/plugin-pug": "*",
"@shopify/prettier-plugin-liquid": "*",
"@shufo/prettier-plugin-blade": "*",
"@trivago/prettier-plugin-sort-imports": "*",
"prettier": ">=2.2.0",
"@zackad/prettier-plugin-twig-melody": "*",
"prettier": "^3.0",
"prettier-plugin-astro": "*",
"prettier-plugin-css-order": "*",
"prettier-plugin-import-sort": "*",
@ -10424,9 +10320,9 @@
"prettier-plugin-marko": "*",
"prettier-plugin-organize-attributes": "*",
"prettier-plugin-organize-imports": "*",
"prettier-plugin-sort-imports": "*",
"prettier-plugin-style-order": "*",
"prettier-plugin-svelte": "*",
"prettier-plugin-twig-melody": "*"
"prettier-plugin-svelte": "*"
},
"peerDependenciesMeta": {
"@ianvs/prettier-plugin-sort-imports": {
@ -10438,10 +10334,10 @@
"@shopify/prettier-plugin-liquid": {
"optional": true
},
"@shufo/prettier-plugin-blade": {
"@trivago/prettier-plugin-sort-imports": {
"optional": true
},
"@trivago/prettier-plugin-sort-imports": {
"@zackad/prettier-plugin-twig-melody": {
"optional": true
},
"prettier-plugin-astro": {
@ -10465,14 +10361,14 @@
"prettier-plugin-organize-imports": {
"optional": true
},
"prettier-plugin-sort-imports": {
"optional": true
},
"prettier-plugin-style-order": {
"optional": true
},
"prettier-plugin-svelte": {
"optional": true
},
"prettier-plugin-twig-melody": {
"optional": true
}
}
},
@ -11079,18 +10975,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/regexpp": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
"dev": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/mysticatea"
}
},
"node_modules/rehype-mathjax": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/rehype-mathjax/-/rehype-mathjax-4.0.3.tgz",
@ -11245,7 +11129,7 @@
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"deprecated": "Rimraf versions prior to v4 are no longer supported",
"devOptional": true,
"optional": true,
"dependencies": {
"glob": "^7.1.3"
},
@ -12395,18 +12279,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typescript": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
@ -12444,9 +12316,9 @@
}
},
"node_modules/undici": {
"version": "6.18.2",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.18.2.tgz",
"integrity": "sha512-o/MQLTwRm9IVhOqhZ0NQ9oXax1ygPjw6Vs+Vq/4QRjbOAC3B1GCHy7TYxxbExKlb7bzDRzt9vBWU6BDz0RFfYg==",
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.19.0.tgz",
"integrity": "sha512-9gGwbSLgYMjp4r6M5P9bhqhx1E+RyUIHqZE0r7BmrRoqroJUG6xlVu5TXH9DnwmCPLkcaVNrcYtxUE9d3InnyQ==",
"engines": {
"node": ">=18.17"
}

View file

@ -121,12 +121,11 @@
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.15",
"daisyui": "^4.0.4",
"eslint": "^8.57.0",
"eslint-plugin-node": "^11.1.0",
"eslint": "^9.5.0",
"postcss": "^8.4.29",
"prettier": "^2.8.8",
"prettier": "^3.3.2",
"prettier-plugin-organize-imports": "^3.2.3",
"prettier-plugin-tailwindcss": "^0.3.0",
"prettier-plugin-tailwindcss": "^0.6.4",
"simple-git-hooks": "^2.11.1",
"tailwindcss": "^3.3.3",
"tailwindcss-dotted-background": "^1.1.0",

View file

@ -1,3 +1,3 @@
module.exports = {
plugins: [require("prettier-plugin-tailwindcss")],
plugins: ["prettier-plugin-tailwindcss"],
};

View file

@ -19,7 +19,7 @@ export default function OutputModal({
<SwitchOutputView nodeId={nodeId} outputName={outputName} />
</BaseModal.Content>
<BaseModal.Footer>
<div className="flex w-full justify-end pt-2">
<div className="flex w-full justify-end pt-2">
<Button className="flex gap-2 px-3" onClick={() => setOpen(false)}>
Close
</Button>

View file

@ -114,7 +114,7 @@ export default function ParameterComponent({
const logs = (data?.logs[outputName] ?? [])[0];
if (Array.isArray(logs) && logs.length > 1) {
return logs.some(
(log) => log.type === "error" || log.type === "ValueError",
(log) => log.type === "error" || log.type === "ValueError"
);
} else {
return logs?.type === "error" || logs?.type === "ValueError";
@ -156,7 +156,7 @@ export default function ParameterComponent({
handleUpdateValues,
debouncedHandleUpdateValues,
setNode,
setIsLoading,
setIsLoading
);
const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
@ -164,7 +164,7 @@ export default function ParameterComponent({
name,
takeSnapshot,
setNode,
updateNodeInternals,
updateNodeInternals
);
const { handleRefreshButtonPress: handleRefreshButtonPressHook } =
@ -173,13 +173,13 @@ export default function ParameterComponent({
let disabled =
edges.some(
(edge) =>
edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id),
edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id)
) ?? false;
let disabledOutput =
edges.some(
(edge) =>
edge.sourceHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id),
edge.sourceHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id)
) ?? false;
const handleRefreshButtonPress = async (name, data) => {
@ -190,7 +190,7 @@ export default function ParameterComponent({
const handleOnNewValue = async (
newValue: string | string[] | boolean | Object[],
skipSnapshot: boolean | undefined = false,
skipSnapshot: boolean | undefined = false
): Promise<void> => {
handleOnNewValueHook(newValue, skipSnapshot);
};
@ -302,16 +302,16 @@ export default function ParameterComponent({
isValidConnection(connection, nodes, edges)
}
className={classNames(
left ? "my-12 -ml-0.5 " : " my-12 -mr-0.5 ",
left ? "my-12 -ml-0.5" : "my-12 -mr-0.5",
"h-3 w-3 rounded-full border-2 bg-background",
!showNode ? "mt-0" : "",
!showNode ? "mt-0" : ""
)}
style={{
borderColor: color ?? nodeColors.unknown,
}}
onClick={() => {
setFilterEdge(
groupByFamily(myData, tooltipTitle!, left, nodes!),
groupByFamily(myData, tooltipTitle!, left, nodes!)
);
}}
></Handle>
@ -326,7 +326,7 @@ export default function ParameterComponent({
"relative mt-1 flex w-full flex-wrap items-center justify-between bg-muted px-5 py-2" +
((name === "code" && type === "code") ||
(name.includes("code") && proxy)
? " hidden "
? " hidden"
: "")
}
>
@ -389,7 +389,7 @@ export default function ParameterComponent({
{errorOutput ? (
<IconComponent
className={classNames(
"h-5 w-5 rounded-md text-status-red",
"h-5 w-5 rounded-md text-status-red"
)}
name={"X"}
/>
@ -399,7 +399,7 @@ export default function ParameterComponent({
"h-5 w-5 rounded-md",
displayOutputPreview && !unknownOutput
? " hover:text-medium-indigo"
: " cursor-not-allowed text-muted-foreground",
: " cursor-not-allowed text-muted-foreground"
)}
name={"ScanEye"}
/>
@ -457,12 +457,12 @@ export default function ParameterComponent({
}
className={classNames(
left ? "-ml-0.5" : "-mr-0.5",
"h-3 w-3 rounded-full border-2 bg-background",
"h-3 w-3 rounded-full border-2 bg-background"
)}
style={{ borderColor: color ?? nodeColors.unknown }}
onClick={() => {
setFilterEdge(
groupByFamily(myData, tooltipTitle!, left, nodes!),
groupByFamily(myData, tooltipTitle!, left, nodes!)
);
}}
/>
@ -502,7 +502,7 @@ export default function ParameterComponent({
</div>
</Case>
<Case condition={data.node?.template[name]?.multiline}>
<div className="mt-2 flex w-full flex-col ">
<div className="mt-2 flex w-full flex-col">
<div className="flex-grow">
<TextAreaComponent
disabled={disabled}

View file

@ -376,14 +376,14 @@ export default function GenericNode({
className={
"generic-node-div-title " +
(!showNode
? " relative h-24 w-24 rounded-full "
: " justify-between rounded-t-lg ")
? " relative h-24 w-24 rounded-full"
: " justify-between rounded-t-lg")
}
>
<div
className={
"generic-node-title-arrangement rounded-full" +
(!showNode && " justify-center ")
(!showNode && " justify-center")
}
data-testid="generic-node-title-arrangement"
>
@ -714,10 +714,7 @@ export default function GenericNode({
nameEditable ? (
"Double Click to Edit Description"
) : (
<Markdown
className="markdown prose flex flex-col text-primary word-break-break-word
dark:prose-invert"
>
<Markdown className="markdown prose flex flex-col text-primary word-break-break-word dark:prose-invert">
{String(data.node?.description)}
</Markdown>
)}

View file

@ -83,7 +83,7 @@ export default function SingleAlert({
<div className="flex-shrink-0 cursor-help">
<IconComponent
name="Info"
className="h-5 w-5 text-status-blue "
className="h-5 w-5 text-status-blue"
aria-hidden="true"
/>
</div>

View file

@ -39,7 +39,7 @@ export default function AlertDropdown({
<PopoverContent className="nocopy nowheel nopan nodelete nodrag noundo flex h-[500px] w-[500px] flex-col">
<div className="text-md flex flex-row justify-between pl-3 font-medium text-foreground">
Notifications
<div className="flex gap-3 pr-3 ">
<div className="flex gap-3 pr-3">
<button
className="text-foreground hover:text-status-red"
onClick={() => {

View file

@ -42,7 +42,7 @@ export default function NoticeAlert({
<div className="flex-shrink-0 cursor-help">
<IconComponent
name="Info"
className="h-5 w-5 text-status-blue "
className="h-5 w-5 text-status-blue"
aria-hidden="true"
/>
</div>

View file

@ -81,8 +81,8 @@ export default function ImageViewer({ image }) {
}
return image === "" ? (
<div className="align-center flex h-full w-full flex-col justify-center gap-5 rounded-md border border-border bg-muted">
<div className="align-center flex justify-center gap-2 ">
<div className="align-center flex h-full w-full flex-col justify-center gap-5 rounded-md border border-border bg-muted">
<div className="align-center flex justify-center gap-2">
<ForwardedIconComponent name="Image" />
{IMGViewErrorTitle}
</div>
@ -95,10 +95,10 @@ export default function ImageViewer({ image }) {
) : (
<>
<div className="align-center my-2 mb-4 flex w-full justify-center">
<div className="shadow-round-btn-shadow hover:shadow-round-btn-shadow flex w-[50%] items-center justify-center rounded-sm border bg-muted shadow-md transition-all">
<div className="shadow-round-btn-shadow hover:shadow-round-btn-shadow flex w-[50%] items-center justify-center rounded-sm border bg-muted shadow-md transition-all">
<button
id="zoom-in-button"
className="relative inline-flex w-full w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-hover"
>
<ForwardedIconComponent
name="ZoomIn"
@ -110,7 +110,7 @@ export default function ImageViewer({ image }) {
</div>
<button
id="zoom-out-button"
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-hover"
>
<ForwardedIconComponent
name="ZoomOut"
@ -122,7 +122,7 @@ export default function ImageViewer({ image }) {
</div>
<button
id="home-button"
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-hover"
>
<ForwardedIconComponent
name="RotateCcw"
@ -134,7 +134,7 @@ export default function ImageViewer({ image }) {
</div>
<button
id="full-page-button"
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-hover"
>
<ForwardedIconComponent
name="Maximize2"
@ -147,7 +147,7 @@ export default function ImageViewer({ image }) {
<button
onClick={download}
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-hover"
>
<ForwardedIconComponent
name="ArrowDownToLine"
@ -156,7 +156,7 @@ export default function ImageViewer({ image }) {
</button>
</div>
</div>
<div id="canvas" ref={viewerRef} className={`h-[90%] w-full `} />
<div id="canvas" ref={viewerRef} className={`h-[90%] w-full`} />
</>
);
}

View file

@ -92,7 +92,7 @@ export default function AddNewVariableButton({
<span className="pr-2"> Create Variable </span>
<ForwardedIconComponent
name="Globe"
className="h-6 w-6 pl-1 text-primary "
className="h-6 w-6 pl-1 text-primary"
aria-hidden="true"
/>
</BaseModal.Header>

View file

@ -262,10 +262,7 @@ export default function CollectionCardComponent({
)}
<ShadTooltip content="Likes">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent
name="Heart"
className={cn("h-4 w-4 ")}
/>
<IconComponent name="Heart" className={cn("h-4 w-4")} />
<span data-testid={`likes-${data.name}`}>
{likes_count ?? 0}
</span>
@ -428,7 +425,7 @@ export default function CollectionCardComponent({
name="Trash2"
className={cn(
"h-5 w-5",
!authorized ? " text-ring" : ""
!authorized ? "text-ring" : ""
)}
/>
</Button>
@ -463,7 +460,7 @@ export default function CollectionCardComponent({
liked_by_user
? "fill-destructive stroke-destructive"
: "",
!authorized ? " text-ring" : ""
!authorized ? "text-ring" : ""
)}
/>
</Button>
@ -501,7 +498,7 @@ export default function CollectionCardComponent({
}
className={cn(
loading ? "h-5 w-5 animate-spin" : "h-5 w-5",
!authorized ? " text-ring" : ""
!authorized ? "text-ring" : ""
)}
/>
</Button>

View file

@ -62,9 +62,9 @@ export default function FlowToolbar(): JSX.Element {
<button
disabled={!hasApiKey || !validApiKey || !hasStore}
className={classNames(
"relative inline-flex h-full w-full items-center justify-center gap-[4px] bg-muted px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-background hover:bg-hover ",
"relative inline-flex h-full w-full items-center justify-center gap-[4px] bg-muted px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-background hover:bg-hover",
!hasApiKey || !validApiKey || !hasStore
? " button-disable text-muted-foreground "
? "button-disable text-muted-foreground"
: ""
)}
>
@ -105,28 +105,28 @@ export default function FlowToolbar(): JSX.Element {
>
<div
className={
"shadow-round-btn-shadow hover:shadow-round-btn-shadow message-button-position flex items-center justify-center gap-7 rounded-sm border bg-muted shadow-md transition-all"
"shadow-round-btn-shadow hover:shadow-round-btn-shadow message-button-position flex items-center justify-center gap-7 rounded-sm border bg-muted shadow-md transition-all"
}
>
<div className="flex">
<div className="flex h-full w-full gap-1 rounded-sm transition-all">
<div className="flex h-full w-full gap-1 rounded-sm transition-all">
{hasIO ? (
<IOModal open={open} setOpen={setOpen} disable={!hasIO}>
<div className="relative inline-flex w-full items-center justify-center gap-1 px-5 py-3 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-hover">
<div className="relative inline-flex w-full items-center justify-center gap-1 px-5 py-3 text-sm font-semibold transition-all duration-500 ease-in-out hover:bg-hover">
<ForwardedIconComponent
name="BotMessageSquareIcon"
className={" h-5 w-5 transition-all"}
className={"h-5 w-5 transition-all"}
/>
Playground
</div>
</IOModal>
) : (
<div
className={`relative inline-flex w-full cursor-not-allowed items-center justify-center gap-1 px-5 py-3 text-sm font-semibold text-muted-foreground transition-all duration-150 ease-in-out ease-in-out`}
className={`relative inline-flex w-full cursor-not-allowed items-center justify-center gap-1 px-5 py-3 text-sm font-semibold text-muted-foreground transition-all duration-150 ease-in-out`}
>
<ForwardedIconComponent
name="BotMessageSquareIcon"
className={" h-5 w-5 transition-all"}
className={"h-5 w-5 transition-all"}
/>
Playground
</div>
@ -149,7 +149,7 @@ export default function FlowToolbar(): JSX.Element {
>
<ForwardedIconComponent
name="Code2"
className={" h-5 w-5"}
className={"h-5 w-5"}
/>
API
</div>
@ -163,8 +163,8 @@ export default function FlowToolbar(): JSX.Element {
<div
className={`side-bar-button ${
!hasApiKey || !validApiKey || !hasStore
? " cursor-not-allowed"
: " cursor-pointer"
? "cursor-not-allowed"
: "cursor-pointer"
}`}
>
{ModalMemo}

View file

@ -32,7 +32,7 @@ export default function CodeAreaComponent({
}, [value]);
return (
<div className={disabled ? "pointer-events-none w-full " : " w-full"}>
<div className={disabled ? "pointer-events-none w-full" : "w-full"}>
<CodeAreaModal
open={open}
setOpen={setOpen}
@ -53,8 +53,8 @@ export default function CodeAreaComponent({
className={
editNode
? "input-edit-node input-dialog"
: (disabled ? " input-disable input-ring " : "") +
" primary-input text-muted-foreground "
: (disabled ? "input-disable input-ring " : "") +
" primary-input text-muted-foreground"
}
>
{myValue !== "" ? myValue : "Type something..."}

View file

@ -98,7 +98,7 @@ export default function CodeTabsComponent({
value={activeTab}
className={
"api-modal-tabs inset-0 m-0 " +
(isMessage ? "dark " : "") +
(isMessage ? "dark" : "") +
(dark && isMessage ? "bg-background" : "")
}
onValueChange={(value) => {

View file

@ -9,7 +9,7 @@ export default function CrashErrorComponent({
}: crashComponentPropsType): JSX.Element {
return (
<div className="z-50 flex h-screen w-screen items-center justify-center bg-foreground bg-opacity-50">
<div className="flex h-screen w-screen flex-col bg-background text-start shadow-lg">
<div className="flex h-screen w-screen flex-col bg-background text-start shadow-lg">
<div className="m-auto grid w-1/2 justify-center gap-5 text-center">
<Card className="p-8">
<CardHeader>
@ -31,7 +31,7 @@ export default function CrashErrorComponent({
href="https://github.com/langflow-ai/langflow/issues"
target="_blank"
rel="noopener noreferrer"
className="font-medium hover:underline "
className="font-medium hover:underline"
>
GitHub Issues
</a>{" "}

View file

@ -32,7 +32,7 @@ function CsvOutputComponent({
if (!file) {
return (
<div className=" align-center flex h-full w-full flex-col items-center justify-center gap-5">
<div className="align-center flex h-full w-full flex-col items-center justify-center gap-5">
<div className="align-center flex w-full justify-center gap-2">
<ForwardedIconComponent name="Table" />
{CSVViewErrorTitle}
@ -81,9 +81,9 @@ function CsvOutputComponent({
}, [separator]);
return (
<div className=" h-full rounded-md border bg-muted">
<div className="h-full rounded-md border bg-muted">
{status === "nodata" && (
<div className=" align-center flex h-full w-full flex-col items-center justify-center gap-5">
<div className="align-center flex h-full w-full flex-col items-center justify-center gap-5">
<div className="align-center flex w-full justify-center gap-2">
<ForwardedIconComponent name="Table" />
{CSVViewErrorTitle}
@ -96,7 +96,7 @@ function CsvOutputComponent({
</div>
)}
{status === "error" && (
<div className=" align-center flex h-full w-full flex-col items-center justify-center gap-5">
<div className="align-center flex h-full w-full flex-col items-center justify-center gap-5">
<div className="align-center flex w-full justify-center gap-2">
<ForwardedIconComponent name="Table" />
{CSVViewErrorTitle}
@ -125,7 +125,7 @@ function CsvOutputComponent({
</div>
)}
{status === "loading" && (
<div className=" flex h-full w-full items-center justify-center align-middle">
<div className="flex h-full w-full items-center justify-center align-middle">
<Loading />
</div>
)}

View file

@ -26,7 +26,7 @@ export default function DropdownButton({
id="new-project-btn"
variant="primary"
className={
"relative" + dropdownOptions ? " pl-[12px]" : " pl-[12px] pr-10"
"relative" + dropdownOptions ? "pl-[12px]" : "pl-[12px] pr-10"
}
onClick={(event) => {
event.stopPropagation();

View file

@ -78,7 +78,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
</Label>
<Label>
<div className="edit-flow-arrangement mt-3">
<span className="font-medium ">
<span className="font-medium">
Description{setDescription ? " (optional)" : ":"}
</span>
</div>

View file

@ -84,7 +84,7 @@ export default function CollectionCardComponent({
tabIndex={-1}
variant="outline"
size="sm"
className="whitespace-nowrap "
className="whitespace-nowrap"
>
<IconComponent
name="ExternalLink"

View file

@ -9,10 +9,11 @@ import {
import { useNavigate } from "react-router-dom";
import { UPLOAD_ERROR_ALERT } from "../../../../constants/alerts_constants";
import { IS_MAC, SAVED_HOVER } from "../../../../constants/constants";
import { SAVED_HOVER } from "../../../../constants/constants";
import ExportModal from "../../../../modals/exportModal";
import FlowLogsModal from "../../../../modals/flowLogsModal";
import FlowSettingsModal from "../../../../modals/flowSettingsModal";
import ToolbarSelectItem from "../../../../pages/FlowPage/components/nodeToolbarComponent/toolbarSelectItem";
import useAlertStore from "../../../../stores/alertStore";
import useFlowStore from "../../../../stores/flowStore";
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
@ -96,10 +97,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
}}
className="cursor-pointer"
>
<IconComponent
name="Settings2"
className="header-menu-options "
/>
<IconComponent name="Settings2" className="header-menu-options" />
Settings
</DropdownMenuItem>
<DropdownMenuItem
@ -110,7 +108,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
>
<IconComponent
name="ScrollText"
className="header-menu-options "
className="header-menu-options"
/>
Logs
</DropdownMenuItem>
@ -127,7 +125,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
);
}}
>
<IconComponent name="FileUp" className="header-menu-options " />
<IconComponent name="FileUp" className="header-menu-options" />
Import
</DropdownMenuItem>
<ExportModal>
@ -145,21 +143,15 @@ export const MenuBar = ({}: {}): JSX.Element => {
}}
className="cursor-pointer"
>
<IconComponent name="Undo" className="header-menu-options " />
Undo
{IS_MAC ? (
<IconComponent
name="Command"
className="absolute right-[1.15rem] top-[0.65em] h-3.5 w-3.5 stroke-2"
/>
) : (
<span className="absolute right-[1.15rem] top-[0.40em] stroke-2">
{
shortcuts.find((s) => s.name.toLowerCase() === "undo")
?.shortcut
}
</span>
)}
<ToolbarSelectItem
value="Undo"
icon="Undo"
dataTestId=""
shortcut={
shortcuts.find((s) => s.name.toLowerCase() === "undo")
?.shortcut!
}
/>
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
@ -167,21 +159,15 @@ export const MenuBar = ({}: {}): JSX.Element => {
}}
className="cursor-pointer"
>
<IconComponent name="Redo" className="header-menu-options " />
Redo
{IS_MAC ? (
<IconComponent
name="Command"
className="absolute right-[1.15rem] top-[0.65em] h-3.5 w-3.5 stroke-2"
/>
) : (
<span className="absolute right-[1.15rem] top-[0.40em] stroke-2">
{
shortcuts.find((s) => s.name.toLowerCase() === "redo")
?.shortcut
}
</span>
)}
<ToolbarSelectItem
value="Redo"
icon="Redo"
dataTestId=""
shortcut={
shortcuts.find((s) => s.name.toLowerCase() === "redo")
?.shortcut!
}
/>
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {

View file

@ -230,7 +230,7 @@ export default function Header(): JSX.Element {
userData?.profile_image ?? "Space/046-rocket.svg"
}` ?? profileCircle
}
className="h-5 w-5 focus-visible:outline-0 "
className="h-5 w-5 focus-visible:outline-0"
/>
{userData?.username ?? "User"}

View file

@ -93,9 +93,9 @@ const CustomInputPopover = ({
(!setSelectedOption || selectedOption === "") &&
!pwdVisible &&
value !== ""
? " text-clip password "
? "text-clip password"
: "",
editNode ? " input-edit-node " : "",
editNode ? "input-edit-node" : "",
password && (setSelectedOption || setSelectedOptions)
? "pr-[62.9px]"
: "",

View file

@ -67,9 +67,9 @@ export default function InputComponent({
required={required}
className={classNames(
password && !pwdVisible && value !== ""
? " text-clip password "
? "text-clip password"
: "",
editNode ? " input-edit-node " : "",
editNode ? "input-edit-node" : "",
password && editNode ? "pr-8" : "",
password && !editNode ? "pr-10" : "",
className!

View file

@ -117,7 +117,7 @@ export default function InputFileComponent({
name="FileSearch2"
className={
"icons-parameters-comp" +
(disabled ? " text-ring " : " hover:text-accent-foreground")
(disabled ? " text-ring" : " hover:text-accent-foreground")
}
/>
)}

View file

@ -34,8 +34,8 @@ export default function PaginatorComponent({
<div
className={
storeComponent
? "flex items-center lg:space-x-8 "
: "flex items-center space-x-6 lg:space-x-8 "
? "flex items-center lg:space-x-8"
: "flex items-center space-x-6 lg:space-x-8"
}
>
<div className="flex items-center space-x-2">

View file

@ -110,7 +110,7 @@ export default function PdfViewer({ pdf }: { pdf: string }): JSX.Element {
"absolute z-50 pb-5 " + (showControl && numPages > 0 ? "" : " hidden")
}
>
<div className=" flex w-min items-center justify-center gap-0.5 rounded-xl bg-secondary px-2 align-middle">
<div className="flex w-min items-center justify-center gap-0.5 rounded-xl bg-secondary px-2 align-middle">
<button
type="button"
disabled={pageNumber <= 1}

View file

@ -23,7 +23,7 @@ export default function PromptAreaComponent({
}, [disabled]);
return (
<div className={disabled ? "pointer-events-none w-full " : " w-full"}>
<div className={disabled ? "pointer-events-none w-full" : "w-full"}>
<GenericModal
id={id}
field_name={field_name}
@ -43,8 +43,8 @@ export default function PromptAreaComponent({
className={
editNode
? "input-edit-node input-dialog"
: (disabled ? " input-disable text-ring " : "") +
" primary-input text-muted-foreground "
: (disabled ? "input-disable text-ring " : "") +
" primary-input text-muted-foreground"
}
>
{value !== "" ? value : "Type your prompt here..."}

View file

@ -12,21 +12,22 @@ export default function RenderIcons({
shortcutWPlus: string[];
}): JSX.Element {
return hasShift ? (
<span className="flex gap-0.5 text-xs">
<span className="flex items-center justify-center gap-0.5 text-xs">
{isMac ? (
<ForwardedIconComponent name="Command" className="h-3 w-3" />
) : (
filteredShortcut[0]
)}
<ForwardedIconComponent name="ArrowBigUp" className=" h-4 w-4" />
<ForwardedIconComponent name="ArrowBigUp" className="h-4 w-4" />
{filteredShortcut.map((key, idx) => {
if (idx > 0) {
return <span className=""> {key.toUpperCase()} </span>;
return key.toUpperCase();
}
return null;
})}
</span>
) : (
<span className="flex gap-1 text-xs">
<span className="flex items-center justify-center gap-0.5 text-xs">
{shortcutWPlus[0].toLowerCase() === "space" ? (
"Space"
) : shortcutWPlus[0].length <= 1 ? (
@ -34,12 +35,17 @@ export default function RenderIcons({
) : isMac ? (
<ForwardedIconComponent name="Command" className="h-3 w-3" />
) : (
shortcutWPlus[0]
<span className="flex items-center">{shortcutWPlus[0]}</span>
)}
{shortcutWPlus.map((key, idx) => {
if (idx > 0) {
return <span className=""> {key.toUpperCase()} </span>;
return (
<span key={idx} className="flex items-center">
{key.toUpperCase()}
</span>
);
}
return null;
})}
</span>
);

View file

@ -10,7 +10,7 @@ export default function ShadTooltip({
styleClasses,
delayDuration = 500,
}: ShadToolTipType): JSX.Element {
return (
return content ? (
<Tooltip defaultOpen={!children} delayDuration={delayDuration}>
<TooltipTrigger asChild={asChild}>{children}</TooltipTrigger>
<TooltipContent
@ -22,5 +22,7 @@ export default function ShadTooltip({
{content}
</TooltipContent>
</Tooltip>
) : (
<>{children}</>
);
}

View file

@ -293,7 +293,7 @@ const SideBarFoldersButtonsComponent = ({
>
<IconComponent
name={"trash"}
className=" w-4 stroke-[1.5]"
className="w-4 stroke-[1.5]"
/>
</Button>
)}
@ -309,7 +309,7 @@ const SideBarFoldersButtonsComponent = ({
>
<IconComponent
name={"Download"}
className=" w-4 stroke-[1.5] text-white "
className="w-4 stroke-[1.5] text-white"
/>
</Button>
</div>

View file

@ -84,8 +84,8 @@ export default function TableOptions({
<IconComponent
name="Trash2"
className={cn(
"h-5 w-5 text-primary transition-all",
!hasSelection ? "" : "hover:text-status-red "
"h-5 w-5 text-primary transition-all",
!hasSelection ? "" : "hover:text-status-red"
)}
/>
</Button>

View file

@ -2,7 +2,7 @@ import Loading from "../../../ui/loading";
export default function LoadingOverlay() {
return (
<div className=" flex h-full w-full items-center justify-center bg-background align-middle">
<div className="flex h-full w-full items-center justify-center bg-background align-middle">
<Loading />
</div>
);

View file

@ -45,7 +45,19 @@ export default function TableAutoCellRender({
"min-w-min bg-error-background text-error-foreground hover:bg-error-background",
)}
>
{value}
Success
</Badge>
);
} else if (value === "failure") {
return (
<Badge
variant="outline"
size="sq"
className={cn(
"min-w-min bg-error-background text-error-foreground hover:bg-error-background"
)}
>
Failure
</Badge>
);
} else {

View file

@ -33,7 +33,7 @@ export function TagsSelector({
className={
disabled
? "cursor-not-allowed"
: " overflow-hidden whitespace-nowrap"
: "overflow-hidden whitespace-nowrap"
}
onClick={() => {
updateTags(tag.name);

View file

@ -28,7 +28,7 @@ export default function TextAreaComponent({
data-testid={id}
value={value}
disabled={disabled}
className={editNode ? "input-edit-node w-full" : " w-full"}
className={editNode ? "input-edit-node w-full" : "w-full"}
placeholder={"Type something..."}
onChange={(event) => {
onChange(event.target.value);

View file

@ -34,7 +34,7 @@ const AccordionTrigger = React.forwardRef<
<div
className={cn(
"flex flex-1 cursor-pointer items-center justify-between py-4 text-sm font-medium transition-all [&[data-state=open]>svg]:rotate-180",
className,
className
)}
>
{children}
@ -46,7 +46,7 @@ const AccordionTrigger = React.forwardRef<
<ChevronDownIcon
className={cn(
"h-4 w-4 font-bold transition-transform duration-200",
disabled ? "text-muted-foreground" : "text-primary",
disabled ? "text-muted-foreground" : "text-primary"
)}
/>
</ShadTooltip>
@ -64,7 +64,7 @@ const AccordionContent = React.forwardRef<
ref={ref}
className={cn(
"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
className,
className
)}
{...props}
>

View file

@ -69,7 +69,7 @@ const CardFooter = React.forwardRef<
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(" flex items-center p-4 pt-0", className)}
className={cn("flex items-center p-4 pt-0", className)}
{...props}
/>
));

View file

@ -23,7 +23,7 @@ const AccordionTrigger = React.forwardRef<
<AccordionPrimitive.Trigger asChild ref={ref} {...props}>
<div
className={cn(
" flex flex-1 cursor-pointer items-center justify-between border-[1px] py-2 text-sm font-medium data-[state=closed]:rounded-md data-[state=open]:rounded-t-md data-[state=open]:border-b-0 data-[state=open]:bg-muted [&[data-state=open]>svg]:rotate-180",
"flex flex-1 cursor-pointer items-center justify-between border-[1px] py-2 text-sm font-medium data-[state=closed]:rounded-md data-[state=open]:rounded-t-md data-[state=open]:border-b-0 data-[state=open]:bg-muted [&[data-state=open]>svg]:rotate-180",
className
)}
>

View file

@ -64,7 +64,7 @@ const DialogHeader = ({
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
"flex flex-col space-y-1 text-center sm:text-left",
className
)}
{...props}

View file

@ -48,7 +48,7 @@ export default function FoldersModal({
</span>
<ForwardedIconComponent
name="Plus"
className="h-6 w-6 pl-1 text-primary "
className="h-6 w-6 pl-1 text-primary"
aria-hidden="true"
/>
</BaseModal.Header>

View file

@ -136,7 +136,7 @@ export default function IOFileInput({ field, updateValue }: IOFileInputProps) {
</>
) : image ? (
<img
className="order-last h-12 w-12 rounded-full object-cover "
className="order-last h-12 w-12 rounded-full object-cover"
src={image ?? ""}
/>
) : (

View file

@ -58,7 +58,7 @@ export default function IOFieldView({
return (
<Textarea
className={`w-full custom-scroll ${
left ? " min-h-32" : " h-full"
left ? "min-h-32" : "h-full"
}`}
placeholder={"Enter text..."}
value={node.data.node!.template["input_value"].value}
@ -142,7 +142,7 @@ export default function IOFieldView({
return (
<Textarea
className={`w-full custom-scroll ${
left ? " min-h-32" : " h-full"
left ? "min-h-32" : "h-full"
}`}
placeholder={"Enter text..."}
value={node.data.node!.template["input_value"]}
@ -266,7 +266,7 @@ export default function IOFieldView({
return (
<Textarea
className={`w-full custom-scroll ${
left ? " min-h-32" : " h-full"
left ? "min-h-32" : "h-full"
}`}
placeholder={"Empty"}
// update to real value on flowPool

View file

@ -27,7 +27,7 @@ const ButtonSendWrapper = ({
"form-modal-send-button",
noInput
? "bg-high-indigo text-background"
: chatValue === ""
: chatValue
? "text-primary"
: "bg-chat-send text-background"
)}
@ -64,7 +64,7 @@ const ButtonSendWrapper = ({
>
<IconComponent
name="LucideSend"
className="form-modal-send-icon "
className="form-modal-send-icon"
aria-hidden="true"
/>
</Case>

View file

@ -162,7 +162,7 @@ export default function ChatMessage({
)}
{chat.thought && chat.thought !== "" && !hidden && (
<SanitizedHTMLWrapper
className=" form-modal-chat-thought"
className="form-modal-chat-thought"
content={convert.toHtml(chat.thought)}
onClick={() => setHidden((prev) => !prev)}
/>
@ -187,8 +187,7 @@ export default function ChatMessage({
<Markdown
remarkPlugins={[remarkGfm, remarkMath]}
rehypePlugins={[rehypeMathjax]}
className="markdown prose flex flex-col text-primary word-break-break-word
dark:prose-invert"
className="markdown prose flex flex-col text-primary word-break-break-word dark:prose-invert"
components={{
pre({ node, ...props }) {
return <>{props.children}</>;
@ -319,7 +318,7 @@ dark:prose-invert"
{chatMessage}
</span>
{chat.files && (
<div className="my-2 flex flex-col gap-5">
<div className="my-2 flex flex-col gap-5">
{chat.files.map((file, index) => {
return (
<FileCardWrapper

View file

@ -11,7 +11,7 @@ export default function DownloadButton({
if (isHovered) {
return (
<div
className={`absolute right-1 top-1 rounded-md bg-muted text-sm font-bold text-foreground `}
className={`absolute right-1 top-1 rounded-md bg-muted text-sm font-bold text-foreground`}
>
<Button
variant={"none"}

View file

@ -45,7 +45,7 @@ export default function FileCard({
<img
src={imgSrc}
alt="generated image"
className="m-0 h-auto w-auto rounded-lg border border-border p-0 transition-all"
className="m-0 h-auto w-auto rounded-lg border border-border p-0 transition-all"
/>
<DownloadButton
isHovered={isHovered}

View file

@ -27,10 +27,10 @@ export default function FilePreview({
<div className="relative inline-block">
{loading ? (
isImage ? (
<div className="flex h-20 w-20 items-center justify-center rounded-md border border-ring bg-background ">
<div className="flex h-20 w-20 items-center justify-center rounded-md border border-ring bg-background">
<svg
aria-hidden="true"
className={`h-10 w-10 animate-spin fill-black text-muted`}
className={`h-10 w-10 animate-spin fill-black text-muted`}
viewBox="0 0 100 101"
fill="none"
xmlns="http://www.w3.org/2000/svg"
@ -49,7 +49,7 @@ export default function FilePreview({
<div
className={`relative ${
isImage ? "h-20 w-20" : "h-20 w-80"
} cursor-wait rounded-lg border border-ring bg-background transition duration-300 ${
} cursor-wait rounded-lg border border-ring bg-background transition duration-300 ${
isHovered ? "shadow-md" : ""
}`}
>
@ -68,7 +68,7 @@ export default function FilePreview({
<div
className={`relative mt-2 ${
isImage ? "h-20 w-20" : "h-20 w-80"
} cursor-pointer rounded-lg border border-ring bg-background transition duration-300 ${
} cursor-pointer rounded-lg border border-ring bg-background transition duration-300 ${
isHovered ? "shadow-md" : ""
}`}
onMouseEnter={() => setIsHovered(true)}
@ -93,7 +93,7 @@ export default function FilePreview({
<div
className={`absolute ${
isImage ? "bottom-16 left-16" : "bottom-16 left-[19em]"
} flex h-5 w-5 items-center justify-center`}
} flex h-5 w-5 items-center justify-center`}
>
<div
className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-gray-200 p-2 transition-all"

View file

@ -58,7 +58,7 @@ export default function ChatView({
//
.filter(
(output) =>
output.data.message || (!output.data.message && output.artifacts),
output.data.message || (!output.data.message && output.artifacts)
)
.map((output, index) => {
try {
@ -78,7 +78,10 @@ export default function ChatView({
sender === "Machine" || sender === null || sender === undefined;
return {
isSend: !is_ai,
message: message,
message:
message === "" || !message
? "No input message provided."
: message,
sender_name,
componentId: output.id,
stream_url: stream_url,
@ -138,7 +141,7 @@ export default function ChatView({
function updateChat(
chat: ChatMessageType,
message: string,
stream_url?: string,
stream_url?: string
) {
chat.message = message;
updateFlowPool(chat.componentId, {
@ -154,7 +157,7 @@ export default function ChatView({
setIsDragging,
setFiles,
currentFlowId,
setErrorData,
setErrorData
);
return (
@ -205,7 +208,7 @@ export default function ChatView({
<span>
<IconComponent
name="MessageSquareMore"
className="mx-1 inline h-5 w-5 animate-bounce "
className="mx-1 inline h-5 w-5 animate-bounce"
/>
</span>{" "}
{CHAT_SECOND_INITIAL_TEXT}

View file

@ -68,7 +68,7 @@ const Header: React.FC<{
}> = ({ children, description }: modalHeaderType): JSX.Element => {
return (
<DialogHeader>
<DialogTitle className="line-clamp-1 flex items-center">
<DialogTitle className="line-clamp-1 flex items-center pb-0.5">
{children}
</DialogTitle>
<DialogDescription className="line-clamp-2">

View file

@ -153,7 +153,7 @@ export default function CodeAreaModal({
<span className="pr-2"> {EDIT_CODE_TITLE} </span>
<IconComponent
name="prompts"
className="h-6 w-6 pl-1 text-primary "
className="h-6 w-6 pl-1 text-primary"
aria-hidden="true"
/>
</BaseModal.Header>

View file

@ -54,12 +54,12 @@ export default function DictAreaModal({
</span>
<IconComponent
name="BookMarked"
className="h-6 w-6 pl-1 text-primary "
className="h-6 w-6 pl-1 text-primary"
aria-hidden="true"
/>
</BaseModal.Header>
<BaseModal.Content>
<div className="flex h-full w-full flex-col transition-all ">
<div className="flex h-full w-full flex-col transition-all">
<JsonView
theme="vscode"
dark={isDark}

View file

@ -92,11 +92,11 @@ const ExportModal = forwardRef(
setChecked(event);
}}
/>
<label htmlFor="terms" className="export-modal-save-api text-sm ">
<label htmlFor="terms" className="export-modal-save-api text-sm">
{SAVE_WITH_API_CHECKBOX}
</label>
</div>
<span className="mt-1 text-xs text-destructive ">
<span className="mt-1 text-xs text-destructive">
{ALERT_SAVE_WITH_API}
</span>
</BaseModal.Content>

View file

@ -63,7 +63,7 @@ export default function FlowSettingsModal({
>
<BaseModal.Header description={SETTINGS_DIALOG_SUBTITLE}>
<span className="pr-2">Settings</span>
<IconComponent name="Settings2" className="mr-2 h-4 w-4 " />
<IconComponent name="Settings2" className="mr-2 h-4 w-4" />
</BaseModal.Header>
<BaseModal.Content>
<EditFlowSettings

View file

@ -48,7 +48,7 @@ export default function FoldersModal({
</span>
<ForwardedIconComponent
name={folderToEdit ? "Pencil" : "Plus"}
className="h-6 w-6 pl-1 text-primary "
className="h-6 w-6 pl-1 text-primary"
aria-hidden="true"
/>
</BaseModal.Header>

View file

@ -83,7 +83,7 @@ export default function GenericModal({
}
const filteredWordsHighlight = new Set(
matches.filter((word) => !invalid_chars.includes(word)),
matches.filter((word) => !invalid_chars.includes(word))
);
setWordsHighlight(filteredWordsHighlight);
@ -134,7 +134,7 @@ export default function GenericModal({
// to the first key of the custom_fields object
if (field_name === "") {
field_name = Array.isArray(
apiReturn.data?.frontend_node?.custom_fields?.[""],
apiReturn.data?.frontend_node?.custom_fields?.[""]
)
? apiReturn.data?.frontend_node?.custom_fields?.[""][0] ?? ""
: apiReturn.data?.frontend_node?.custom_fields?.[""] ?? "";
@ -200,7 +200,7 @@ export default function GenericModal({
</span>
<IconComponent
name={myModalTitle === "Edit Prompt" ? "TerminalSquare" : "FileText"}
className="h-6 w-6 pl-1 text-primary "
className="h-6 w-6 pl-1 text-primary"
aria-hidden="true"
/>
</BaseModal.Header>
@ -208,7 +208,7 @@ export default function GenericModal({
<div
className={classNames(
!isEdit ? "rounded-lg border" : "",
"flex h-full w-full",
"flex h-full w-full"
)}
>
{type === TypeModal.PROMPT && isEdit && !readonly ? (
@ -265,15 +265,15 @@ export default function GenericModal({
<div className="flex w-full shrink-0 items-end justify-between">
<div className="mb-auto flex-1">
{type === TypeModal.PROMPT && (
<div className=" mr-2">
<div className="mr-2">
<div
ref={divRef}
className="max-h-20 overflow-y-auto custom-scroll"
>
<div className="flex flex-wrap items-center">
<div className="flex flex-wrap items-center gap-2">
<IconComponent
name="Braces"
className=" -ml-px mr-1 flex h-4 w-4 text-primary"
className="flex h-4 w-4 text-primary"
/>
<span className="text-md font-semibold text-primary">
Prompt Variables:
@ -289,7 +289,7 @@ export default function GenericModal({
key={index}
variant="gray"
size="md"
className="m-1 max-w-[40vw] cursor-default truncate p-2.5 text-sm"
className="max-w-[40vw] cursor-default truncate p-1 text-sm"
>
<div className="relative bottom-[1px]">
<span id={"badge" + index.toString()}>

View file

@ -24,7 +24,7 @@ export default function NewFlowModal({
</span>
</BaseModal.Header>
<BaseModal.Content>
<div className=" mb-5 grid h-fit w-full grid-cols-3 gap-4 overflow-auto pb-6 custom-scroll">
<div className="mb-5 grid h-fit w-full grid-cols-3 gap-4 overflow-auto pb-6 custom-scroll">
<NewFlowCardComponent />
{examples.find((e) => e.name == "Basic Prompting (Hello, World)") && (

View file

@ -182,7 +182,7 @@ export default function ShareModal({
current?
</span>
<br></br>
<span className=" text-xs text-destructive ">
<span className="text-xs text-destructive">
Note: This action is irreversible.
</span>
</ConfirmationModal.Content>
@ -253,11 +253,11 @@ export default function ShareModal({
}}
data-testid="public-checkbox"
/>
<label htmlFor="public" className="export-modal-save-api text-sm ">
<label htmlFor="public" className="export-modal-save-api text-sm">
Set {nameComponent} status to public
</label>
</div>
<span className=" text-xs text-destructive ">
<span className="text-xs text-destructive">
<b>Attention:</b> API keys in specified fields are automatically
removed upon sharing.
</span>

View file

@ -284,7 +284,7 @@ export default function AdminPage() {
(loadingUsers ? " border-0" : "")
}
>
<Table className={"table-fixed outline-1 "}>
<Table className={"table-fixed outline-1"}>
<TableHeader
className={
loadingUsers ? "hidden" : "table-fixed bg-muted outline-1"
@ -297,7 +297,7 @@ export default function AdminPage() {
<TableHead className="h-10">Superuser</TableHead>
<TableHead className="h-10">Created At</TableHead>
<TableHead className="h-10">Updated At</TableHead>
<TableHead className="h-10 w-[100px] text-right"></TableHead>
<TableHead className="h-10 w-[100px] text-right"></TableHead>
</TableRow>
</TableHeader>
{!loadingUsers && (
@ -380,7 +380,7 @@ export default function AdminPage() {
</ConfirmationModal.Trigger>
</ConfirmationModal>
</TableCell>
<TableCell className="truncate py-2 ">
<TableCell className="truncate py-2">
{
new Date(user.create_at!)
.toISOString()

View file

@ -13,7 +13,7 @@ const ConnectionLineComponent = ({
fill="none"
// ! Replace hash # colors here
strokeWidth={1.5}
className="animated stroke-connection "
className="animated stroke-connection"
d={`M${fromX},${fromY} C ${fromX} ${toY} ${fromX} ${toY} ${toX},${toY}`}
style={connectionLineStyle}
/>

View file

@ -495,10 +495,7 @@ export default function Page({
>
<Background className="" />
{!view && (
<Controls
className="fill-foreground stroke-foreground text-primary [&>button]:border-b-border
[&>button]:bg-muted hover:[&>button]:bg-border"
></Controls>
<Controls className="fill-foreground stroke-foreground text-primary [&>button]:border-b-border [&>button]:bg-muted hover:[&>button]:bg-border"></Controls>
)}
<SelectionMenu
lastSelection={lastSelection}

View file

@ -18,7 +18,7 @@ export default function ParentDisclosureComponent({
data-testid={testId}
>
<div className="flex gap-4">
<span className="parent-disclosure-title ">{title}</span>
<span className="parent-disclosure-title">{title}</span>
</div>
<div className="components-disclosure-div">
{buttons.map((btn, index) => (

View file

@ -58,7 +58,7 @@ export default function SelectionMenu({
<div
className={
"duration-400 h-10 w-24 rounded-md border border-indigo-300 bg-background px-2.5 text-primary shadow-inner transition-all ease-in-out" +
(isTransitioning ? " opacity-100" : " opacity-0 ")
(isTransitioning ? " opacity-100" : " opacity-0")
}
>
<button

View file

@ -199,7 +199,7 @@ export default function ExtraSidebar(): JSX.Element {
className={classNames(
"extra-side-bar-buttons gap-[4px] text-sm font-semibold",
!hasApiKey || !validApiKey || !hasStore
? "button-disable cursor-default text-muted-foreground"
? "button-disable cursor-default text-muted-foreground"
: ""
)}
>
@ -262,7 +262,7 @@ export default function ExtraSidebar(): JSX.Element {
}}
/>
<div
className="search-icon "
className="search-icon"
onClick={() => {
if (search) {
setFilterData(data);

View file

@ -117,7 +117,7 @@ export const SidebarDraggableComponent = forwardRef(
<div ref={popoverRef}>
<IconComponent
name="Menu"
className="side-bar-components-icon "
className="side-bar-components-icon"
/>
<SelectTrigger></SelectTrigger>
<SelectContent

View file

@ -455,7 +455,7 @@ export default function NodeToolbarComponent({
<button
className={`${
isGroup ? "rounded-l-md" : ""
} relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10`}
} relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10`}
onClick={() => {
setShowModalAdvanced(true);
}}
@ -494,7 +494,7 @@ export default function NodeToolbarComponent({
>
<button
className={classNames(
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
)}
onClick={(event) => {
event.preventDefault();
@ -543,7 +543,7 @@ export default function NodeToolbarComponent({
<div
data-testid="more-options-modal"
className={classNames(
"relative -ml-px inline-flex h-8 w-[31px] items-center rounded-r-md bg-background text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
"relative -ml-px inline-flex h-8 w-[31px] items-center rounded-r-md bg-background text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
)}
>
<IconComponent
@ -710,11 +710,11 @@ export default function NodeToolbarComponent({
<div className="font-red flex text-status-red">
<IconComponent
name="Trash2"
className="relative top-0.5 mr-2 h-4 w-4 "
className="relative top-0.5 mr-2 h-4 w-4"
/>{" "}
<span className="">Delete</span>{" "}
<span
className={` absolute right-2 top-2 flex items-center justify-center rounded-sm px-1 py-[0.2] ${
className={`absolute right-2 top-2 flex items-center justify-center rounded-sm px-1 py-[0.2] ${
deleteIsFocus ? " " : "bg-muted"
}`}
>

View file

@ -1,5 +1,6 @@
import ForwardedIconComponent from "../../../../../components/genericIconComponent";
import RenderIcons from "../../../../../components/renderIconComponent";
import { IS_MAC } from "../../../../../constants/constants";
import { toolbarSelectItemProps } from "../../../../../types/components";
export default function ToolbarSelectItem({
@ -10,7 +11,6 @@ export default function ToolbarSelectItem({
ping,
shortcut,
}: toolbarSelectItemProps) {
const isMac = navigator.platform.toUpperCase().includes("MAC");
let hasShift = false;
const fixedShortcut = shortcut?.split("+");
fixedShortcut.forEach((key) => {
@ -28,20 +28,20 @@ export default function ToolbarSelectItem({
<div className={`flex ${style}`} data-testid={dataTestId}>
<ForwardedIconComponent
name={icon}
className={` mr-2 ${
className={`mr-2 ${
icon === "Share3"
? "absolute left-2 top-[0.25em] h-6 w-6"
? "absolute left-2 top-[0.25em] h-6 w-6"
: "mt-[0.15em] h-4 w-4"
} ${ping && "animate-pulse text-green-500"}`}
} ${ping && "animate-pulse text-green-500"}`}
/>
<span className={`${icon === "Share3" ? "ml-[1.8em]" : " "}`}>
{value}
</span>
<span
className={`absolute right-2 top-[0.43em] flex items-center rounded-sm bg-muted px-1.5 py-[0.1em] text-muted-foreground `}
className={`absolute right-2 top-[0.43em] flex items-center rounded-sm bg-muted px-1.5 py-[0.1em] text-muted-foreground`}
>
<RenderIcons
isMac={isMac}
isMac={IS_MAC}
hasShift={hasShift}
filteredShortcut={filteredShortcut}
shortcutWPlus={shortcutWPlus}

View file

@ -15,7 +15,7 @@ const EmptyComponent = ({}: EmptyComponentProps) => {
<>
<div className="mt-2 flex w-full items-center justify-center text-center">
<div className="flex-max-width h-full flex-col">
<div className="align-center flex w-full justify-center gap-1 ">
<div className="align-center flex w-full justify-center gap-1">
<span className="text-muted-foreground">
This folder is empty. New?
</span>

View file

@ -61,7 +61,7 @@ const InputSearchComponent = ({
>
<ForwardedIconComponent
name={loading ? "Loader2" : "Search"}
className={loading ? " animate-spin cursor-not-allowed" : ""}
className={loading ? "animate-spin cursor-not-allowed" : ""}
/>
</button>
</div>

View file

@ -62,8 +62,8 @@ const TabsSearchComponent = ({
className={
(tabActive === tabOption
? "border-b-2 border-primary p-3"
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
(loading ? " cursor-not-allowed " : "")
: "border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
(loading ? " cursor-not-allowed" : "")
}
>
{tabOption}

View file

@ -154,7 +154,7 @@ export default function EditShortcutButton({
<span className="pr-2"> Key Combination </span>
<ForwardedIconComponent
name="Keyboard"
className="h-6 w-6 pl-1 text-primary "
className="h-6 w-6 pl-1 text-primary"
aria-hidden="true"
/>
</BaseModal.Header>

View file

@ -53,7 +53,7 @@ export default function ShortcutsPage() {
}
return (
<div className="flex h-full w-full flex-col gap-6 ">
<div className="flex h-full w-full flex-col gap-6">
<div className="flex w-full items-center justify-between gap-4 space-y-0.5">
<div className="flex w-full flex-col">
<h2 className="flex items-center text-lg font-semibold tracking-tight">

View file

@ -222,8 +222,8 @@ export default function StorePage(): JSX.Element {
className={
(tabActive === "All"
? "border-b-2 border-primary p-3"
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
(loading ? " cursor-not-allowed " : "")
: "border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
(loading ? " cursor-not-allowed" : "")
}
>
All
@ -238,8 +238,8 @@ export default function StorePage(): JSX.Element {
className={
(tabActive === "Flows"
? "border-b-2 border-primary p-3"
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
(loading ? " cursor-not-allowed " : "")
: "border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
(loading ? " cursor-not-allowed" : "")
}
>
Flows
@ -254,8 +254,8 @@ export default function StorePage(): JSX.Element {
className={
(tabActive === "Components"
? "border-b-2 border-primary p-3"
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
(loading ? " cursor-not-allowed " : "")
: "border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
(loading ? " cursor-not-allowed" : "")
}
>
Components

View file

@ -4,7 +4,7 @@ const TextOutputView = ({ left, value }) => {
return (
<>
<Textarea
className={`w-full custom-scroll ${left ? " min-h-32" : " h-full"}`}
className={`w-full custom-scroll ${left ? "min-h-32" : "h-full"}`}
placeholder={"Empty"}
// update to real value on flowPool
value={value}

View file

@ -55,6 +55,68 @@ select:-webkit-autofill:focus {
width: 8px;
}
.ag-cell {
display: block;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ag-cell-focus {
border-radius: 0.375rem;
border: 1px solid #94a3b8 !important;
background-color: transparent !important;
text-align: left;
font-size: 0.875rem;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05) !important;
outline: none !important;
outline-color: transparent !important;
}
.ag-cell-focus:focus {
border-color: #94a3b8 !important;
box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.05) !important;
background-color: transparent !important;
outline: none !important;
outline-color: transparent !important;
}
input .ag-cell-edit-input {
border: 1px solid transparent !important;
outline: none !important;
outline-color: transparent !important;
}
input[class^="ag-"]:not([type]),
input[class^="ag-"][type="text"],
input[class^="ag-"][type="number"],
input[class^="ag-"][type="tel"],
input[class^="ag-"][type="date"],
input[class^="ag-"][type="datetime-local"],
textarea[class^="ag-"] {
border: 1px solid transparent !important;
outline: none !important;
outline-color: transparent !important;
-webkit-box-shadow: none !important; /* Safari and older Chrome versions */
-moz-box-shadow: none !important; /* Older Firefox versions */
box-shadow: none !important; /* Standard syntax */
}
input[class^="ag-"][type="text"]:focus,
input[class^="ag-"][type="number"]:focus,
input[class^="ag-"][type="tel"]:focus,
input[class^="ag-"][type="date"]:focus,
input[class^="ag-"][type="datetime-local"]:focus,
textarea[class^="ag-"]:focus {
border: 1px solid transparent !important;
outline-color: transparent !important;
outline: none !important;
-webkit-box-shadow: none !important; /* Safari and older Chrome versions */
-moz-box-shadow: none !important; /* Older Firefox versions */
box-shadow: none !important; /* Standard syntax */
}
.ace_scrollbar::-webkit-scrollbar-track {
background-color: hsl(var(--muted));
}