feat: Activate ruff rules UP(pyupgrade) (#3871)
* Activate ruff rules UP(pyupgrade) * Set ruff target version * Fix threading.Lock | None error Due to https://github.com/python/cpython/issues/114315 * Fix Text in custom component supported typed * Fix mypy issues --------- Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
parent
c567323413
commit
f8a2a7d3b8
186 changed files with 911 additions and 983 deletions
|
|
@ -4,7 +4,6 @@ import sys
|
||||||
import time
|
import time
|
||||||
import warnings
|
import warnings
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import httpx
|
import httpx
|
||||||
|
|
@ -84,7 +83,7 @@ def run(
|
||||||
workers: int = typer.Option(1, help="Number of worker processes.", envvar="LANGFLOW_WORKERS"),
|
workers: int = typer.Option(1, help="Number of worker processes.", envvar="LANGFLOW_WORKERS"),
|
||||||
timeout: int = typer.Option(300, help="Worker timeout in seconds.", envvar="LANGFLOW_WORKER_TIMEOUT"),
|
timeout: int = typer.Option(300, help="Worker timeout in seconds.", envvar="LANGFLOW_WORKER_TIMEOUT"),
|
||||||
port: int = typer.Option(7860, help="Port to listen on.", envvar="LANGFLOW_PORT"),
|
port: int = typer.Option(7860, help="Port to listen on.", envvar="LANGFLOW_PORT"),
|
||||||
components_path: Optional[Path] = typer.Option(
|
components_path: Path | None = typer.Option(
|
||||||
Path(__file__).parent / "components",
|
Path(__file__).parent / "components",
|
||||||
help="Path to the directory containing custom components.",
|
help="Path to the directory containing custom components.",
|
||||||
envvar="LANGFLOW_COMPONENTS_PATH",
|
envvar="LANGFLOW_COMPONENTS_PATH",
|
||||||
|
|
@ -93,7 +92,7 @@ def run(
|
||||||
env_file: Path = typer.Option(None, help="Path to the .env file containing environment variables."),
|
env_file: Path = typer.Option(None, help="Path to the .env file containing environment variables."),
|
||||||
log_level: str = typer.Option("critical", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"),
|
log_level: str = typer.Option("critical", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"),
|
||||||
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file.", envvar="LANGFLOW_LOG_FILE"),
|
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file.", envvar="LANGFLOW_LOG_FILE"),
|
||||||
cache: Optional[str] = typer.Option(
|
cache: str | None = typer.Option(
|
||||||
envvar="LANGFLOW_LANGCHAIN_CACHE",
|
envvar="LANGFLOW_LANGCHAIN_CACHE",
|
||||||
help="Type of cache to use. (InMemoryCache, SQLiteCache)",
|
help="Type of cache to use. (InMemoryCache, SQLiteCache)",
|
||||||
default=None,
|
default=None,
|
||||||
|
|
@ -161,7 +160,7 @@ def run(
|
||||||
health_check_max_retries=health_check_max_retries,
|
health_check_max_retries=health_check_max_retries,
|
||||||
)
|
)
|
||||||
# create path object if path is provided
|
# create path object if path is provided
|
||||||
static_files_dir: Optional[Path] = Path(path) if path else None
|
static_files_dir: Path | None = Path(path) if path else None
|
||||||
settings_service = get_settings_service()
|
settings_service = get_settings_service()
|
||||||
settings_service.set("backend_only", backend_only)
|
settings_service.set("backend_only", backend_only)
|
||||||
app = setup_app(static_files_dir=static_files_dir, backend_only=backend_only)
|
app = setup_app(static_files_dir=static_files_dir, backend_only=backend_only)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
@ -69,7 +71,7 @@ def build_input_keys_response(langchain_object, artifacts):
|
||||||
return input_keys_response
|
return input_keys_response
|
||||||
|
|
||||||
|
|
||||||
def validate_is_component(flows: list["Flow"]):
|
def validate_is_component(flows: list[Flow]):
|
||||||
for flow in flows:
|
for flow in flows:
|
||||||
if not flow.data or flow.is_component is not None:
|
if not flow.data or flow.is_component is not None:
|
||||||
continue
|
continue
|
||||||
|
|
@ -152,7 +154,7 @@ async def build_graph_from_db_no_cache(flow_id: str, session: Session):
|
||||||
return await build_graph_from_data(flow_id, flow.data, flow_name=flow.name, user_id=str(flow.user_id))
|
return await build_graph_from_data(flow_id, flow.data, flow_name=flow.name, user_id=str(flow.user_id))
|
||||||
|
|
||||||
|
|
||||||
async def build_graph_from_db(flow_id: str, session: Session, chat_service: "ChatService"):
|
async def build_graph_from_db(flow_id: str, session: Session, chat_service: ChatService):
|
||||||
graph = await build_graph_from_db_no_cache(flow_id, session)
|
graph = await build_graph_from_db_no_cache(flow_id, session)
|
||||||
await chat_service.set_cache(flow_id, graph)
|
await chat_service.set_cache(flow_id, graph)
|
||||||
return graph
|
return graph
|
||||||
|
|
@ -160,7 +162,7 @@ async def build_graph_from_db(flow_id: str, session: Session, chat_service: "Cha
|
||||||
|
|
||||||
async def build_and_cache_graph_from_data(
|
async def build_and_cache_graph_from_data(
|
||||||
flow_id: str,
|
flow_id: str,
|
||||||
chat_service: "ChatService",
|
chat_service: ChatService,
|
||||||
graph_data: dict,
|
graph_data: dict,
|
||||||
): # -> Graph | Any:
|
): # -> Graph | Any:
|
||||||
"""Build and cache the graph."""
|
"""Build and cache the graph."""
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
|
@ -25,7 +27,7 @@ class AsyncStreamingLLMCallbackHandleSIO(AsyncCallbackHandler):
|
||||||
def __init__(self, session_id: str):
|
def __init__(self, session_id: str):
|
||||||
self.chat_service = get_chat_service()
|
self.chat_service = get_chat_service()
|
||||||
self.client_id = session_id
|
self.client_id = session_id
|
||||||
self.socketio_service: "SocketIOService" = get_socket_service()
|
self.socketio_service: SocketIOService = get_socket_service()
|
||||||
self.sid = session_id
|
self.sid = session_id
|
||||||
# self.socketio_service = self.chat_service.active_connections[self.client_id]
|
# self.socketio_service = self.chat_service.active_connections[self.client_id]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
|
@ -72,9 +74,9 @@ async def retrieve_vertices_order(
|
||||||
data: Annotated[FlowDataRequest | None, Body(embed=True)] | None = None,
|
data: Annotated[FlowDataRequest | None, Body(embed=True)] | None = None,
|
||||||
stop_component_id: str | None = None,
|
stop_component_id: str | None = None,
|
||||||
start_component_id: str | None = None,
|
start_component_id: str | None = None,
|
||||||
chat_service: "ChatService" = Depends(get_chat_service),
|
chat_service: ChatService = Depends(get_chat_service),
|
||||||
session=Depends(get_session),
|
session=Depends(get_session),
|
||||||
telemetry_service: "TelemetryService" = Depends(get_telemetry_service),
|
telemetry_service: TelemetryService = Depends(get_telemetry_service),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Retrieve the vertices order for a given flow.
|
Retrieve the vertices order for a given flow.
|
||||||
|
|
@ -148,12 +150,12 @@ async def build_flow(
|
||||||
stop_component_id: str | None = None,
|
stop_component_id: str | None = None,
|
||||||
start_component_id: str | None = None,
|
start_component_id: str | None = None,
|
||||||
log_builds: bool | None = True,
|
log_builds: bool | None = True,
|
||||||
chat_service: "ChatService" = Depends(get_chat_service),
|
chat_service: ChatService = Depends(get_chat_service),
|
||||||
current_user=Depends(get_current_active_user),
|
current_user=Depends(get_current_active_user),
|
||||||
telemetry_service: "TelemetryService" = Depends(get_telemetry_service),
|
telemetry_service: TelemetryService = Depends(get_telemetry_service),
|
||||||
session=Depends(get_session),
|
session=Depends(get_session),
|
||||||
):
|
):
|
||||||
async def build_graph_and_get_order() -> tuple[list[str], list[str], "Graph"]:
|
async def build_graph_and_get_order() -> tuple[list[str], list[str], Graph]:
|
||||||
start_time = time.perf_counter()
|
start_time = time.perf_counter()
|
||||||
components_count = None
|
components_count = None
|
||||||
try:
|
try:
|
||||||
|
|
@ -205,7 +207,7 @@ async def build_flow(
|
||||||
logger.exception(exc)
|
logger.exception(exc)
|
||||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||||
|
|
||||||
async def _build_vertex(vertex_id: str, graph: "Graph", event_manager: "EventManager") -> VertexBuildResponse:
|
async def _build_vertex(vertex_id: str, graph: Graph, event_manager: EventManager) -> VertexBuildResponse:
|
||||||
flow_id_str = str(flow_id)
|
flow_id_str = str(flow_id)
|
||||||
|
|
||||||
next_runnable_vertices = []
|
next_runnable_vertices = []
|
||||||
|
|
@ -320,9 +322,9 @@ async def build_flow(
|
||||||
|
|
||||||
async def build_vertices(
|
async def build_vertices(
|
||||||
vertex_id: str,
|
vertex_id: str,
|
||||||
graph: "Graph",
|
graph: Graph,
|
||||||
client_consumed_queue: asyncio.Queue,
|
client_consumed_queue: asyncio.Queue,
|
||||||
event_manager: "EventManager",
|
event_manager: EventManager,
|
||||||
) -> None:
|
) -> None:
|
||||||
build_task = asyncio.create_task(asyncio.to_thread(asyncio.run, _build_vertex(vertex_id, graph, event_manager)))
|
build_task = asyncio.create_task(asyncio.to_thread(asyncio.run, _build_vertex(vertex_id, graph, event_manager)))
|
||||||
try:
|
try:
|
||||||
|
|
@ -457,9 +459,9 @@ async def build_vertex(
|
||||||
background_tasks: BackgroundTasks,
|
background_tasks: BackgroundTasks,
|
||||||
inputs: Annotated[InputValueRequest | None, Body(embed=True)] = None,
|
inputs: Annotated[InputValueRequest | None, Body(embed=True)] = None,
|
||||||
files: list[str] | None = None,
|
files: list[str] | None = None,
|
||||||
chat_service: "ChatService" = Depends(get_chat_service),
|
chat_service: ChatService = Depends(get_chat_service),
|
||||||
current_user=Depends(get_current_active_user),
|
current_user=Depends(get_current_active_user),
|
||||||
telemetry_service: "TelemetryService" = Depends(get_telemetry_service),
|
telemetry_service: TelemetryService = Depends(get_telemetry_service),
|
||||||
):
|
):
|
||||||
"""Build a vertex instead of the entire graph.
|
"""Build a vertex instead of the entire graph.
|
||||||
|
|
||||||
|
|
@ -489,7 +491,7 @@ async def build_vertex(
|
||||||
if not cache:
|
if not cache:
|
||||||
# If there's no cache
|
# If there's no cache
|
||||||
logger.warning(f"No cache found for {flow_id_str}. Building graph starting at {vertex_id}")
|
logger.warning(f"No cache found for {flow_id_str}. Building graph starting at {vertex_id}")
|
||||||
graph: "Graph" = await build_graph_from_db(
|
graph: Graph = await build_graph_from_db(
|
||||||
flow_id=flow_id_str, session=next(get_session()), chat_service=chat_service
|
flow_id=flow_id_str, session=next(get_session()), chat_service=chat_service
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
@ -609,8 +611,8 @@ async def build_vertex_stream(
|
||||||
flow_id: uuid.UUID,
|
flow_id: uuid.UUID,
|
||||||
vertex_id: str,
|
vertex_id: str,
|
||||||
session_id: str | None = None,
|
session_id: str | None = None,
|
||||||
chat_service: "ChatService" = Depends(get_chat_service),
|
chat_service: ChatService = Depends(get_chat_service),
|
||||||
session_service: "SessionService" = Depends(get_session_service),
|
session_service: SessionService = Depends(get_session_service),
|
||||||
):
|
):
|
||||||
"""Build a vertex instead of the entire graph.
|
"""Build a vertex instead of the entire graph.
|
||||||
|
|
||||||
|
|
@ -650,7 +652,7 @@ async def build_vertex_stream(
|
||||||
else:
|
else:
|
||||||
graph = cache.get("result")
|
graph = cache.get("result")
|
||||||
|
|
||||||
vertex: "InterfaceVertex" = graph.get_vertex(vertex_id)
|
vertex: InterfaceVertex = graph.get_vertex(vertex_id)
|
||||||
if not hasattr(vertex, "stream"):
|
if not hasattr(vertex, "stream"):
|
||||||
raise ValueError(f"Vertex {vertex_id} does not support streaming")
|
raise ValueError(f"Vertex {vertex_id} does not support streaming")
|
||||||
if isinstance(vertex._built_result, str) and vertex._built_result:
|
if isinstance(vertex._built_result, str) and vertex._built_result:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from asyncio import Lock
|
from asyncio import Lock
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
|
@ -62,7 +64,7 @@ router = APIRouter(tags=["Base"])
|
||||||
@router.get("/all", dependencies=[Depends(get_current_active_user)])
|
@router.get("/all", dependencies=[Depends(get_current_active_user)])
|
||||||
async def get_all(
|
async def get_all(
|
||||||
settings_service=Depends(get_settings_service),
|
settings_service=Depends(get_settings_service),
|
||||||
cache_service: "CacheService" = Depends(dependency=get_cache_service),
|
cache_service: CacheService = Depends(dependency=get_cache_service),
|
||||||
force_refresh: bool = False,
|
force_refresh: bool = False,
|
||||||
):
|
):
|
||||||
from langflow.interface.types import get_and_cache_all_types_dict
|
from langflow.interface.types import get_and_cache_all_types_dict
|
||||||
|
|
@ -181,7 +183,7 @@ async def simplified_run_flow(
|
||||||
input_request: SimplifiedAPIRequest = SimplifiedAPIRequest(),
|
input_request: SimplifiedAPIRequest = SimplifiedAPIRequest(),
|
||||||
stream: bool = False,
|
stream: bool = False,
|
||||||
api_key_user: UserRead = Depends(api_key_security),
|
api_key_user: UserRead = Depends(api_key_security),
|
||||||
telemetry_service: "TelemetryService" = Depends(get_telemetry_service),
|
telemetry_service: TelemetryService = Depends(get_telemetry_service),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Executes a specified flow by ID with input customization, performance enhancements through caching, and optional data streaming.
|
Executes a specified flow by ID with input customization, performance enhancements through caching, and optional data streaming.
|
||||||
|
|
@ -290,7 +292,7 @@ async def webhook_run_flow(
|
||||||
user: Annotated[User, Depends(get_user_by_flow_id_or_endpoint_name)],
|
user: Annotated[User, Depends(get_user_by_flow_id_or_endpoint_name)],
|
||||||
request: Request,
|
request: Request,
|
||||||
background_tasks: BackgroundTasks,
|
background_tasks: BackgroundTasks,
|
||||||
telemetry_service: "TelemetryService" = Depends(get_telemetry_service),
|
telemetry_service: TelemetryService = Depends(get_telemetry_service),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Run a flow using a webhook request.
|
Run a flow using a webhook request.
|
||||||
|
|
@ -484,7 +486,7 @@ async def process(
|
||||||
tweaks: dict | None = None,
|
tweaks: dict | None = None,
|
||||||
clear_cache: Annotated[bool, Body(embed=True)] = False, # noqa: F821
|
clear_cache: Annotated[bool, Body(embed=True)] = False, # noqa: F821
|
||||||
session_id: Annotated[None | str, Body(embed=True)] = None, # noqa: F821
|
session_id: Annotated[None | str, Body(embed=True)] = None, # noqa: F821
|
||||||
task_service: "TaskService" = Depends(get_task_service),
|
task_service: TaskService = Depends(get_task_service),
|
||||||
api_key_user: UserRead = Depends(api_key_security),
|
api_key_user: UserRead = Depends(api_key_security),
|
||||||
sync: Annotated[bool, Body(embed=True)] = True, # noqa: F821
|
sync: Annotated[bool, Body(embed=True)] = True, # noqa: F821
|
||||||
session_service: SessionService = Depends(get_session_service),
|
session_service: SessionService = Depends(get_session_service),
|
||||||
|
|
@ -633,7 +635,7 @@ def get_config():
|
||||||
try:
|
try:
|
||||||
from langflow.services.deps import get_settings_service
|
from langflow.services.deps import get_settings_service
|
||||||
|
|
||||||
settings_service: "SettingsService" = get_settings_service() # type: ignore
|
settings_service: SettingsService = get_settings_service() # type: ignore
|
||||||
return settings_service.settings.model_dump()
|
return settings_service.settings.model_dump()
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.exception(exc)
|
logger.exception(exc)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import List, Optional, Union, cast
|
from typing import cast
|
||||||
|
|
||||||
from langchain.agents import AgentExecutor, BaseMultiActionAgent, BaseSingleActionAgent
|
from langchain.agents import AgentExecutor, BaseMultiActionAgent, BaseSingleActionAgent
|
||||||
from langchain.agents.agent import RunnableAgent
|
from langchain.agents.agent import RunnableAgent
|
||||||
|
|
@ -20,7 +20,7 @@ from langflow.utils.constants import MESSAGE_SENDER_AI
|
||||||
|
|
||||||
class LCAgentComponent(Component):
|
class LCAgentComponent(Component):
|
||||||
trace_type = "agent"
|
trace_type = "agent"
|
||||||
_base_inputs: List[InputTypes] = [
|
_base_inputs: list[InputTypes] = [
|
||||||
MessageTextInput(name="input_value", display_name="Input"),
|
MessageTextInput(name="input_value", display_name="Input"),
|
||||||
BoolInput(
|
BoolInput(
|
||||||
name="handle_parsing_errors",
|
name="handle_parsing_errors",
|
||||||
|
|
@ -89,7 +89,7 @@ class LCAgentComponent(Component):
|
||||||
}
|
}
|
||||||
return {**base, "agent_executor_kwargs": agent_kwargs}
|
return {**base, "agent_executor_kwargs": agent_kwargs}
|
||||||
|
|
||||||
def get_chat_history_data(self) -> Optional[List[Data]]:
|
def get_chat_history_data(self) -> list[Data] | None:
|
||||||
# might be overridden in subclasses
|
# might be overridden in subclasses
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@ class LCToolsAgentComponent(LCAgentComponent):
|
||||||
|
|
||||||
async def run_agent(
|
async def run_agent(
|
||||||
self,
|
self,
|
||||||
agent: Union[Runnable, BaseSingleActionAgent, BaseMultiActionAgent, AgentExecutor],
|
agent: Runnable | BaseSingleActionAgent | BaseMultiActionAgent | AgentExecutor,
|
||||||
) -> Text:
|
) -> Text:
|
||||||
if isinstance(agent, AgentExecutor):
|
if isinstance(agent, AgentExecutor):
|
||||||
runnable = agent
|
runnable = agent
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, Dict, List
|
from typing import Any
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from langchain.callbacks.base import AsyncCallbackHandler
|
from langchain.callbacks.base import AsyncCallbackHandler
|
||||||
|
|
@ -15,14 +15,14 @@ class AgentAsyncHandler(AsyncCallbackHandler):
|
||||||
|
|
||||||
async def on_tool_start(
|
async def on_tool_start(
|
||||||
self,
|
self,
|
||||||
serialized: Dict[str, Any],
|
serialized: dict[str, Any],
|
||||||
input_str: str,
|
input_str: str,
|
||||||
*,
|
*,
|
||||||
run_id: UUID,
|
run_id: UUID,
|
||||||
parent_run_id: UUID | None = None,
|
parent_run_id: UUID | None = None,
|
||||||
tags: List[str] | None = None,
|
tags: list[str] | None = None,
|
||||||
metadata: Dict[str, Any] | None = None,
|
metadata: dict[str, Any] | None = None,
|
||||||
inputs: Dict[str, Any] | None = None,
|
inputs: dict[str, Any] | None = None,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
if self.log_function is None:
|
if self.log_function is None:
|
||||||
|
|
@ -62,7 +62,7 @@ class AgentAsyncHandler(AsyncCallbackHandler):
|
||||||
*,
|
*,
|
||||||
run_id: UUID,
|
run_id: UUID,
|
||||||
parent_run_id: UUID | None = None,
|
parent_run_id: UUID | None = None,
|
||||||
tags: List[str] | None = None,
|
tags: list[str] | None = None,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
if self.log_function is None:
|
if self.log_function is None:
|
||||||
|
|
@ -85,7 +85,7 @@ class AgentAsyncHandler(AsyncCallbackHandler):
|
||||||
*,
|
*,
|
||||||
run_id: UUID,
|
run_id: UUID,
|
||||||
parent_run_id: UUID | None = None,
|
parent_run_id: UUID | None = None,
|
||||||
tags: List[str] | None = None,
|
tags: list[str] | None = None,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
if self.log_function is None:
|
if self.log_function is None:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from typing import Callable, List, Tuple, Union, cast
|
from collections.abc import Callable
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
from crewai import Agent, Crew, Process, Task # type: ignore
|
from crewai import Agent, Crew, Process, Task # type: ignore
|
||||||
from crewai.task import TaskOutput # type: ignore
|
from crewai.task import TaskOutput # type: ignore
|
||||||
|
|
@ -62,7 +63,7 @@ class BaseCrewComponent(Component):
|
||||||
def get_step_callback(
|
def get_step_callback(
|
||||||
self,
|
self,
|
||||||
) -> Callable:
|
) -> Callable:
|
||||||
def step_callback(agent_output: Union[AgentFinish, List[Tuple[AgentAction, str]]]):
|
def step_callback(agent_output: AgentFinish | list[tuple[AgentAction, str]]):
|
||||||
_id = self._vertex.id if self._vertex else self.display_name
|
_id = self._vertex.id if self._vertex else self.display_name
|
||||||
if isinstance(agent_output, AgentFinish):
|
if isinstance(agent_output, AgentFinish):
|
||||||
messages = agent_output.messages
|
messages = agent_output.messages
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from typing import Any, Callable, Dict, List, Optional, Sequence, Union
|
from collections.abc import Callable, Sequence
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from langchain.agents import (
|
from langchain.agents import (
|
||||||
create_json_chat_agent,
|
create_json_chat_agent,
|
||||||
|
|
@ -24,17 +25,17 @@ class AgentSpec(BaseModel):
|
||||||
BaseLanguageModel,
|
BaseLanguageModel,
|
||||||
Sequence[BaseTool],
|
Sequence[BaseTool],
|
||||||
BasePromptTemplate | ChatPromptTemplate,
|
BasePromptTemplate | ChatPromptTemplate,
|
||||||
Optional[Callable[[List[BaseTool]], str]],
|
Callable[[list[BaseTool]], str] | None,
|
||||||
Optional[Union[bool, List[str]]],
|
bool | list[str] | None,
|
||||||
],
|
],
|
||||||
Any,
|
Any,
|
||||||
]
|
]
|
||||||
prompt: Optional[Any] = None
|
prompt: Any | None = None
|
||||||
fields: List[str]
|
fields: list[str]
|
||||||
hub_repo: Optional[str] = None
|
hub_repo: str | None = None
|
||||||
|
|
||||||
|
|
||||||
def data_to_messages(data: List[Data]) -> List[BaseMessage]:
|
def data_to_messages(data: list[Data]) -> list[BaseMessage]:
|
||||||
"""
|
"""
|
||||||
Convert a list of data to a list of messages.
|
Convert a list of data to a list of messages.
|
||||||
|
|
||||||
|
|
@ -51,9 +52,9 @@ def validate_and_create_xml_agent(
|
||||||
llm: BaseLanguageModel,
|
llm: BaseLanguageModel,
|
||||||
tools: Sequence[BaseTool],
|
tools: Sequence[BaseTool],
|
||||||
prompt: BasePromptTemplate,
|
prompt: BasePromptTemplate,
|
||||||
tools_renderer: Callable[[List[BaseTool]], str] = render_text_description,
|
tools_renderer: Callable[[list[BaseTool]], str] = render_text_description,
|
||||||
*,
|
*,
|
||||||
stop_sequence: Union[bool, List[str]] = True,
|
stop_sequence: bool | list[str] = True,
|
||||||
):
|
):
|
||||||
return create_xml_agent(
|
return create_xml_agent(
|
||||||
llm=llm,
|
llm=llm,
|
||||||
|
|
@ -68,9 +69,9 @@ def validate_and_create_openai_tools_agent(
|
||||||
llm: BaseLanguageModel,
|
llm: BaseLanguageModel,
|
||||||
tools: Sequence[BaseTool],
|
tools: Sequence[BaseTool],
|
||||||
prompt: ChatPromptTemplate,
|
prompt: ChatPromptTemplate,
|
||||||
tools_renderer: Callable[[List[BaseTool]], str] = render_text_description,
|
tools_renderer: Callable[[list[BaseTool]], str] = render_text_description,
|
||||||
*,
|
*,
|
||||||
stop_sequence: Union[bool, List[str]] = True,
|
stop_sequence: bool | list[str] = True,
|
||||||
):
|
):
|
||||||
return create_openai_tools_agent(
|
return create_openai_tools_agent(
|
||||||
llm=llm,
|
llm=llm,
|
||||||
|
|
@ -83,9 +84,9 @@ def validate_and_create_tool_calling_agent(
|
||||||
llm: BaseLanguageModel,
|
llm: BaseLanguageModel,
|
||||||
tools: Sequence[BaseTool],
|
tools: Sequence[BaseTool],
|
||||||
prompt: ChatPromptTemplate,
|
prompt: ChatPromptTemplate,
|
||||||
tools_renderer: Callable[[List[BaseTool]], str] = render_text_description,
|
tools_renderer: Callable[[list[BaseTool]], str] = render_text_description,
|
||||||
*,
|
*,
|
||||||
stop_sequence: Union[bool, List[str]] = True,
|
stop_sequence: bool | list[str] = True,
|
||||||
):
|
):
|
||||||
return create_tool_calling_agent(
|
return create_tool_calling_agent(
|
||||||
llm=llm,
|
llm=llm,
|
||||||
|
|
@ -98,9 +99,9 @@ def validate_and_create_json_chat_agent(
|
||||||
llm: BaseLanguageModel,
|
llm: BaseLanguageModel,
|
||||||
tools: Sequence[BaseTool],
|
tools: Sequence[BaseTool],
|
||||||
prompt: ChatPromptTemplate,
|
prompt: ChatPromptTemplate,
|
||||||
tools_renderer: Callable[[List[BaseTool]], str] = render_text_description,
|
tools_renderer: Callable[[list[BaseTool]], str] = render_text_description,
|
||||||
*,
|
*,
|
||||||
stop_sequence: Union[bool, List[str]] = True,
|
stop_sequence: bool | list[str] = True,
|
||||||
):
|
):
|
||||||
return create_json_chat_agent(
|
return create_json_chat_agent(
|
||||||
llm=llm,
|
llm=llm,
|
||||||
|
|
@ -111,7 +112,7 @@ def validate_and_create_json_chat_agent(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
AGENTS: Dict[str, AgentSpec] = {
|
AGENTS: dict[str, AgentSpec] = {
|
||||||
"Tool Calling Agent": AgentSpec(
|
"Tool Calling Agent": AgentSpec(
|
||||||
func=validate_and_create_tool_calling_agent,
|
func=validate_and_create_tool_calling_agent,
|
||||||
prompt=None,
|
prompt=None,
|
||||||
|
|
|
||||||
|
|
@ -153,13 +153,13 @@ def parse_context(curl_command):
|
||||||
# proxy_auth = parsed_args.proxy_user
|
# proxy_auth = parsed_args.proxy_user
|
||||||
if parsed_args.proxy and parsed_args.proxy_user:
|
if parsed_args.proxy and parsed_args.proxy_user:
|
||||||
proxies = {
|
proxies = {
|
||||||
"http": "http://{}@{}/".format(parsed_args.proxy_user, parsed_args.proxy),
|
"http": f"http://{parsed_args.proxy_user}@{parsed_args.proxy}/",
|
||||||
"https": "http://{}@{}/".format(parsed_args.proxy_user, parsed_args.proxy),
|
"https": f"http://{parsed_args.proxy_user}@{parsed_args.proxy}/",
|
||||||
}
|
}
|
||||||
elif parsed_args.proxy:
|
elif parsed_args.proxy:
|
||||||
proxies = {
|
proxies = {
|
||||||
"http": "http://{}/".format(parsed_args.proxy),
|
"http": f"http://{parsed_args.proxy}/",
|
||||||
"https": "http://{}/".format(parsed_args.proxy),
|
"https": f"http://{parsed_args.proxy}/",
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParsedContext(
|
return ParsedContext(
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
from collections.abc import Callable
|
||||||
from concurrent import futures
|
from concurrent import futures
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Callable, List, Optional
|
|
||||||
|
|
||||||
import chardet
|
import chardet
|
||||||
import orjson
|
import orjson
|
||||||
|
|
@ -49,8 +49,8 @@ def retrieve_file_paths(
|
||||||
load_hidden: bool,
|
load_hidden: bool,
|
||||||
recursive: bool,
|
recursive: bool,
|
||||||
depth: int,
|
depth: int,
|
||||||
types: List[str] = TEXT_FILE_TYPES,
|
types: list[str] = TEXT_FILE_TYPES,
|
||||||
) -> List[str]:
|
) -> list[str]:
|
||||||
path_obj = Path(path)
|
path_obj = Path(path)
|
||||||
if not path_obj.exists() or not path_obj.is_dir():
|
if not path_obj.exists() or not path_obj.is_dir():
|
||||||
raise ValueError(f"Path {path} must exist and be a directory.")
|
raise ValueError(f"Path {path} must exist and be a directory.")
|
||||||
|
|
@ -75,7 +75,7 @@ def retrieve_file_paths(
|
||||||
return file_paths
|
return file_paths
|
||||||
|
|
||||||
|
|
||||||
def partition_file_to_data(file_path: str, silent_errors: bool) -> Optional[Data]:
|
def partition_file_to_data(file_path: str, silent_errors: bool) -> Data | None:
|
||||||
# Use the partition function to load the file
|
# Use the partition function to load the file
|
||||||
from unstructured.partition.auto import partition # type: ignore
|
from unstructured.partition.auto import partition # type: ignore
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ def read_text_file(file_path: str) -> str:
|
||||||
if encoding in ["Windows-1252", "Windows-1254", "MacRoman"]:
|
if encoding in ["Windows-1252", "Windows-1254", "MacRoman"]:
|
||||||
encoding = "utf-8"
|
encoding = "utf-8"
|
||||||
|
|
||||||
with open(file_path, "r", encoding=encoding) as f:
|
with open(file_path, encoding=encoding) as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -122,7 +122,7 @@ def parse_pdf_to_text(file_path: str) -> str:
|
||||||
return "\n\n".join([page.extract_text() for page in reader.pages])
|
return "\n\n".join([page.extract_text() for page in reader.pages])
|
||||||
|
|
||||||
|
|
||||||
def parse_text_file_to_data(file_path: str, silent_errors: bool) -> Optional[Data]:
|
def parse_text_file_to_data(file_path: str, silent_errors: bool) -> Data | None:
|
||||||
try:
|
try:
|
||||||
if file_path.endswith(".pdf"):
|
if file_path.endswith(".pdf"):
|
||||||
text = parse_pdf_to_text(file_path)
|
text = parse_pdf_to_text(file_path)
|
||||||
|
|
@ -171,11 +171,11 @@ def parse_text_file_to_data(file_path: str, silent_errors: bool) -> Optional[Dat
|
||||||
|
|
||||||
|
|
||||||
def parallel_load_data(
|
def parallel_load_data(
|
||||||
file_paths: List[str],
|
file_paths: list[str],
|
||||||
silent_errors: bool,
|
silent_errors: bool,
|
||||||
max_concurrency: int,
|
max_concurrency: int,
|
||||||
load_function: Callable = parse_text_file_to_data,
|
load_function: Callable = parse_text_file_to_data,
|
||||||
) -> List[Optional[Data]]:
|
) -> list[Data | None]:
|
||||||
with futures.ThreadPoolExecutor(max_workers=max_concurrency) as executor:
|
with futures.ThreadPoolExecutor(max_workers=max_concurrency) as executor:
|
||||||
loaded_files = executor.map(
|
loaded_files = executor.map(
|
||||||
lambda file_path: load_function(file_path, silent_errors),
|
lambda file_path: load_function(file_path, silent_errors),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from langflow.graph.schema import ResultData, RunOutputs
|
from langflow.graph.schema import ResultData, RunOutputs
|
||||||
|
|
@ -7,7 +5,7 @@ from langflow.schema import Data
|
||||||
from langflow.schema.message import Message
|
from langflow.schema.message import Message
|
||||||
|
|
||||||
|
|
||||||
def build_data_from_run_outputs(run_outputs: RunOutputs) -> List[Data]:
|
def build_data_from_run_outputs(run_outputs: RunOutputs) -> list[Data]:
|
||||||
"""
|
"""
|
||||||
Build a list of data from the given RunOutputs.
|
Build a list of data from the given RunOutputs.
|
||||||
|
|
||||||
|
|
@ -27,7 +25,7 @@ def build_data_from_run_outputs(run_outputs: RunOutputs) -> List[Data]:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def build_data_from_result_data(result_data: ResultData, get_final_results_only: bool = True) -> List[Data]:
|
def build_data_from_result_data(result_data: ResultData, get_final_results_only: bool = True) -> list[Data]:
|
||||||
"""
|
"""
|
||||||
Build a list of data from the given ResultData.
|
Build a list of data from the given ResultData.
|
||||||
|
|
||||||
|
|
@ -80,7 +78,7 @@ def build_data_from_result_data(result_data: ResultData, get_final_results_only:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def format_flow_output_data(data: List[Data]) -> str:
|
def format_flow_output_data(data: list[Data]) -> str:
|
||||||
"""
|
"""
|
||||||
Format the flow output data into a string.
|
Format the flow output data into a string.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import AsyncIterator, Iterator, Optional, Union
|
from collections.abc import AsyncIterator, Iterator
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
from langflow.memory import store_message
|
from langflow.memory import store_message
|
||||||
|
|
@ -54,7 +54,7 @@ class ChatComponent(Component):
|
||||||
|
|
||||||
def _stream_message(self, message: Message, message_id: str) -> str:
|
def _stream_message(self, message: Message, message_id: str) -> str:
|
||||||
iterator = message.text
|
iterator = message.text
|
||||||
if not isinstance(iterator, (AsyncIterator, Iterator)):
|
if not isinstance(iterator, AsyncIterator | Iterator):
|
||||||
raise ValueError("The message must be an iterator or an async iterator.")
|
raise ValueError("The message must be an iterator or an async iterator.")
|
||||||
|
|
||||||
if isinstance(iterator, AsyncIterator):
|
if isinstance(iterator, AsyncIterator):
|
||||||
|
|
@ -68,12 +68,12 @@ class ChatComponent(Component):
|
||||||
|
|
||||||
def build_with_data(
|
def build_with_data(
|
||||||
self,
|
self,
|
||||||
sender: Optional[str] = "User",
|
sender: str | None = "User",
|
||||||
sender_name: Optional[str] = "User",
|
sender_name: str | None = "User",
|
||||||
input_value: Optional[Union[str, Data, Message]] = None,
|
input_value: str | Data | Message | None = None,
|
||||||
files: Optional[list[str]] = None,
|
files: list[str] | None = None,
|
||||||
session_id: Optional[str] = None,
|
session_id: str | None = None,
|
||||||
return_message: Optional[bool] = False,
|
return_message: bool | None = False,
|
||||||
) -> Message:
|
) -> Message:
|
||||||
message: Message | None = None
|
message: Message | None = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import Sequence, Union
|
from collections.abc import Sequence
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
from langflow.field_typing import Tool
|
from langflow.field_typing import Tool
|
||||||
|
|
@ -24,7 +24,7 @@ class LCToolComponent(Component):
|
||||||
raise ValueError(f"Method '{method_name}' must be defined.")
|
raise ValueError(f"Method '{method_name}' must be defined.")
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def run_model(self) -> Union[Data, list[Data]]:
|
def run_model(self) -> Data | list[Data]:
|
||||||
"""
|
"""
|
||||||
Run model and return the output.
|
Run model and return the output.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import CustomComponent
|
||||||
from langflow.schema import Data
|
from langflow.schema import Data
|
||||||
from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER
|
from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER
|
||||||
|
|
@ -45,6 +43,6 @@ class BaseMemoryComponent(CustomComponent):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def add_message(
|
def add_message(
|
||||||
self, sender: str, sender_name: str, text: str, session_id: str, metadata: Optional[dict] = None, **kwargs
|
self, sender: str, sender_name: str, text: str, session_id: str, metadata: dict | None = None, **kwargs
|
||||||
):
|
):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import json
|
import json
|
||||||
import warnings
|
import warnings
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import List, Optional, Union
|
|
||||||
|
|
||||||
from langchain_core.language_models.llms import LLM
|
from langchain_core.language_models.llms import LLM
|
||||||
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage
|
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage
|
||||||
|
|
@ -20,7 +19,7 @@ class LCModelComponent(Component):
|
||||||
description: str = "Model Description"
|
description: str = "Model Description"
|
||||||
trace_type = "llm"
|
trace_type = "llm"
|
||||||
|
|
||||||
_base_inputs: List[InputTypes] = [
|
_base_inputs: list[InputTypes] = [
|
||||||
MessageInput(name="input_value", display_name="Input"),
|
MessageInput(name="input_value", display_name="Input"),
|
||||||
MessageTextInput(
|
MessageTextInput(
|
||||||
name="system_message",
|
name="system_message",
|
||||||
|
|
@ -138,9 +137,9 @@ class LCModelComponent(Component):
|
||||||
runnable: LanguageModel,
|
runnable: LanguageModel,
|
||||||
stream: bool,
|
stream: bool,
|
||||||
input_value: str | Message,
|
input_value: str | Message,
|
||||||
system_message: Optional[str] = None,
|
system_message: str | None = None,
|
||||||
):
|
):
|
||||||
messages: list[Union[BaseMessage]] = []
|
messages: list[BaseMessage] = []
|
||||||
if not input_value and not system_message:
|
if not input_value and not system_message:
|
||||||
raise ValueError("The message you want to send to the model is empty.")
|
raise ValueError("The message you want to send to the model is empty.")
|
||||||
system_message_added = False
|
system_message_added = False
|
||||||
|
|
@ -161,7 +160,7 @@ class LCModelComponent(Component):
|
||||||
|
|
||||||
if system_message and not system_message_added:
|
if system_message and not system_message_added:
|
||||||
messages.append(SystemMessage(content=system_message))
|
messages.append(SystemMessage(content=system_message))
|
||||||
inputs: Union[list, dict] = messages or {}
|
inputs: list | dict = messages or {}
|
||||||
try:
|
try:
|
||||||
runnable = runnable.with_config( # type: ignore
|
runnable = runnable.with_config( # type: ignore
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
from langchain_core.prompts import PromptTemplate
|
from langchain_core.prompts import PromptTemplate
|
||||||
|
|
@ -198,7 +198,7 @@ def update_input_variables_field(input_variables, template):
|
||||||
|
|
||||||
|
|
||||||
def process_prompt_template(
|
def process_prompt_template(
|
||||||
template: str, name: str, custom_fields: Optional[Dict[str, List[str]]], frontend_node_template: Dict[str, Any]
|
template: str, name: str, custom_fields: dict[str, list[str]] | None, frontend_node_template: dict[str, Any]
|
||||||
):
|
):
|
||||||
"""Process and validate prompt template, update template and custom fields."""
|
"""Process and validate prompt template, update template and custom fields."""
|
||||||
# Validate the prompt template and extract input variables
|
# Validate the prompt template and extract input variables
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Any, List, Optional, Type
|
from typing import Any
|
||||||
|
|
||||||
from langchain_core.runnables import RunnableConfig
|
from langchain_core.runnables import RunnableConfig
|
||||||
from langchain_core.tools import BaseTool, ToolException
|
from langchain_core.tools import BaseTool, ToolException
|
||||||
|
|
@ -15,10 +15,10 @@ from langflow.utils.async_helpers import run_until_complete
|
||||||
class FlowTool(BaseTool):
|
class FlowTool(BaseTool):
|
||||||
name: str
|
name: str
|
||||||
description: str
|
description: str
|
||||||
graph: Optional[Graph] = None
|
graph: Graph | None = None
|
||||||
flow_id: Optional[str] = None
|
flow_id: str | None = None
|
||||||
user_id: Optional[str] = None
|
user_id: str | None = None
|
||||||
inputs: List["Vertex"] = []
|
inputs: list["Vertex"] = []
|
||||||
get_final_results_only: bool = True
|
get_final_results_only: bool = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -26,7 +26,7 @@ class FlowTool(BaseTool):
|
||||||
schema = self.get_input_schema()
|
schema = self.get_input_schema()
|
||||||
return schema.schema()["properties"]
|
return schema.schema()["properties"]
|
||||||
|
|
||||||
def get_input_schema(self, config: Optional[RunnableConfig] = None) -> Type[BaseModel]:
|
def get_input_schema(self, config: RunnableConfig | None = None) -> type[BaseModel]:
|
||||||
"""The tool's input schema."""
|
"""The tool's input schema."""
|
||||||
if self.args_schema is not None:
|
if self.args_schema is not None:
|
||||||
return self.args_schema
|
return self.args_schema
|
||||||
|
|
@ -68,7 +68,7 @@ class FlowTool(BaseTool):
|
||||||
data.extend(build_data_from_result_data(output, get_final_results_only=self.get_final_results_only))
|
data.extend(build_data_from_result_data(output, get_final_results_only=self.get_final_results_only))
|
||||||
return format_flow_output_data(data)
|
return format_flow_output_data(data)
|
||||||
|
|
||||||
def validate_inputs(self, args_names: List[dict[str, str]], args: Any, kwargs: Any):
|
def validate_inputs(self, args_names: list[dict[str, str]], args: Any, kwargs: Any):
|
||||||
"""Validate the inputs."""
|
"""Validate the inputs."""
|
||||||
|
|
||||||
if len(args) > 0 and len(args) != len(args_names):
|
if len(args) > 0 and len(args) != len(args_names):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from abc import ABC, ABCMeta, abstractmethod
|
from abc import ABC, ABCMeta, abstractmethod
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import List, cast
|
from typing import cast
|
||||||
|
|
||||||
from langchain_core.documents import Document
|
from langchain_core.documents import Document
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
@ -94,7 +94,7 @@ class LCVectorStoreComponent(Component, ABC, metaclass=EnforceCacheDecoratorMeta
|
||||||
vector_store: VectorStore,
|
vector_store: VectorStore,
|
||||||
k=10,
|
k=10,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> List[Data]:
|
) -> list[Data]:
|
||||||
"""
|
"""
|
||||||
Search for data in the vector store based on the input value and search type.
|
Search for data in the vector store based on the input value and search type.
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ class LCVectorStoreComponent(Component, ABC, metaclass=EnforceCacheDecoratorMeta
|
||||||
ValueError: If invalid inputs are provided.
|
ValueError: If invalid inputs are provided.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
docs: List[Document] = []
|
docs: list[Document] = []
|
||||||
if input_value and isinstance(input_value, str) and hasattr(vector_store, "search"):
|
if input_value and isinstance(input_value, str) and hasattr(vector_store, "search"):
|
||||||
docs = vector_store.search(query=input_value, search_type=search_type.lower(), k=k, **kwargs)
|
docs = vector_store.search(query=input_value, search_type=search_type.lower(), k=k, **kwargs)
|
||||||
else:
|
else:
|
||||||
|
|
@ -140,7 +140,7 @@ class LCVectorStoreComponent(Component, ABC, metaclass=EnforceCacheDecoratorMeta
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Vector Store {vector_store.__class__.__name__} does not have an as_retriever method.")
|
raise ValueError(f"Vector Store {vector_store.__class__.__name__} does not have an as_retriever method.")
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
"""
|
"""
|
||||||
Search for documents in the vector store.
|
Search for documents in the vector store.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import json
|
import json
|
||||||
from typing import Any, Dict, Union
|
from typing import Any
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
@ -54,7 +54,7 @@ class AddContentToPage(LCToolComponent):
|
||||||
args_schema=self.AddContentToPageSchema,
|
args_schema=self.AddContentToPageSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _add_content_to_page(self, markdown_text: str, block_id: str) -> Union[Dict[str, Any], str]:
|
def _add_content_to_page(self, markdown_text: str, block_id: str) -> dict[str, Any] | str:
|
||||||
try:
|
try:
|
||||||
html_text = markdown(markdown_text)
|
html_text = markdown(markdown_text)
|
||||||
soup = BeautifulSoup(html_text, "html.parser")
|
soup = BeautifulSoup(html_text, "html.parser")
|
||||||
|
|
@ -209,7 +209,7 @@ class AddContentToPage(LCToolComponent):
|
||||||
|
|
||||||
return blocks
|
return blocks
|
||||||
|
|
||||||
def create_block(self, block_type: str, content: str, **kwargs) -> Dict[str, Any]:
|
def create_block(self, block_type: str, content: str, **kwargs) -> dict[str, Any]:
|
||||||
block: dict[str, Any] = {
|
block: dict[str, Any] = {
|
||||||
"object": "block",
|
"object": "block",
|
||||||
"type": block_type,
|
"type": block_type,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import json
|
import json
|
||||||
from typing import Any, Dict, Union
|
from typing import Any
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
|
|
@ -60,7 +60,7 @@ class NotionPageCreator(LCToolComponent):
|
||||||
args_schema=self.NotionPageCreatorSchema,
|
args_schema=self.NotionPageCreatorSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _create_notion_page(self, database_id: str, properties_json: str) -> Union[Dict[str, Any], str]:
|
def _create_notion_page(self, database_id: str, properties_json: str) -> dict[str, Any] | str:
|
||||||
if not database_id or not properties_json:
|
if not database_id or not properties_json:
|
||||||
return "Invalid input. Please provide 'database_id' and 'properties_json'."
|
return "Invalid input. Please provide 'database_id' and 'properties_json'."
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Dict, Union
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
@ -50,7 +48,7 @@ class NotionDatabaseProperties(LCToolComponent):
|
||||||
args_schema=self.NotionDatabasePropertiesSchema,
|
args_schema=self.NotionDatabasePropertiesSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _fetch_database_properties(self, database_id: str) -> Union[Dict, str]:
|
def _fetch_database_properties(self, database_id: str) -> dict | str:
|
||||||
url = f"https://api.notion.com/v1/databases/{database_id}"
|
url = f"https://api.notion.com/v1/databases/{database_id}"
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {self.notion_secret}",
|
"Authorization": f"Bearer {self.notion_secret}",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import json
|
import json
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
|
|
@ -43,12 +43,12 @@ class NotionListPages(LCToolComponent):
|
||||||
|
|
||||||
class NotionListPagesSchema(BaseModel):
|
class NotionListPagesSchema(BaseModel):
|
||||||
database_id: str = Field(..., description="The ID of the Notion database to query.")
|
database_id: str = Field(..., description="The ID of the Notion database to query.")
|
||||||
query_json: Optional[str] = Field(
|
query_json: str | None = Field(
|
||||||
default="",
|
default="",
|
||||||
description="A JSON string containing the filters and sorts for querying the database. Leave empty for no filters or sorts.",
|
description="A JSON string containing the filters and sorts for querying the database. Leave empty for no filters or sorts.",
|
||||||
)
|
)
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
result = self._query_notion_database(self.database_id, self.query_json)
|
result = self._query_notion_database(self.database_id, self.query_json)
|
||||||
|
|
||||||
if isinstance(result, str):
|
if isinstance(result, str):
|
||||||
|
|
@ -89,7 +89,7 @@ class NotionListPages(LCToolComponent):
|
||||||
args_schema=self.NotionListPagesSchema,
|
args_schema=self.NotionListPagesSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _query_notion_database(self, database_id: str, query_json: Optional[str] = None) -> List[Dict[str, Any]] | str:
|
def _query_notion_database(self, database_id: str, query_json: str | None = None) -> list[dict[str, Any]] | str:
|
||||||
url = f"https://api.notion.com/v1/databases/{database_id}/query"
|
url = f"https://api.notion.com/v1/databases/{database_id}/query"
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {self.notion_secret}",
|
"Authorization": f"Bearer {self.notion_secret}",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Dict, List
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
@ -28,7 +26,7 @@ class NotionUserList(LCToolComponent):
|
||||||
class NotionUserListSchema(BaseModel):
|
class NotionUserListSchema(BaseModel):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
users = self._list_users()
|
users = self._list_users()
|
||||||
records = []
|
records = []
|
||||||
combined_text = ""
|
combined_text = ""
|
||||||
|
|
@ -53,7 +51,7 @@ class NotionUserList(LCToolComponent):
|
||||||
args_schema=self.NotionUserListSchema,
|
args_schema=self.NotionUserListSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _list_users(self) -> List[Dict]:
|
def _list_users(self) -> list[dict]:
|
||||||
url = "https://api.notion.com/v1/users"
|
url = "https://api.notion.com/v1/users"
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {self.notion_secret}",
|
"Authorization": f"Bearer {self.notion_secret}",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, Dict, List
|
from typing import Any
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
|
|
@ -49,7 +49,7 @@ class NotionSearch(LCToolComponent):
|
||||||
filter_value: str = Field(default="page", description="Filter type: 'page' or 'database'.")
|
filter_value: str = Field(default="page", description="Filter type: 'page' or 'database'.")
|
||||||
sort_direction: str = Field(default="descending", description="Sort direction: 'ascending' or 'descending'.")
|
sort_direction: str = Field(default="descending", description="Sort direction: 'ascending' or 'descending'.")
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
results = self._search_notion(self.query, self.filter_value, self.sort_direction)
|
results = self._search_notion(self.query, self.filter_value, self.sort_direction)
|
||||||
records = []
|
records = []
|
||||||
combined_text = f"Results found: {len(results)}\n\n"
|
combined_text = f"Results found: {len(results)}\n\n"
|
||||||
|
|
@ -89,7 +89,7 @@ class NotionSearch(LCToolComponent):
|
||||||
|
|
||||||
def _search_notion(
|
def _search_notion(
|
||||||
self, query: str, filter_value: str = "page", sort_direction: str = "descending"
|
self, query: str, filter_value: str = "page", sort_direction: str = "descending"
|
||||||
) -> List[Dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
url = "https://api.notion.com/v1/search"
|
url = "https://api.notion.com/v1/search"
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {self.notion_secret}",
|
"Authorization": f"Bearer {self.notion_secret}",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import json
|
import json
|
||||||
from typing import Any, Dict, Union
|
from typing import Any
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
|
|
@ -39,7 +39,7 @@ class NotionPageUpdate(LCToolComponent):
|
||||||
|
|
||||||
class NotionPageUpdateSchema(BaseModel):
|
class NotionPageUpdateSchema(BaseModel):
|
||||||
page_id: str = Field(..., description="The ID of the Notion page to update.")
|
page_id: str = Field(..., description="The ID of the Notion page to update.")
|
||||||
properties: Union[str, Dict[str, Any]] = Field(
|
properties: str | dict[str, Any] = Field(
|
||||||
..., description="The properties to update on the page (as a JSON string or a dictionary)."
|
..., description="The properties to update on the page (as a JSON string or a dictionary)."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ class NotionPageUpdate(LCToolComponent):
|
||||||
args_schema=self.NotionPageUpdateSchema,
|
args_schema=self.NotionPageUpdateSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _update_notion_page(self, page_id: str, properties: Union[str, Dict[str, Any]]) -> Union[Dict[str, Any], str]:
|
def _update_notion_page(self, page_id: str, properties: str | dict[str, Any]) -> dict[str, Any] | str:
|
||||||
url = f"https://api.notion.com/v1/pages/{page_id}"
|
url = f"https://api.notion.com/v1/pages/{page_id}"
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {self.notion_secret}",
|
"Authorization": f"Bearer {self.notion_secret}",
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class JsonAgentComponent(LCAgentComponent):
|
||||||
|
|
||||||
def build_agent(self) -> AgentExecutor:
|
def build_agent(self) -> AgentExecutor:
|
||||||
if self.path.endswith("yaml") or self.path.endswith("yml"):
|
if self.path.endswith("yaml") or self.path.endswith("yml"):
|
||||||
with open(self.path, "r") as file:
|
with open(self.path) as file:
|
||||||
yaml_dict = yaml.load(file, Loader=yaml.FullLoader)
|
yaml_dict = yaml.load(file, Loader=yaml.FullLoader)
|
||||||
spec = JsonSpec(dict_=yaml_dict)
|
spec = JsonSpec(dict_=yaml_dict)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List, Optional
|
|
||||||
|
|
||||||
from langchain.agents import create_openai_tools_agent
|
from langchain.agents import create_openai_tools_agent
|
||||||
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, PromptTemplate
|
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, PromptTemplate
|
||||||
|
|
||||||
|
|
@ -35,7 +33,7 @@ class OpenAIToolsAgentComponent(LCToolsAgentComponent):
|
||||||
DataInput(name="chat_history", display_name="Chat History", is_list=True, advanced=True),
|
DataInput(name="chat_history", display_name="Chat History", is_list=True, advanced=True),
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_chat_history_data(self) -> Optional[List[Data]]:
|
def get_chat_history_data(self) -> list[Data] | None:
|
||||||
return self.chat_history
|
return self.chat_history
|
||||||
|
|
||||||
def create_agent_runnable(self):
|
def create_agent_runnable(self):
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class OpenAPIAgentComponent(LCAgentComponent):
|
||||||
|
|
||||||
def build_agent(self) -> AgentExecutor:
|
def build_agent(self) -> AgentExecutor:
|
||||||
if self.path.endswith("yaml") or self.path.endswith("yml"):
|
if self.path.endswith("yaml") or self.path.endswith("yml"):
|
||||||
with open(self.path, "r") as file:
|
with open(self.path) as file:
|
||||||
yaml_dict = yaml.load(file, Loader=yaml.FullLoader)
|
yaml_dict = yaml.load(file, Loader=yaml.FullLoader)
|
||||||
spec = JsonSpec(dict_=yaml_dict)
|
spec = JsonSpec(dict_=yaml_dict)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List, Optional
|
|
||||||
|
|
||||||
from langchain.agents import create_tool_calling_agent
|
from langchain.agents import create_tool_calling_agent
|
||||||
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, PromptTemplate
|
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, PromptTemplate
|
||||||
|
|
||||||
|
|
@ -30,7 +28,7 @@ class ToolCallingAgentComponent(LCToolsAgentComponent):
|
||||||
DataInput(name="chat_history", display_name="Chat History", is_list=True, advanced=True),
|
DataInput(name="chat_history", display_name="Chat History", is_list=True, advanced=True),
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_chat_history_data(self) -> Optional[List[Data]]:
|
def get_chat_history_data(self) -> list[Data] | None:
|
||||||
return self.chat_history
|
return self.chat_history
|
||||||
|
|
||||||
def create_agent_runnable(self):
|
def create_agent_runnable(self):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List, Optional
|
|
||||||
|
|
||||||
from langchain.agents import create_xml_agent
|
from langchain.agents import create_xml_agent
|
||||||
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, PromptTemplate
|
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, PromptTemplate
|
||||||
|
|
||||||
|
|
@ -52,7 +50,7 @@ Question: {input}
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_chat_history_data(self) -> Optional[List[Data]]:
|
def get_chat_history_data(self) -> list[Data] | None:
|
||||||
return self.chat_history
|
return self.chat_history
|
||||||
|
|
||||||
def create_agent_runnable(self):
|
def create_agent_runnable(self):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
|
||||||
from astra_assistants import patch # type: ignore
|
from astra_assistants import patch # type: ignore
|
||||||
from openai import OpenAI
|
from openai import OpenAI
|
||||||
|
|
@ -20,7 +20,7 @@ class AssistantsRun(Component):
|
||||||
self,
|
self,
|
||||||
build_config: dotdict,
|
build_config: dotdict,
|
||||||
field_value: Any,
|
field_value: Any,
|
||||||
field_name: Optional[str] = None,
|
field_name: str | None = None,
|
||||||
):
|
):
|
||||||
if field_name == "thread_id":
|
if field_name == "thread_id":
|
||||||
if field_value is None:
|
if field_value is None:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
from typing import Any, List, Optional
|
from typing import Any
|
||||||
from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse
|
from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
@ -104,8 +104,8 @@ class APIRequestComponent(Component):
|
||||||
client: httpx.AsyncClient,
|
client: httpx.AsyncClient,
|
||||||
method: str,
|
method: str,
|
||||||
url: str,
|
url: str,
|
||||||
headers: Optional[dict] = None,
|
headers: dict | None = None,
|
||||||
body: Optional[dict] = None,
|
body: dict | None = None,
|
||||||
timeout: int = 5,
|
timeout: int = 5,
|
||||||
) -> Data:
|
) -> Data:
|
||||||
method = method.upper()
|
method = method.upper()
|
||||||
|
|
@ -162,7 +162,7 @@ class APIRequestComponent(Component):
|
||||||
url_parts[4] = urlencode(query)
|
url_parts[4] = urlencode(query)
|
||||||
return urlunparse(url_parts)
|
return urlunparse(url_parts)
|
||||||
|
|
||||||
async def make_requests(self) -> List[Data]:
|
async def make_requests(self) -> list[Data]:
|
||||||
method = self.method
|
method = self.method
|
||||||
urls = [url.strip() for url in self.urls if url.strip()]
|
urls = [url.strip() for url in self.urls if url.strip()]
|
||||||
curl = self.curl
|
curl = self.curl
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langflow.base.data.utils import parallel_load_data, parse_text_file_to_data, retrieve_file_paths
|
from langflow.base.data.utils import parallel_load_data, parse_text_file_to_data, retrieve_file_paths
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
from langflow.io import BoolInput, IntInput, MessageTextInput
|
from langflow.io import BoolInput, IntInput, MessageTextInput
|
||||||
|
|
@ -68,7 +66,7 @@ class DirectoryComponent(Component):
|
||||||
Output(display_name="Data", name="data", method="load_directory"),
|
Output(display_name="Data", name="data", method="load_directory"),
|
||||||
]
|
]
|
||||||
|
|
||||||
def load_directory(self) -> List[Data]:
|
def load_directory(self) -> list[Data]:
|
||||||
path = self.path
|
path = self.path
|
||||||
types = self.types or [] # self.types is already a list due to is_list=True
|
types = self.types or [] # self.types is already a list due to is_list=True
|
||||||
depth = self.depth
|
depth = self.depth
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
from collections.abc import Iterator
|
||||||
from json.decoder import JSONDecodeError
|
from json.decoder import JSONDecodeError
|
||||||
from typing import Any, Iterator, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
from google.auth.exceptions import RefreshError
|
from google.auth.exceptions import RefreshError
|
||||||
from google.oauth2.credentials import Credentials
|
from google.oauth2.credentials import Credentials
|
||||||
|
|
@ -29,7 +30,7 @@ class GmailLoaderComponent(Component):
|
||||||
display_name="JSON String of the Service Account Token",
|
display_name="JSON String of the Service Account Token",
|
||||||
info="JSON string containing OAuth 2.0 access token information for service account access",
|
info="JSON string containing OAuth 2.0 access token information for service account access",
|
||||||
required=True,
|
required=True,
|
||||||
value=str("""{
|
value="""{
|
||||||
"account": "",
|
"account": "",
|
||||||
"client_id": "",
|
"client_id": "",
|
||||||
"client_secret": "",
|
"client_secret": "",
|
||||||
|
|
@ -41,7 +42,7 @@ class GmailLoaderComponent(Component):
|
||||||
"token": "",
|
"token": "",
|
||||||
"token_uri": "https://oauth2.googleapis.com/token",
|
"token_uri": "https://oauth2.googleapis.com/token",
|
||||||
"universe_domain": "googleapis.com"
|
"universe_domain": "googleapis.com"
|
||||||
}"""),
|
}""",
|
||||||
),
|
),
|
||||||
MessageTextInput(
|
MessageTextInput(
|
||||||
name="label_ids",
|
name="label_ids",
|
||||||
|
|
@ -66,7 +67,7 @@ class GmailLoaderComponent(Component):
|
||||||
def load_emails(self) -> Data:
|
def load_emails(self) -> Data:
|
||||||
class CustomGMailLoader(GMailLoader):
|
class CustomGMailLoader(GMailLoader):
|
||||||
def __init__(
|
def __init__(
|
||||||
self, creds: Any, n: int = 100, label_ids: Optional[List[str]] = None, raise_error: bool = False
|
self, creds: Any, n: int = 100, label_ids: list[str] | None = None, raise_error: bool = False
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(creds, n, raise_error)
|
super().__init__(creds, n, raise_error)
|
||||||
self.label_ids = label_ids if label_ids is not None else ["SENT"]
|
self.label_ids = label_ids if label_ids is not None else ["SENT"]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import json
|
import json
|
||||||
from json.decoder import JSONDecodeError
|
from json.decoder import JSONDecodeError
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from google.auth.exceptions import RefreshError
|
from google.auth.exceptions import RefreshError
|
||||||
from google.oauth2.credentials import Credentials
|
from google.oauth2.credentials import Credentials
|
||||||
|
|
@ -37,7 +36,7 @@ class GoogleDriveComponent(Component):
|
||||||
|
|
||||||
def load_documents(self) -> Data:
|
def load_documents(self) -> Data:
|
||||||
class CustomGoogleDriveLoader(GoogleDriveLoader):
|
class CustomGoogleDriveLoader(GoogleDriveLoader):
|
||||||
creds: Optional[Credentials] = None
|
creds: Credentials | None = None
|
||||||
"""Credentials object to be passed directly."""
|
"""Credentials object to be passed directly."""
|
||||||
|
|
||||||
def _load_credentials(self):
|
def _load_credentials(self):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import json
|
import json
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from google.oauth2.credentials import Credentials
|
from google.oauth2.credentials import Credentials
|
||||||
from googleapiclient.discovery import build
|
from googleapiclient.discovery import build
|
||||||
|
|
@ -146,13 +145,13 @@ class GoogleDriveSearchComponent(Component):
|
||||||
|
|
||||||
return {"doc_urls": doc_urls, "doc_ids": doc_ids, "doc_titles_urls": doc_titles_urls, "doc_titles": doc_titles}
|
return {"doc_urls": doc_urls, "doc_ids": doc_ids, "doc_titles_urls": doc_titles_urls, "doc_titles": doc_titles}
|
||||||
|
|
||||||
def search_doc_ids(self) -> List[str]:
|
def search_doc_ids(self) -> list[str]:
|
||||||
return self.search_files()["doc_ids"]
|
return self.search_files()["doc_ids"]
|
||||||
|
|
||||||
def search_doc_urls(self) -> List[str]:
|
def search_doc_urls(self) -> list[str]:
|
||||||
return self.search_files()["doc_urls"]
|
return self.search_files()["doc_urls"]
|
||||||
|
|
||||||
def search_doc_titles(self) -> List[str]:
|
def search_doc_titles(self) -> list[str]:
|
||||||
return self.search_files()["doc_titles"]
|
return self.search_files()["doc_titles"]
|
||||||
|
|
||||||
def search_data(self) -> Data:
|
def search_data(self) -> Data:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_core.documents import Document
|
from langchain_core.documents import Document
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import CustomComponent
|
||||||
|
|
@ -16,7 +14,7 @@ class DocumentsToDataComponent(CustomComponent):
|
||||||
"documents": {"display_name": "Documents"},
|
"documents": {"display_name": "Documents"},
|
||||||
}
|
}
|
||||||
|
|
||||||
def build(self, documents: List[Document]) -> List[Data]:
|
def build(self, documents: list[Document]) -> list[Data]:
|
||||||
if isinstance(documents, Document):
|
if isinstance(documents, Document):
|
||||||
documents = [documents]
|
documents = [documents]
|
||||||
data = [Data.from_document(document) for document in documents]
|
data = [Data.from_document(document) for document in documents]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import CustomComponent
|
||||||
from langflow.schema import Data
|
from langflow.schema import Data
|
||||||
|
|
||||||
|
|
@ -16,7 +14,7 @@ class ListFlowsComponent(CustomComponent):
|
||||||
|
|
||||||
def build(
|
def build(
|
||||||
self,
|
self,
|
||||||
) -> List[Data]:
|
) -> list[Data]:
|
||||||
flows = self.list_flows()
|
flows = self.list_flows()
|
||||||
self.status = flows
|
self.status = flows
|
||||||
return flows
|
return flows
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import CustomComponent
|
||||||
from langflow.schema.message import Message
|
from langflow.schema.message import Message
|
||||||
from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER
|
from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER
|
||||||
|
|
@ -28,8 +26,8 @@ class MessageComponent(CustomComponent):
|
||||||
def build(
|
def build(
|
||||||
self,
|
self,
|
||||||
sender: str = MESSAGE_SENDER_USER,
|
sender: str = MESSAGE_SENDER_USER,
|
||||||
sender_name: Optional[str] = None,
|
sender_name: str | None = None,
|
||||||
session_id: Optional[str] = None,
|
session_id: str | None = None,
|
||||||
text: str = "",
|
text: str = "",
|
||||||
) -> Message:
|
) -> Message:
|
||||||
message = Message(
|
message = Message(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_text_splitters import CharacterTextSplitter
|
from langchain_text_splitters import CharacterTextSplitter
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
|
|
@ -52,7 +50,7 @@ class SplitTextComponent(Component):
|
||||||
data.append(Data(text=doc.page_content, data=doc.metadata))
|
data.append(Data(text=doc.page_content, data=doc.metadata))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def split_text(self) -> List[Data]:
|
def split_text(self) -> list[Data]:
|
||||||
separator = unescape_string(self.separator)
|
separator = unescape_string(self.separator)
|
||||||
|
|
||||||
documents = []
|
documents = []
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
|
@ -22,11 +22,11 @@ class SubFlowComponent(CustomComponent):
|
||||||
field_order = ["flow_name"]
|
field_order = ["flow_name"]
|
||||||
name = "SubFlow"
|
name = "SubFlow"
|
||||||
|
|
||||||
def get_flow_names(self) -> List[str]:
|
def get_flow_names(self) -> list[str]:
|
||||||
flow_datas = self.list_flows()
|
flow_datas = self.list_flows()
|
||||||
return [flow_data.data["name"] for flow_data in flow_datas]
|
return [flow_data.data["name"] for flow_data in flow_datas]
|
||||||
|
|
||||||
def get_flow(self, flow_name: str) -> Optional[Data]:
|
def get_flow(self, flow_name: str) -> Data | None:
|
||||||
flow_datas = self.list_flows()
|
flow_datas = self.list_flows()
|
||||||
for flow_data in flow_datas:
|
for flow_data in flow_datas:
|
||||||
if flow_data.data["name"] == flow_name:
|
if flow_data.data["name"] == flow_name:
|
||||||
|
|
@ -56,7 +56,7 @@ class SubFlowComponent(CustomComponent):
|
||||||
|
|
||||||
return build_config
|
return build_config
|
||||||
|
|
||||||
def add_inputs_to_build_config(self, inputs: List[Vertex], build_config: dotdict):
|
def add_inputs_to_build_config(self, inputs: list[Vertex], build_config: dotdict):
|
||||||
new_fields: list[Input] = []
|
new_fields: list[Input] = []
|
||||||
for vertex in inputs:
|
for vertex in inputs:
|
||||||
field = Input(
|
field = Input(
|
||||||
|
|
@ -96,9 +96,9 @@ class SubFlowComponent(CustomComponent):
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async def build(self, flow_name: str, get_final_results_only: bool = True, **kwargs) -> List[Data]:
|
async def build(self, flow_name: str, get_final_results_only: bool = True, **kwargs) -> list[Data]:
|
||||||
tweaks = {key: {"input_value": value} for key, value in kwargs.items()}
|
tweaks = {key: {"input_value": value} for key, value in kwargs.items()}
|
||||||
run_outputs: List[Optional[RunOutputs]] = await self.run_flow(
|
run_outputs: list[RunOutputs | None] = await self.run_flow(
|
||||||
tweaks=tweaks,
|
tweaks=tweaks,
|
||||||
flow_name=flow_name,
|
flow_name=flow_name,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.document_loaders import ConfluenceLoader
|
from langchain_community.document_loaders import ConfluenceLoader
|
||||||
from langchain_community.document_loaders.confluence import ContentFormat
|
from langchain_community.document_loaders.confluence import ContentFormat
|
||||||
|
|
||||||
|
|
@ -79,7 +77,7 @@ class ConfluenceComponent(Component):
|
||||||
)
|
)
|
||||||
return loader
|
return loader
|
||||||
|
|
||||||
def load_documents(self) -> List[Data]:
|
def load_documents(self) -> list[Data]:
|
||||||
confluence = self.build_confluence()
|
confluence = self.build_confluence()
|
||||||
documents = confluence.load()
|
documents = confluence.load()
|
||||||
data = [Data.from_document(doc) for doc in documents] # Using the from_document method of Data
|
data = [Data.from_document(doc) for doc in documents] # Using the from_document method of Data
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import re
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.document_loaders.git import GitLoader
|
from langchain_community.document_loaders.git import GitLoader
|
||||||
|
|
||||||
|
|
@ -109,7 +108,7 @@ class GitLoaderComponent(Component):
|
||||||
)
|
)
|
||||||
return loader
|
return loader
|
||||||
|
|
||||||
def load_documents(self) -> List[Data]:
|
def load_documents(self) -> list[Data]:
|
||||||
gitloader = self.build_gitloader()
|
gitloader = self.build_gitloader()
|
||||||
documents = list(gitloader.lazy_load())
|
documents = list(gitloader.lazy_load())
|
||||||
data = [Data.from_document(doc) for doc in documents]
|
data = [Data.from_document(doc) for doc in documents]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_unstructured import UnstructuredLoader
|
from langchain_unstructured import UnstructuredLoader
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
|
|
@ -47,7 +45,7 @@ class UnstructuredComponent(Component):
|
||||||
|
|
||||||
return loader
|
return loader
|
||||||
|
|
||||||
def load_documents(self) -> List[Data]:
|
def load_documents(self) -> list[Data]:
|
||||||
unstructured = self.build_unstructured()
|
unstructured = self.build_unstructured()
|
||||||
|
|
||||||
documents = unstructured.load()
|
documents = unstructured.load()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
|
|
@ -33,7 +31,7 @@ class EmbeddingSimilarityComponent(Component):
|
||||||
]
|
]
|
||||||
|
|
||||||
def compute_similarity(self) -> Data:
|
def compute_similarity(self) -> Data:
|
||||||
embedding_vectors: List[Data] = self.embedding_vectors
|
embedding_vectors: list[Data] = self.embedding_vectors
|
||||||
|
|
||||||
# Assert that the list contains exactly two Data objects
|
# Assert that the list contains exactly two Data objects
|
||||||
assert len(embedding_vectors) == 2, "Exactly two embedding vectors are required."
|
assert len(embedding_vectors) == 2, "Exactly two embedding vectors are required."
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,11 @@
|
||||||
# from langflow.field_typing import Data
|
# from langflow.field_typing import Data
|
||||||
from typing import List, Optional
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
# TODO: remove ignore once the google package is published with types
|
# TODO: remove ignore once the google package is published with types
|
||||||
from google.ai.generativelanguage_v1beta.types import (
|
from google.ai.generativelanguage_v1beta.types import BatchEmbedContentsRequest
|
||||||
BatchEmbedContentsRequest,
|
|
||||||
)
|
|
||||||
from langchain_core.embeddings import Embeddings
|
from langchain_core.embeddings import Embeddings
|
||||||
from langchain_google_genai import GoogleGenerativeAIEmbeddings
|
from langchain_google_genai import GoogleGenerativeAIEmbeddings
|
||||||
from langchain_google_genai._common import (
|
from langchain_google_genai._common import GoogleGenerativeAIError
|
||||||
GoogleGenerativeAIError,
|
|
||||||
)
|
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
from langflow.io import MessageTextInput, Output, SecretStrInput
|
from langflow.io import MessageTextInput, Output, SecretStrInput
|
||||||
|
|
@ -43,13 +37,13 @@ class GoogleGenerativeAIEmbeddingsComponent(Component):
|
||||||
|
|
||||||
def embed_documents(
|
def embed_documents(
|
||||||
self,
|
self,
|
||||||
texts: List[str],
|
texts: list[str],
|
||||||
*,
|
*,
|
||||||
batch_size: int = 100,
|
batch_size: int = 100,
|
||||||
task_type: Optional[str] = None,
|
task_type: str | None = None,
|
||||||
titles: Optional[List[str]] = None,
|
titles: list[str] | None = None,
|
||||||
output_dimensionality: Optional[int] = 1536,
|
output_dimensionality: int | None = 1536,
|
||||||
) -> List[List[float]]:
|
) -> list[list[float]]:
|
||||||
"""Embed a list of strings. Google Generative AI currently
|
"""Embed a list of strings. Google Generative AI currently
|
||||||
sets a max batch size of 100 strings.
|
sets a max batch size of 100 strings.
|
||||||
|
|
||||||
|
|
@ -64,7 +58,7 @@ class GoogleGenerativeAIEmbeddingsComponent(Component):
|
||||||
Returns:
|
Returns:
|
||||||
List of embeddings, one for each text.
|
List of embeddings, one for each text.
|
||||||
"""
|
"""
|
||||||
embeddings: List[List[float]] = []
|
embeddings: list[list[float]] = []
|
||||||
batch_start_index = 0
|
batch_start_index = 0
|
||||||
for batch in GoogleGenerativeAIEmbeddings._prepare_batches(texts, batch_size):
|
for batch in GoogleGenerativeAIEmbeddings._prepare_batches(texts, batch_size):
|
||||||
if titles:
|
if titles:
|
||||||
|
|
@ -95,10 +89,10 @@ class GoogleGenerativeAIEmbeddingsComponent(Component):
|
||||||
def embed_query(
|
def embed_query(
|
||||||
self,
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
task_type: Optional[str] = None,
|
task_type: str | None = None,
|
||||||
title: Optional[str] = None,
|
title: str | None = None,
|
||||||
output_dimensionality: Optional[int] = 1536,
|
output_dimensionality: int | None = 1536,
|
||||||
) -> List[float]:
|
) -> list[float]:
|
||||||
"""Embed a text.
|
"""Embed a text.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
import json
|
import json
|
||||||
from typing import List
|
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from langchain_core.pydantic_v1 import BaseModel, SecretStr
|
from langchain_core.pydantic_v1 import BaseModel, SecretStr
|
||||||
|
|
@ -15,7 +14,7 @@ class AIMLEmbeddingsImpl(BaseModel, Embeddings):
|
||||||
api_key: SecretStr
|
api_key: SecretStr
|
||||||
model: str
|
model: str
|
||||||
|
|
||||||
def embed_documents(self, texts: List[str]) -> List[List[float]]:
|
def embed_documents(self, texts: list[str]) -> list[list[float]]:
|
||||||
embeddings = [None] * len(texts)
|
embeddings = [None] * len(texts)
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
@ -58,5 +57,5 @@ class AIMLEmbeddingsImpl(BaseModel, Embeddings):
|
||||||
result_data = response.json()
|
result_data = response.json()
|
||||||
return result_data
|
return result_data
|
||||||
|
|
||||||
def embed_query(self, text: str) -> List[float]:
|
def embed_query(self, text: str) -> list[float]:
|
||||||
return self.embed_documents([text])[0]
|
return self.embed_documents([text])[0]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
from langflow.io import DataInput, MessageTextInput, Output
|
from langflow.io import DataInput, MessageTextInput, Output
|
||||||
from langflow.schema import Data
|
from langflow.schema import Data
|
||||||
|
|
@ -31,7 +29,7 @@ class FilterDataComponent(Component):
|
||||||
]
|
]
|
||||||
|
|
||||||
def filter_data(self) -> Data:
|
def filter_data(self) -> Data:
|
||||||
filter_criteria: List[str] = self.filter_criteria
|
filter_criteria: list[str] = self.filter_criteria
|
||||||
data = self.data.data if isinstance(self.data, Data) else {}
|
data = self.data.data if isinstance(self.data, Data) else {}
|
||||||
|
|
||||||
# Filter the data
|
# Filter the data
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
from langflow.io import MessageTextInput, Output
|
from langflow.io import MessageTextInput, Output
|
||||||
|
|
@ -26,7 +26,7 @@ class IDGeneratorComponent(Component):
|
||||||
Output(display_name="ID", name="id", method="generate_id"),
|
Output(display_name="ID", name="id", method="generate_id"),
|
||||||
]
|
]
|
||||||
|
|
||||||
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: Optional[str] = None):
|
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None):
|
||||||
if field_name == "unique_id":
|
if field_name == "unique_id":
|
||||||
build_config[field_name]["value"] = str(uuid.uuid4())
|
build_config[field_name]["value"] = str(uuid.uuid4())
|
||||||
return build_config
|
return build_config
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_text_splitters import CharacterTextSplitter
|
from langchain_text_splitters import CharacterTextSplitter
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
|
|
@ -52,7 +50,7 @@ class SplitTextComponent(Component):
|
||||||
data.append(Data(text=doc.page_content, data=doc.metadata))
|
data.append(Data(text=doc.page_content, data=doc.metadata))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def split_text(self) -> List[Data]:
|
def split_text(self) -> list[Data]:
|
||||||
separator = unescape_string(self.separator)
|
separator = unescape_string(self.separator)
|
||||||
|
|
||||||
documents = []
|
documents = []
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import CustomComponent
|
||||||
from langflow.schema import Data
|
from langflow.schema import Data
|
||||||
|
|
@ -51,9 +50,9 @@ class FirecrawlCrawlApi(CustomComponent):
|
||||||
api_key: str,
|
api_key: str,
|
||||||
url: str,
|
url: str,
|
||||||
timeout: int = 30000,
|
timeout: int = 30000,
|
||||||
crawlerOptions: Optional[Data] = None,
|
crawlerOptions: Data | None = None,
|
||||||
pageOptions: Optional[Data] = None,
|
pageOptions: Data | None = None,
|
||||||
idempotency_key: Optional[str] = None,
|
idempotency_key: str | None = None,
|
||||||
) -> Data:
|
) -> Data:
|
||||||
try:
|
try:
|
||||||
from firecrawl.firecrawl import FirecrawlApp # type: ignore
|
from firecrawl.firecrawl import FirecrawlApp # type: ignore
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import CustomComponent
|
||||||
from langflow.schema import Data
|
from langflow.schema import Data
|
||||||
|
|
||||||
|
|
@ -46,8 +44,8 @@ class FirecrawlScrapeApi(CustomComponent):
|
||||||
api_key: str,
|
api_key: str,
|
||||||
url: str,
|
url: str,
|
||||||
timeout: int = 10000,
|
timeout: int = 10000,
|
||||||
pageOptions: Optional[Data] = None,
|
pageOptions: Data | None = None,
|
||||||
extractorOptions: Optional[Data] = None,
|
extractorOptions: Data | None = None,
|
||||||
) -> Data:
|
) -> Data:
|
||||||
try:
|
try:
|
||||||
from firecrawl.firecrawl import FirecrawlApp # type: ignore
|
from firecrawl.firecrawl import FirecrawlApp # type: ignore
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from langchain_groq import ChatGroq
|
from langchain_groq import ChatGroq
|
||||||
from pydantic.v1 import SecretStr
|
from pydantic.v1 import SecretStr
|
||||||
|
|
@ -55,7 +53,7 @@ class GroqModel(LCModelComponent):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_models(self) -> List[str]:
|
def get_models(self) -> list[str]:
|
||||||
api_key = self.groq_api_key
|
api_key = self.groq_api_key
|
||||||
base_url = self.groq_api_base or "https://api.groq.com"
|
base_url = self.groq_api_base or "https://api.groq.com"
|
||||||
url = f"{base_url}/openai/v1/models"
|
url = f"{base_url}/openai/v1/models"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any
|
||||||
|
|
||||||
from langchain_community.llms.huggingface_endpoint import HuggingFaceEndpoint
|
from langchain_community.llms.huggingface_endpoint import HuggingFaceEndpoint
|
||||||
from tenacity import retry, stop_after_attempt, wait_fixed
|
from tenacity import retry, stop_after_attempt, wait_fixed
|
||||||
|
|
@ -84,15 +84,15 @@ class HuggingFaceEndpointsComponent(LCModelComponent):
|
||||||
def create_huggingface_endpoint(
|
def create_huggingface_endpoint(
|
||||||
self,
|
self,
|
||||||
model_id: str,
|
model_id: str,
|
||||||
task: Optional[str],
|
task: str | None,
|
||||||
huggingfacehub_api_token: Optional[str],
|
huggingfacehub_api_token: str | None,
|
||||||
model_kwargs: Dict[str, Any],
|
model_kwargs: dict[str, Any],
|
||||||
max_new_tokens: int,
|
max_new_tokens: int,
|
||||||
top_k: Optional[int],
|
top_k: int | None,
|
||||||
top_p: float,
|
top_p: float,
|
||||||
typical_p: Optional[float],
|
typical_p: float | None,
|
||||||
temperature: Optional[float],
|
temperature: float | None,
|
||||||
repetition_penalty: Optional[float],
|
repetition_penalty: float | None,
|
||||||
) -> HuggingFaceEndpoint:
|
) -> HuggingFaceEndpoint:
|
||||||
retry_attempts = self.retry_attempts
|
retry_attempts = self.retry_attempts
|
||||||
endpoint_url = self.get_api_url()
|
endpoint_url = self.get_api_url()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import re
|
import re
|
||||||
from typing import List
|
|
||||||
|
from langchain_core.prompts import HumanMessagePromptTemplate
|
||||||
|
|
||||||
from langchain_core.prompts import HumanMessagePromptTemplate
|
from langchain_core.prompts import HumanMessagePromptTemplate
|
||||||
|
|
||||||
|
|
@ -55,7 +56,7 @@ class LangChainHubPromptComponent(Component):
|
||||||
pattern = r"\{(.*?)\}"
|
pattern = r"\{(.*?)\}"
|
||||||
|
|
||||||
# Get all the custom fields
|
# Get all the custom fields
|
||||||
custom_fields: List[str] = []
|
custom_fields: list[str] = []
|
||||||
full_template = ""
|
full_template = ""
|
||||||
for message in prompt_template:
|
for message in prompt_template:
|
||||||
# Find all matches
|
# Find all matches
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Any, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
from langflow.base.langchain_utilities.model import LCToolComponent
|
from langflow.base.langchain_utilities.model import LCToolComponent
|
||||||
from langflow.base.tools.flow_tool import FlowTool
|
from langflow.base.tools.flow_tool import FlowTool
|
||||||
|
|
@ -19,11 +19,11 @@ class FlowToolComponent(LCToolComponent):
|
||||||
name = "FlowTool"
|
name = "FlowTool"
|
||||||
beta = True
|
beta = True
|
||||||
|
|
||||||
def get_flow_names(self) -> List[str]:
|
def get_flow_names(self) -> list[str]:
|
||||||
flow_datas = self.list_flows()
|
flow_datas = self.list_flows()
|
||||||
return [flow_data.data["name"] for flow_data in flow_datas]
|
return [flow_data.data["name"] for flow_data in flow_datas]
|
||||||
|
|
||||||
def get_flow(self, flow_name: str) -> Optional[Data]:
|
def get_flow(self, flow_name: str) -> Data | None:
|
||||||
"""
|
"""
|
||||||
Retrieves a flow by its name.
|
Retrieves a flow by its name.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import CustomComponent
|
||||||
from langflow.schema import Data
|
from langflow.schema import Data
|
||||||
|
|
||||||
|
|
@ -21,7 +19,7 @@ class NotifyComponent(CustomComponent):
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def build(self, name: str, data: Optional[Data] = None, append: bool = False) -> Data:
|
def build(self, name: str, data: Data | None = None, append: bool = False) -> Data:
|
||||||
if data and not isinstance(data, Data):
|
if data and not isinstance(data, Data):
|
||||||
if isinstance(data, str):
|
if isinstance(data, str):
|
||||||
data = Data(text=data)
|
data = Data(text=data)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Callable, List
|
from collections.abc import Callable
|
||||||
|
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
from langflow.custom.utils import get_function
|
from langflow.custom.utils import get_function
|
||||||
|
|
@ -46,7 +46,7 @@ class PythonFunctionComponent(Component):
|
||||||
func = get_function(function_code)
|
func = get_function(function_code)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
def execute_function(self) -> List[dotdict | str] | dotdict | str:
|
def execute_function(self) -> list[dotdict | str] | dotdict | str:
|
||||||
function_code = self.function_code
|
function_code = self.function_code
|
||||||
|
|
||||||
if not function_code:
|
if not function_code:
|
||||||
|
|
@ -58,7 +58,7 @@ class PythonFunctionComponent(Component):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"Error executing function: {str(e)}"
|
return f"Error executing function: {str(e)}"
|
||||||
|
|
||||||
def execute_function_data(self) -> List[Data]:
|
def execute_function_data(self) -> list[Data]:
|
||||||
results = self.execute_function()
|
results = self.execute_function()
|
||||||
results = results if isinstance(results, list) else [results]
|
results = results if isinstance(results, list) else [results]
|
||||||
data = [(Data(text=x) if isinstance(x, str) else Data(**x)) for x in results]
|
data = [(Data(text=x) if isinstance(x, str) else Data(**x)) for x in results]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
from langflow.base.flow_processing.utils import build_data_from_run_outputs
|
from langflow.base.flow_processing.utils import build_data_from_run_outputs
|
||||||
from langflow.custom import Component
|
from langflow.custom import Component
|
||||||
|
|
@ -13,7 +13,7 @@ class RunFlowComponent(Component):
|
||||||
name = "RunFlow"
|
name = "RunFlow"
|
||||||
beta: bool = True
|
beta: bool = True
|
||||||
|
|
||||||
def get_flow_names(self) -> List[str]:
|
def get_flow_names(self) -> list[str]:
|
||||||
flow_data = self.list_flows()
|
flow_data = self.list_flows()
|
||||||
return [flow_data.data["name"] for flow_data in flow_data]
|
return [flow_data.data["name"] for flow_data in flow_data]
|
||||||
|
|
||||||
|
|
@ -47,12 +47,12 @@ class RunFlowComponent(Component):
|
||||||
Output(display_name="Run Outputs", name="run_outputs", method="generate_results"),
|
Output(display_name="Run Outputs", name="run_outputs", method="generate_results"),
|
||||||
]
|
]
|
||||||
|
|
||||||
async def generate_results(self) -> List[Data]:
|
async def generate_results(self) -> list[Data]:
|
||||||
if "flow_name" not in self._attributes or not self._attributes["flow_name"]:
|
if "flow_name" not in self._attributes or not self._attributes["flow_name"]:
|
||||||
raise ValueError("Flow name is required")
|
raise ValueError("Flow name is required")
|
||||||
flow_name = self._attributes["flow_name"]
|
flow_name = self._attributes["flow_name"]
|
||||||
|
|
||||||
results: List[Optional[RunOutputs]] = await self.run_flow(
|
results: list[RunOutputs | None] = await self.run_flow(
|
||||||
inputs={"input_value": self.input_value}, flow_name=flow_name, tweaks=self.tweaks
|
inputs={"input_value": self.input_value}, flow_name=flow_name, tweaks=self.tweaks
|
||||||
)
|
)
|
||||||
if isinstance(results, list):
|
if isinstance(results, list):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
|
@ -17,11 +17,11 @@ class SubFlowComponent(Component):
|
||||||
name = "SubFlow"
|
name = "SubFlow"
|
||||||
beta: bool = True
|
beta: bool = True
|
||||||
|
|
||||||
def get_flow_names(self) -> List[str]:
|
def get_flow_names(self) -> list[str]:
|
||||||
flow_data = self.list_flows()
|
flow_data = self.list_flows()
|
||||||
return [flow_data.data["name"] for flow_data in flow_data]
|
return [flow_data.data["name"] for flow_data in flow_data]
|
||||||
|
|
||||||
def get_flow(self, flow_name: str) -> Optional[Data]:
|
def get_flow(self, flow_name: str) -> Data | None:
|
||||||
flow_datas = self.list_flows()
|
flow_datas = self.list_flows()
|
||||||
for flow_data in flow_datas:
|
for flow_data in flow_datas:
|
||||||
if flow_data.data["name"] == flow_name:
|
if flow_data.data["name"] == flow_name:
|
||||||
|
|
@ -50,7 +50,7 @@ class SubFlowComponent(Component):
|
||||||
|
|
||||||
return build_config
|
return build_config
|
||||||
|
|
||||||
def add_inputs_to_build_config(self, inputs_vertex: List[Vertex], build_config: dotdict):
|
def add_inputs_to_build_config(self, inputs_vertex: list[Vertex], build_config: dotdict):
|
||||||
new_fields: list[dotdict] = []
|
new_fields: list[dotdict] = []
|
||||||
|
|
||||||
for vertex in inputs_vertex:
|
for vertex in inputs_vertex:
|
||||||
|
|
@ -81,7 +81,7 @@ class SubFlowComponent(Component):
|
||||||
|
|
||||||
outputs = [Output(name="flow_outputs", display_name="Flow Outputs", method="generate_results")]
|
outputs = [Output(name="flow_outputs", display_name="Flow Outputs", method="generate_results")]
|
||||||
|
|
||||||
async def generate_results(self) -> List[Data]:
|
async def generate_results(self) -> list[Data]:
|
||||||
tweaks: dict = {}
|
tweaks: dict = {}
|
||||||
for field in self._attributes.keys():
|
for field in self._attributes.keys():
|
||||||
if field != "flow_name":
|
if field != "flow_name":
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Optional, cast
|
from typing import cast
|
||||||
|
|
||||||
from langchain_community.retrievers import AmazonKendraRetriever
|
from langchain_community.retrievers import AmazonKendraRetriever
|
||||||
|
|
||||||
|
|
@ -33,10 +33,10 @@ class AmazonKendraRetrieverComponent(CustomComponent):
|
||||||
self,
|
self,
|
||||||
index_id: str,
|
index_id: str,
|
||||||
top_k: int = 3,
|
top_k: int = 3,
|
||||||
region_name: Optional[str] = None,
|
region_name: str | None = None,
|
||||||
credentials_profile_name: Optional[str] = None,
|
credentials_profile_name: str | None = None,
|
||||||
attribute_filter: Optional[dict] = None,
|
attribute_filter: dict | None = None,
|
||||||
user_context: Optional[dict] = None,
|
user_context: dict | None = None,
|
||||||
) -> Retriever: # type: ignore[type-var]
|
) -> Retriever: # type: ignore[type-var]
|
||||||
try:
|
try:
|
||||||
output = AmazonKendraRetriever(
|
output = AmazonKendraRetriever(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import List, cast
|
from typing import cast
|
||||||
|
|
||||||
from langchain.retrievers import ContextualCompressionRetriever
|
from langchain.retrievers import ContextualCompressionRetriever
|
||||||
from langchain_cohere import CohereRerank
|
from langchain_cohere import CohereRerank
|
||||||
|
|
@ -73,7 +73,7 @@ class CohereRerankComponent(LCVectorStoreComponent):
|
||||||
retriever = ContextualCompressionRetriever(base_compressor=cohere_reranker, base_retriever=self.retriever)
|
retriever = ContextualCompressionRetriever(base_compressor=cohere_reranker, base_retriever=self.retriever)
|
||||||
return cast(Retriever, retriever)
|
return cast(Retriever, retriever)
|
||||||
|
|
||||||
async def search_documents(self) -> List[Data]: # type: ignore
|
async def search_documents(self) -> list[Data]: # type: ignore
|
||||||
retriever = self.build_base_retriever()
|
retriever = self.build_base_retriever()
|
||||||
documents = await retriever.ainvoke(self.search_query, config={"callbacks": self.get_langchain_callbacks()})
|
documents = await retriever.ainvoke(self.search_query, config={"callbacks": self.get_langchain_callbacks()})
|
||||||
data = self.to_data(documents)
|
data = self.to_data(documents)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Optional, cast
|
from typing import cast
|
||||||
|
|
||||||
from langchain_community.retrievers import MetalRetriever
|
from langchain_community.retrievers import MetalRetriever
|
||||||
from metal_sdk.metal import Metal # type: ignore
|
from metal_sdk.metal import Metal # type: ignore
|
||||||
|
|
@ -21,7 +21,7 @@ class MetalRetrieverComponent(CustomComponent):
|
||||||
"code": {"show": False},
|
"code": {"show": False},
|
||||||
}
|
}
|
||||||
|
|
||||||
def build(self, api_key: str, client_id: str, index_id: str, params: Optional[dict] = None) -> Retriever: # type: ignore[type-var]
|
def build(self, api_key: str, client_id: str, index_id: str, params: dict | None = None) -> Retriever: # type: ignore[type-var]
|
||||||
try:
|
try:
|
||||||
metal = Metal(api_key=api_key, client_id=client_id, index_id=index_id)
|
metal = Metal(api_key=api_key, client_id=client_id, index_id=index_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from langchain.retrievers import MultiQueryRetriever
|
from langchain.retrievers import MultiQueryRetriever
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import CustomComponent
|
||||||
|
|
@ -42,7 +40,7 @@ class MultiQueryRetrieverComponent(CustomComponent):
|
||||||
self,
|
self,
|
||||||
llm: LanguageModel,
|
llm: LanguageModel,
|
||||||
retriever: BaseRetriever,
|
retriever: BaseRetriever,
|
||||||
prompt: Optional[Text] = None,
|
prompt: Text | None = None,
|
||||||
parser_key: str = "lines",
|
parser_key: str = "lines",
|
||||||
) -> MultiQueryRetriever:
|
) -> MultiQueryRetriever:
|
||||||
if not prompt:
|
if not prompt:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, List, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from langchain.retrievers import ContextualCompressionRetriever
|
from langchain.retrievers import ContextualCompressionRetriever
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ class NvidiaRerankComponent(LCVectorStoreComponent):
|
||||||
retriever = ContextualCompressionRetriever(base_compressor=nvidia_reranker, base_retriever=self.retriever)
|
retriever = ContextualCompressionRetriever(base_compressor=nvidia_reranker, base_retriever=self.retriever)
|
||||||
return cast(Retriever, retriever)
|
return cast(Retriever, retriever)
|
||||||
|
|
||||||
async def search_documents(self) -> List[Data]: # type: ignore
|
async def search_documents(self) -> list[Data]: # type: ignore
|
||||||
retriever = self.build_base_retriever()
|
retriever = self.build_base_retriever()
|
||||||
documents = await retriever.ainvoke(self.search_query, config={"callbacks": self.get_langchain_callbacks()})
|
documents = await retriever.ainvoke(self.search_query, config={"callbacks": self.get_langchain_callbacks()})
|
||||||
data = self.to_data(documents)
|
data = self.to_data(documents)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain.chains.query_constructor.base import AttributeInfo
|
from langchain.chains.query_constructor.base import AttributeInfo
|
||||||
from langchain.retrievers.self_query.base import SelfQueryRetriever
|
from langchain.retrievers.self_query.base import SelfQueryRetriever
|
||||||
|
|
||||||
|
|
@ -53,7 +51,7 @@ class SelfQueryRetrieverComponent(Component):
|
||||||
Output(display_name="Retrieved Documents", name="documents", method="retrieve_documents"),
|
Output(display_name="Retrieved Documents", name="documents", method="retrieve_documents"),
|
||||||
]
|
]
|
||||||
|
|
||||||
def retrieve_documents(self) -> List[Data]:
|
def retrieve_documents(self) -> list[Data]:
|
||||||
metadata_field_infos = [AttributeInfo(**value.data) for value in self.attribute_infos]
|
metadata_field_infos = [AttributeInfo(**value.data) for value in self.attribute_infos]
|
||||||
self_query_retriever = SelfQueryRetriever.from_llm(
|
self_query_retriever = SelfQueryRetriever.from_llm(
|
||||||
llm=self.llm,
|
llm=self.llm,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import json
|
import json
|
||||||
from typing import List, cast
|
from typing import cast
|
||||||
|
|
||||||
from langchain.chains.query_constructor.base import AttributeInfo
|
from langchain.chains.query_constructor.base import AttributeInfo
|
||||||
from langchain.retrievers.self_query.base import SelfQueryRetriever
|
from langchain.retrievers.self_query.base import SelfQueryRetriever
|
||||||
|
|
@ -40,7 +40,7 @@ class VectaraSelfQueryRetriverComponent(CustomComponent):
|
||||||
vectorstore: VectorStore,
|
vectorstore: VectorStore,
|
||||||
document_content_description: str,
|
document_content_description: str,
|
||||||
llm: LanguageModel,
|
llm: LanguageModel,
|
||||||
metadata_field_info: List[str],
|
metadata_field_info: list[str],
|
||||||
) -> Retriever: # type: ignore
|
) -> Retriever: # type: ignore
|
||||||
metadata_field_obj = []
|
metadata_field_obj = []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from typing import Any, Sequence
|
from collections.abc import Sequence
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from composio_langchain import Action, App, ComposioToolSet # type: ignore
|
from composio_langchain import Action, App, ComposioToolSet # type: ignore
|
||||||
from langchain_core.tools import Tool
|
from langchain_core.tools import Tool
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List, Union
|
|
||||||
|
|
||||||
from langchain_community.agent_toolkits.base import BaseToolkit
|
from langchain_community.agent_toolkits.base import BaseToolkit
|
||||||
from langchain_core.tools import Tool, tool
|
from langchain_core.tools import Tool, tool
|
||||||
from metaphor_python import Metaphor # type: ignore
|
from metaphor_python import Metaphor # type: ignore
|
||||||
|
|
@ -25,7 +23,7 @@ class MetaphorToolkit(CustomComponent):
|
||||||
use_autoprompt: bool = True,
|
use_autoprompt: bool = True,
|
||||||
search_num_results: int = 5,
|
search_num_results: int = 5,
|
||||||
similar_num_results: int = 5,
|
similar_num_results: int = 5,
|
||||||
) -> Union[Tool, BaseToolkit]:
|
) -> Tool | BaseToolkit:
|
||||||
# If documents, then we need to create a Vectara instance using .from_documents
|
# If documents, then we need to create a Vectara instance using .from_documents
|
||||||
client = Metaphor(api_key=metaphor_api_key)
|
client = Metaphor(api_key=metaphor_api_key)
|
||||||
|
|
||||||
|
|
@ -35,7 +33,7 @@ class MetaphorToolkit(CustomComponent):
|
||||||
return client.search(query, use_autoprompt=use_autoprompt, num_results=search_num_results)
|
return client.search(query, use_autoprompt=use_autoprompt, num_results=search_num_results)
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
def get_contents(ids: List[str]):
|
def get_contents(ids: list[str]):
|
||||||
"""Get contents of a webpage.
|
"""Get contents of a webpage.
|
||||||
|
|
||||||
The ids passed in should be a list of ids as fetched from `search`.
|
The ids passed in should be a list of ids as fetched from `search`.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import List, cast
|
from typing import cast
|
||||||
|
|
||||||
from langchain_community.tools.bing_search import BingSearchResults
|
from langchain_community.tools.bing_search import BingSearchResults
|
||||||
from langchain_community.utilities import BingSearchAPIWrapper
|
from langchain_community.utilities import BingSearchAPIWrapper
|
||||||
|
|
@ -24,7 +24,7 @@ class BingSearchAPIComponent(LCToolComponent):
|
||||||
IntInput(name="k", display_name="Number of results", value=4, required=True),
|
IntInput(name="k", display_name="Number of results", value=4, required=True),
|
||||||
]
|
]
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
if self.bing_search_url:
|
if self.bing_search_url:
|
||||||
wrapper = BingSearchAPIWrapper(
|
wrapper = BingSearchAPIWrapper(
|
||||||
bing_search_url=self.bing_search_url, bing_subscription_key=self.bing_subscription_key
|
bing_search_url=self.bing_search_url, bing_subscription_key=self.bing_subscription_key
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import ast
|
import ast
|
||||||
import operator
|
import operator
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
@ -28,7 +27,7 @@ class CalculatorToolComponent(LCToolComponent):
|
||||||
class CalculatorToolSchema(BaseModel):
|
class CalculatorToolSchema(BaseModel):
|
||||||
expression: str = Field(..., description="The arithmetic expression to evaluate.")
|
expression: str = Field(..., description="The arithmetic expression to evaluate.")
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
return self._evaluate_expression(self.expression)
|
return self._evaluate_expression(self.expression)
|
||||||
|
|
||||||
def build_tool(self) -> Tool:
|
def build_tool(self) -> Tool:
|
||||||
|
|
@ -39,7 +38,7 @@ class CalculatorToolComponent(LCToolComponent):
|
||||||
args_schema=self.CalculatorToolSchema,
|
args_schema=self.CalculatorToolSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _evaluate_expression(self, expression: str) -> List[Data]:
|
def _evaluate_expression(self, expression: str) -> list[Data]:
|
||||||
try:
|
try:
|
||||||
# Define the allowed operators
|
# Define the allowed operators
|
||||||
operators = {
|
operators = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, Dict, List
|
from typing import Any
|
||||||
|
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
from langchain_community.tools import DuckDuckGoSearchRun
|
from langchain_community.tools import DuckDuckGoSearchRun
|
||||||
|
|
@ -37,7 +37,7 @@ class DuckDuckGoSearchComponent(LCToolComponent):
|
||||||
def build_tool(self) -> Tool:
|
def build_tool(self) -> Tool:
|
||||||
wrapper = self._build_wrapper()
|
wrapper = self._build_wrapper()
|
||||||
|
|
||||||
def search_func(query: str, max_results: int = 5, max_snippet_length: int = 100) -> List[Dict[str, Any]]:
|
def search_func(query: str, max_results: int = 5, max_snippet_length: int = 100) -> list[dict[str, Any]]:
|
||||||
full_results = wrapper.run(f"{query} (site:*)")
|
full_results = wrapper.run(f"{query} (site:*)")
|
||||||
result_list = full_results.split("\n")[:max_results]
|
result_list = full_results.split("\n")[:max_results]
|
||||||
limited_results = []
|
limited_results = []
|
||||||
|
|
@ -57,7 +57,7 @@ class DuckDuckGoSearchComponent(LCToolComponent):
|
||||||
self.status = "DuckDuckGo Search Tool created"
|
self.status = "DuckDuckGo Search Tool created"
|
||||||
return tool
|
return tool
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
tool = self.build_tool()
|
tool = self.build_tool()
|
||||||
results = tool.run(
|
results = tool.run(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import json
|
import json
|
||||||
from typing import Any, Dict, Optional, Union
|
from typing import Any
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
@ -33,7 +33,7 @@ class GleanSearchAPIComponent(LCToolComponent):
|
||||||
|
|
||||||
return Tool(name="glean_search_api", description="Search with the Glean API", func=wrapper.run)
|
return Tool(name="glean_search_api", description="Search with the Glean API", func=wrapper.run)
|
||||||
|
|
||||||
def run_model(self) -> Union[Data, list[Data]]:
|
def run_model(self) -> Data | list[Data]:
|
||||||
wrapper = self._build_wrapper()
|
wrapper = self._build_wrapper()
|
||||||
|
|
||||||
results = wrapper.results(
|
results = wrapper.results(
|
||||||
|
|
@ -67,7 +67,7 @@ class GleanSearchAPIComponent(LCToolComponent):
|
||||||
self,
|
self,
|
||||||
query: str,
|
query: str,
|
||||||
page_size: int = 10,
|
page_size: int = 10,
|
||||||
request_options: Optional[Dict[str, Any]] = None,
|
request_options: dict[str, Any] | None = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
# Ensure there's a trailing slash
|
# Ensure there's a trailing slash
|
||||||
url = self.glean_api_url
|
url = self.glean_api_url
|
||||||
|
|
@ -97,7 +97,7 @@ class GleanSearchAPIComponent(LCToolComponent):
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def _search_api_results(self, query: str, **kwargs: Any) -> Dict[str, Any]:
|
def _search_api_results(self, query: str, **kwargs: Any) -> dict[str, Any]:
|
||||||
request_details = self._prepare_request(query, **kwargs)
|
request_details = self._prepare_request(query, **kwargs)
|
||||||
|
|
||||||
response = httpx.post(
|
response = httpx.post(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from langchain_core.tools import Tool
|
from langchain_core.tools import Tool
|
||||||
|
|
||||||
from langflow.base.langchain_utilities.model import LCToolComponent
|
from langflow.base.langchain_utilities.model import LCToolComponent
|
||||||
|
|
@ -22,7 +20,7 @@ class GoogleSearchAPIComponent(LCToolComponent):
|
||||||
IntInput(name="k", display_name="Number of results", value=4, required=True),
|
IntInput(name="k", display_name="Number of results", value=4, required=True),
|
||||||
]
|
]
|
||||||
|
|
||||||
def run_model(self) -> Union[Data, list[Data]]:
|
def run_model(self) -> Data | list[Data]:
|
||||||
wrapper = self._build_wrapper()
|
wrapper = self._build_wrapper()
|
||||||
results = wrapper.results(query=self.input_value, num_results=self.k)
|
results = wrapper.results(query=self.input_value, num_results=self.k)
|
||||||
data = [Data(data=result, text=result["snippet"]) for result in results]
|
data = [Data(data=result, text=result["snippet"]) for result in results]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from langchain_community.utilities.google_serper import GoogleSerperAPIWrapper
|
from langchain_community.utilities.google_serper import GoogleSerperAPIWrapper
|
||||||
|
|
||||||
from langflow.base.langchain_utilities.model import LCToolComponent
|
from langflow.base.langchain_utilities.model import LCToolComponent
|
||||||
|
|
@ -22,7 +20,7 @@ class GoogleSerperAPIComponent(LCToolComponent):
|
||||||
IntInput(name="k", display_name="Number of results", value=4, required=True),
|
IntInput(name="k", display_name="Number of results", value=4, required=True),
|
||||||
]
|
]
|
||||||
|
|
||||||
def run_model(self) -> Union[Data, list[Data]]:
|
def run_model(self) -> Data | list[Data]:
|
||||||
wrapper = self._build_wrapper()
|
wrapper = self._build_wrapper()
|
||||||
results = wrapper.results(query=self.input_value)
|
results = wrapper.results(query=self.input_value)
|
||||||
list_results = results.get("organic", [])
|
list_results = results.get("organic", [])
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import importlib
|
import importlib
|
||||||
from typing import List, Union
|
|
||||||
|
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
from langchain_experimental.utilities import PythonREPL
|
from langchain_experimental.utilities import PythonREPL
|
||||||
|
|
@ -46,7 +45,7 @@ class PythonREPLToolComponent(LCToolComponent):
|
||||||
class PythonREPLSchema(BaseModel):
|
class PythonREPLSchema(BaseModel):
|
||||||
code: str = Field(..., description="The Python code to execute.")
|
code: str = Field(..., description="The Python code to execute.")
|
||||||
|
|
||||||
def get_globals(self, global_imports: Union[str, List[str]]) -> dict:
|
def get_globals(self, global_imports: str | list[str]) -> dict:
|
||||||
global_dict = {}
|
global_dict = {}
|
||||||
if isinstance(global_imports, str):
|
if isinstance(global_imports, str):
|
||||||
modules = [module.strip() for module in global_imports.split(",")]
|
modules = [module.strip() for module in global_imports.split(",")]
|
||||||
|
|
@ -83,7 +82,7 @@ class PythonREPLToolComponent(LCToolComponent):
|
||||||
self.status = f"Python REPL Tool created with global imports: {self.global_imports}"
|
self.status = f"Python REPL Tool created with global imports: {self.global_imports}"
|
||||||
return tool
|
return tool
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
tool = self.build_tool()
|
tool = self.build_tool()
|
||||||
result = tool.run(self.code)
|
result = tool.run(self.code)
|
||||||
return [Data(data={"result": result})]
|
return [Data(data={"result": result})]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
from langchain_community.utilities.searchapi import SearchApiAPIWrapper
|
from langchain_community.utilities.searchapi import SearchApiAPIWrapper
|
||||||
|
|
@ -30,7 +30,7 @@ class SearchAPIComponent(LCToolComponent):
|
||||||
|
|
||||||
class SearchAPISchema(BaseModel):
|
class SearchAPISchema(BaseModel):
|
||||||
query: str = Field(..., description="The search query")
|
query: str = Field(..., description="The search query")
|
||||||
params: Optional[Dict[str, Any]] = Field(default_factory=dict, description="Additional search parameters")
|
params: dict[str, Any] | None = Field(default_factory=dict, description="Additional search parameters")
|
||||||
max_results: int = Field(5, description="Maximum number of results to return")
|
max_results: int = Field(5, description="Maximum number of results to return")
|
||||||
max_snippet_length: int = Field(100, description="Maximum length of each result snippet")
|
max_snippet_length: int = Field(100, description="Maximum length of each result snippet")
|
||||||
|
|
||||||
|
|
@ -41,8 +41,8 @@ class SearchAPIComponent(LCToolComponent):
|
||||||
wrapper = self._build_wrapper()
|
wrapper = self._build_wrapper()
|
||||||
|
|
||||||
def search_func(
|
def search_func(
|
||||||
query: str, params: Optional[Dict[str, Any]] = None, max_results: int = 5, max_snippet_length: int = 100
|
query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100
|
||||||
) -> List[Dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
params = params or {}
|
params = params or {}
|
||||||
full_results = wrapper.results(query=query, **params)
|
full_results = wrapper.results(query=query, **params)
|
||||||
organic_results = full_results.get("organic_results", [])[:max_results]
|
organic_results = full_results.get("organic_results", [])[:max_results]
|
||||||
|
|
@ -68,7 +68,7 @@ class SearchAPIComponent(LCToolComponent):
|
||||||
self.status = f"Search API Tool created with engine: {self.engine}"
|
self.status = f"Search API Tool created with engine: {self.engine}"
|
||||||
return tool
|
return tool
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
tool = self.build_tool()
|
tool = self.build_tool()
|
||||||
results = tool.run(
|
results = tool.run(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any
|
||||||
|
|
||||||
from langchain.tools import StructuredTool
|
from langchain.tools import StructuredTool
|
||||||
from langchain_community.utilities.serpapi import SerpAPIWrapper
|
from langchain_community.utilities.serpapi import SerpAPIWrapper
|
||||||
|
|
@ -28,7 +28,7 @@ class SerpAPIComponent(LCToolComponent):
|
||||||
|
|
||||||
class SerpAPISchema(BaseModel):
|
class SerpAPISchema(BaseModel):
|
||||||
query: str = Field(..., description="The search query")
|
query: str = Field(..., description="The search query")
|
||||||
params: Optional[Dict[str, Any]] = Field(default_factory=dict, description="Additional search parameters")
|
params: dict[str, Any] | None = Field(default_factory=dict, description="Additional search parameters")
|
||||||
max_results: int = Field(5, description="Maximum number of results to return")
|
max_results: int = Field(5, description="Maximum number of results to return")
|
||||||
max_snippet_length: int = Field(100, description="Maximum length of each result snippet")
|
max_snippet_length: int = Field(100, description="Maximum length of each result snippet")
|
||||||
|
|
||||||
|
|
@ -44,8 +44,8 @@ class SerpAPIComponent(LCToolComponent):
|
||||||
wrapper = self._build_wrapper()
|
wrapper = self._build_wrapper()
|
||||||
|
|
||||||
def search_func(
|
def search_func(
|
||||||
query: str, params: Optional[Dict[str, Any]] = None, max_results: int = 5, max_snippet_length: int = 100
|
query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100
|
||||||
) -> List[Dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
params = params or {}
|
params = params or {}
|
||||||
full_results = wrapper.results(query, **params)
|
full_results = wrapper.results(query, **params)
|
||||||
organic_results = full_results.get("organic_results", [])[:max_results]
|
organic_results = full_results.get("organic_results", [])[:max_results]
|
||||||
|
|
@ -71,7 +71,7 @@ class SerpAPIComponent(LCToolComponent):
|
||||||
self.status = "SerpAPI Tool created"
|
self.status = "SerpAPI Tool created"
|
||||||
return tool
|
return tool
|
||||||
|
|
||||||
def run_model(self) -> List[Data]:
|
def run_model(self) -> list[Data]:
|
||||||
tool = self.build_tool()
|
tool = self.build_tool()
|
||||||
try:
|
try:
|
||||||
results = tool.run(
|
results = tool.run(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.vectorstores import Cassandra
|
from langchain_community.vectorstores import Cassandra
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
|
@ -219,7 +217,7 @@ class CassandraVectorStoreComponent(LCVectorStoreComponent):
|
||||||
else:
|
else:
|
||||||
return "similarity"
|
return "similarity"
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
logger.debug(f"Search input: {self.search_query}")
|
logger.debug(f"Search input: {self.search_query}")
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
from typing import List
|
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from langchain_community.graph_vectorstores import CassandraGraphVectorStore
|
from langchain_community.graph_vectorstores import CassandraGraphVectorStore
|
||||||
|
|
@ -197,7 +196,7 @@ class CassandraGraphVectorStoreComponent(LCVectorStoreComponent):
|
||||||
else:
|
else:
|
||||||
return "traversal"
|
return "traversal"
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
logger.debug(f"Search input: {self.search_query}")
|
logger.debug(f"Search input: {self.search_query}")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.vectorstores import Clickhouse, ClickhouseSettings
|
from langchain_community.vectorstores import Clickhouse, ClickhouseSettings
|
||||||
|
|
||||||
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
||||||
|
|
@ -117,7 +115,7 @@ class ClickhouseVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return clickhouse_vs
|
return clickhouse_vs
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.vectorstores import CouchbaseVectorStore
|
from langchain_community.vectorstores import CouchbaseVectorStore
|
||||||
|
|
||||||
|
|
@ -92,7 +91,7 @@ class CouchbaseVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return couchbase_vs
|
return couchbase_vs
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.vectorstores import FAISS
|
from langchain_community.vectorstores import FAISS
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
|
@ -79,7 +77,7 @@ class FaissVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return faiss
|
return faiss
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
"""
|
"""
|
||||||
Search for documents in the FAISS vector store.
|
Search for documents in the FAISS vector store.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
||||||
from langflow.helpers.data import docs_to_data
|
from langflow.helpers.data import docs_to_data
|
||||||
from langflow.io import (
|
from langflow.io import (
|
||||||
|
|
@ -108,7 +106,7 @@ class MilvusVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return milvus_store
|
return milvus_store
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.vectorstores import MongoDBAtlasVectorSearch
|
from langchain_community.vectorstores import MongoDBAtlasVectorSearch
|
||||||
|
|
||||||
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
||||||
|
|
@ -75,7 +73,7 @@ class MongoVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return vector_store
|
return vector_store
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
|
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_pinecone import Pinecone
|
from langchain_pinecone import Pinecone
|
||||||
|
|
||||||
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
||||||
|
|
@ -85,7 +83,7 @@ class PineconeVectorStoreComponent(LCVectorStoreComponent):
|
||||||
pinecone.add_documents(documents)
|
pinecone.add_documents(documents)
|
||||||
return pinecone
|
return pinecone
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain.embeddings.base import Embeddings
|
from langchain.embeddings.base import Embeddings
|
||||||
from langchain_community.vectorstores import Qdrant
|
from langchain_community.vectorstores import Qdrant
|
||||||
|
|
||||||
|
|
@ -99,7 +97,7 @@ class QdrantVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return qdrant
|
return qdrant
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain.text_splitter import CharacterTextSplitter
|
from langchain.text_splitter import CharacterTextSplitter
|
||||||
from langchain_community.vectorstores.redis import Redis
|
from langchain_community.vectorstores.redis import Redis
|
||||||
|
|
||||||
|
|
@ -79,7 +77,7 @@ class RedisVectorStoreComponent(LCVectorStoreComponent):
|
||||||
)
|
)
|
||||||
return redis_vs
|
return redis_vs
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.vectorstores import SupabaseVectorStore
|
from langchain_community.vectorstores import SupabaseVectorStore
|
||||||
from supabase.client import Client, create_client
|
from supabase.client import Client, create_client
|
||||||
|
|
||||||
|
|
@ -66,7 +64,7 @@ class SupabaseVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return supabase_vs
|
return supabase_vs
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.vectorstores import UpstashVectorStore
|
from langchain_community.vectorstores import UpstashVectorStore
|
||||||
|
|
||||||
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
||||||
|
|
@ -114,7 +112,7 @@ class UpstashVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return upstash_vs
|
return upstash_vs
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import TYPE_CHECKING, List
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from langchain_community.vectorstores import Vectara
|
from langchain_community.vectorstores import Vectara
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
@ -93,7 +93,7 @@ class VectaraVectorStoreComponent(LCVectorStoreComponent):
|
||||||
logger.debug("No documents to add to Vectara.")
|
logger.debug("No documents to add to Vectara.")
|
||||||
self.status = "No valid documents to add to Vectara"
|
self.status = "No valid documents to add to Vectara"
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
import weaviate # type: ignore
|
import weaviate # type: ignore
|
||||||
from langchain_community.vectorstores import Weaviate
|
from langchain_community.vectorstores import Weaviate
|
||||||
|
|
||||||
|
|
@ -70,7 +68,7 @@ class WeaviateVectorStoreComponent(LCVectorStoreComponent):
|
||||||
by_text=self.search_by_text,
|
by_text=self.search_by_text,
|
||||||
)
|
)
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from langchain_community.vectorstores import PGVector
|
from langchain_community.vectorstores import PGVector
|
||||||
|
|
||||||
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
||||||
|
|
@ -63,7 +61,7 @@ class PGVectorStoreComponent(LCVectorStoreComponent):
|
||||||
|
|
||||||
return pgvector
|
return pgvector
|
||||||
|
|
||||||
def search_documents(self) -> List[Data]:
|
def search_documents(self) -> list[Data]:
|
||||||
vector_store = self.build_vector_store()
|
vector_store = self.build_vector_store()
|
||||||
|
|
||||||
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
if self.search_query and isinstance(self.search_query, str) and self.search_query.strip():
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ def find_class_ast_node(class_obj):
|
||||||
for node in ast.walk(tree):
|
for node in ast.walk(tree):
|
||||||
if isinstance(node, ast.ClassDef) and node.name == class_obj.__name__:
|
if isinstance(node, ast.ClassDef) and node.name == class_obj.__name__:
|
||||||
class_node = node
|
class_node = node
|
||||||
elif isinstance(node, (ast.Import, ast.ImportFrom)):
|
elif isinstance(node, ast.Import | ast.ImportFrom):
|
||||||
import_nodes.append(node)
|
import_nodes.append(node)
|
||||||
|
|
||||||
return class_node, import_nodes
|
return class_node, import_nodes
|
||||||
|
|
@ -275,7 +275,7 @@ class CodeParser:
|
||||||
or any(has_return(child) for child in node.handlers)
|
or any(has_return(child) for child in node.handlers)
|
||||||
or any(has_return(child) for child in node.finalbody)
|
or any(has_return(child) for child in node.finalbody)
|
||||||
)
|
)
|
||||||
elif isinstance(node, (ast.For, ast.While)):
|
elif isinstance(node, ast.For | ast.While):
|
||||||
return any(has_return(child) for child in node.body) or any(has_return(child) for child in node.orelse)
|
return any(has_return(child) for child in node.body) or any(has_return(child) for child in node.orelse)
|
||||||
elif isinstance(node, ast.With):
|
elif isinstance(node, ast.With):
|
||||||
return any(has_return(child) for child in node.body)
|
return any(has_return(child) for child in node.body)
|
||||||
|
|
@ -365,7 +365,7 @@ class CodeParser:
|
||||||
elif isinstance(stmt, ast.AnnAssign):
|
elif isinstance(stmt, ast.AnnAssign):
|
||||||
if attr := self.parse_ann_assign(stmt):
|
if attr := self.parse_ann_assign(stmt):
|
||||||
class_details.attributes.append(attr)
|
class_details.attributes.append(attr)
|
||||||
elif isinstance(stmt, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
elif isinstance(stmt, ast.FunctionDef | ast.AsyncFunctionDef):
|
||||||
method, is_init = self.parse_function_def(stmt)
|
method, is_init = self.parse_function_def(stmt)
|
||||||
if is_init:
|
if is_init:
|
||||||
class_details.init = method
|
class_details.init = method
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
@ -33,7 +35,7 @@ CONFIG_ATTRIBUTES = ["_display_name", "_description", "_icon", "_name"]
|
||||||
|
|
||||||
|
|
||||||
class Component(CustomComponent):
|
class Component(CustomComponent):
|
||||||
inputs: list["InputTypes"] = []
|
inputs: list[InputTypes] = []
|
||||||
outputs: list[Output] = []
|
outputs: list[Output] = []
|
||||||
code_class_base_inheritance: ClassVar[str] = "Component"
|
code_class_base_inheritance: ClassVar[str] = "Component"
|
||||||
_output_logs: dict[str, Log] = {}
|
_output_logs: dict[str, Log] = {}
|
||||||
|
|
@ -51,7 +53,7 @@ class Component(CustomComponent):
|
||||||
config[key[1:]] = value
|
config[key[1:]] = value
|
||||||
else:
|
else:
|
||||||
inputs[key] = value
|
inputs[key] = value
|
||||||
self._inputs: dict[str, "InputTypes"] = {}
|
self._inputs: dict[str, InputTypes] = {}
|
||||||
self._outputs_map: dict[str, Output] = {}
|
self._outputs_map: dict[str, Output] = {}
|
||||||
self._results: dict[str, Any] = {}
|
self._results: dict[str, Any] = {}
|
||||||
self._attributes: dict[str, Any] = {}
|
self._attributes: dict[str, Any] = {}
|
||||||
|
|
@ -179,7 +181,7 @@ class Component(CustomComponent):
|
||||||
"""
|
"""
|
||||||
return await self._run()
|
return await self._run()
|
||||||
|
|
||||||
def set_vertex(self, vertex: "Vertex"):
|
def set_vertex(self, vertex: Vertex):
|
||||||
"""
|
"""
|
||||||
Sets the vertex for the component.
|
Sets the vertex for the component.
|
||||||
|
|
||||||
|
|
@ -258,7 +260,7 @@ class Component(CustomComponent):
|
||||||
# allows each instance of each component to modify its own output
|
# allows each instance of each component to modify its own output
|
||||||
self._outputs_map[output.name] = deepcopy(output)
|
self._outputs_map[output.name] = deepcopy(output)
|
||||||
|
|
||||||
def map_inputs(self, inputs: list["InputTypes"]):
|
def map_inputs(self, inputs: list[InputTypes]):
|
||||||
"""
|
"""
|
||||||
Maps the given inputs to the component.
|
Maps the given inputs to the component.
|
||||||
|
|
||||||
|
|
@ -325,7 +327,7 @@ class Component(CustomComponent):
|
||||||
text += f"{output.name}[{','.join(output.types)}]->{input_.name}[{','.join(input_.input_types or [])}]\n"
|
text += f"{output.name}[{','.join(output.types)}]->{input_.name}[{','.join(input_.input_types or [])}]\n"
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def _find_matching_output_method(self, value: "Component"):
|
def _find_matching_output_method(self, value: Component):
|
||||||
# get all outputs of the value component
|
# get all outputs of the value component
|
||||||
outputs = value._outputs_map.values()
|
outputs = value._outputs_map.values()
|
||||||
# check if the any of the types in the output.types matches ONLY one input in the current component
|
# check if the any of the types in the output.types matches ONLY one input in the current component
|
||||||
|
|
@ -652,7 +654,7 @@ class Component(CustomComponent):
|
||||||
output.value = result
|
output.value = result
|
||||||
|
|
||||||
custom_repr = self.custom_repr()
|
custom_repr = self.custom_repr()
|
||||||
if custom_repr is None and isinstance(result, (dict, Data, str)):
|
if custom_repr is None and isinstance(result, dict | Data | str):
|
||||||
custom_repr = result
|
custom_repr = result
|
||||||
if not isinstance(custom_repr, str):
|
if not isinstance(custom_repr, str):
|
||||||
custom_repr = str(custom_repr)
|
custom_repr = str(custom_repr)
|
||||||
|
|
@ -670,7 +672,7 @@ class Component(CustomComponent):
|
||||||
|
|
||||||
elif hasattr(raw, "model_dump") and raw is not None:
|
elif hasattr(raw, "model_dump") and raw is not None:
|
||||||
raw = raw.model_dump()
|
raw = raw.model_dump()
|
||||||
if raw is None and isinstance(result, (dict, Data, str)):
|
if raw is None and isinstance(result, dict | Data | str):
|
||||||
raw = result.data if isinstance(result, Data) else result
|
raw = result.data if isinstance(result, Data) else result
|
||||||
artifact_type = get_artifact_type(artifact_value, result)
|
artifact_type = get_artifact_type(artifact_value, result)
|
||||||
raw, artifact_type = post_process_raw(raw, artifact_type)
|
raw, artifact_type = post_process_raw(raw, artifact_type)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable, Sequence
|
from collections.abc import Callable, Sequence
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Any, ClassVar, Optional
|
from typing import TYPE_CHECKING, Any, ClassVar
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
from cachetools import TTLCache
|
from cachetools import TTLCache
|
||||||
|
|
@ -69,7 +71,7 @@ class CustomComponent(BaseComponent):
|
||||||
"""The default frozen state of the component. Defaults to False."""
|
"""The default frozen state of the component. Defaults to False."""
|
||||||
build_parameters: dict | None = None
|
build_parameters: dict | None = None
|
||||||
"""The build parameters of the component. Defaults to None."""
|
"""The build parameters of the component. Defaults to None."""
|
||||||
_vertex: Optional["Vertex"] = None
|
_vertex: Vertex | None = None
|
||||||
"""The edge target parameter of the component. Defaults to None."""
|
"""The edge target parameter of the component. Defaults to None."""
|
||||||
_code_class_base_inheritance: ClassVar[str] = "CustomComponent"
|
_code_class_base_inheritance: ClassVar[str] = "CustomComponent"
|
||||||
function_entrypoint_name: ClassVar[str] = "build"
|
function_entrypoint_name: ClassVar[str] = "build"
|
||||||
|
|
@ -81,7 +83,7 @@ class CustomComponent(BaseComponent):
|
||||||
_outputs: list[OutputValue] = []
|
_outputs: list[OutputValue] = []
|
||||||
_logs: list[Log] = []
|
_logs: list[Log] = []
|
||||||
_output_logs: dict[str, Log] = {}
|
_output_logs: dict[str, Log] = {}
|
||||||
_tracing_service: Optional["TracingService"] = None
|
_tracing_service: TracingService | None = None
|
||||||
_tree: dict | None = None
|
_tree: dict | None = None
|
||||||
|
|
||||||
def __init__(self, **data):
|
def __init__(self, **data):
|
||||||
|
|
@ -158,7 +160,7 @@ class CustomComponent(BaseComponent):
|
||||||
return str(path_object)
|
return str(path_object)
|
||||||
|
|
||||||
def get_full_path(self, path: str) -> str:
|
def get_full_path(self, path: str) -> str:
|
||||||
storage_svc: "StorageService" = get_storage_service()
|
storage_svc: StorageService = get_storage_service()
|
||||||
|
|
||||||
flow_id, file_name = path.split("/", 1)
|
flow_id, file_name = path.split("/", 1)
|
||||||
return storage_svc.build_full_path(flow_id, file_name)
|
return storage_svc.build_full_path(flow_id, file_name)
|
||||||
|
|
@ -464,7 +466,7 @@ class CustomComponent(BaseComponent):
|
||||||
"""
|
"""
|
||||||
return validate.create_function(self._code, self._function_entrypoint_name)
|
return validate.create_function(self._code, self._function_entrypoint_name)
|
||||||
|
|
||||||
async def load_flow(self, flow_id: str, tweaks: dict | None = None) -> "Graph":
|
async def load_flow(self, flow_id: str, tweaks: dict | None = None) -> Graph:
|
||||||
if not self.user_id:
|
if not self.user_id:
|
||||||
raise ValueError("Session is invalid")
|
raise ValueError("Session is invalid")
|
||||||
return await load_flow(user_id=str(self._user_id), flow_id=flow_id, tweaks=tweaks)
|
return await load_flow(user_id=str(self._user_id), flow_id=flow_id, tweaks=tweaks)
|
||||||
|
|
@ -517,7 +519,7 @@ class CustomComponent(BaseComponent):
|
||||||
)
|
)
|
||||||
return frontend_node
|
return frontend_node
|
||||||
|
|
||||||
def get_langchain_callbacks(self) -> list["BaseCallbackHandler"]:
|
def get_langchain_callbacks(self) -> list[BaseCallbackHandler]:
|
||||||
if self._tracing_service:
|
if self._tracing_service:
|
||||||
return self._tracing_service.get_langchain_callbacks()
|
return self._tracing_service.get_langchain_callbacks()
|
||||||
return []
|
return []
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from typing import Callable, Dict, Text, TypeAlias, TypeVar, Union
|
from collections.abc import Callable
|
||||||
|
from typing import Text, TypeAlias, TypeVar
|
||||||
|
|
||||||
from langchain.agents.agent import AgentExecutor
|
from langchain.agents.agent import AgentExecutor
|
||||||
from langchain.chains.base import Chain
|
from langchain.chains.base import Chain
|
||||||
|
|
@ -20,7 +21,7 @@ from langchain_text_splitters import TextSplitter
|
||||||
from langflow.schema.data import Data
|
from langflow.schema.data import Data
|
||||||
from langflow.schema.message import Message
|
from langflow.schema.message import Message
|
||||||
|
|
||||||
NestedDict: TypeAlias = Dict[str, Union[str, Dict]]
|
NestedDict: TypeAlias = dict[str, str | dict]
|
||||||
LanguageModel = TypeVar("LanguageModel", BaseLanguageModel, BaseLLM, BaseChatModel)
|
LanguageModel = TypeVar("LanguageModel", BaseLanguageModel, BaseLLM, BaseChatModel)
|
||||||
ToolEnabledLanguageModel = TypeVar("ToolEnabledLanguageModel", BaseLanguageModel, BaseLLM, BaseChatModel)
|
ToolEnabledLanguageModel = TypeVar("ToolEnabledLanguageModel", BaseLanguageModel, BaseLLM, BaseChatModel)
|
||||||
Retriever = TypeVar(
|
Retriever = TypeVar(
|
||||||
|
|
@ -66,7 +67,7 @@ CUSTOM_COMPONENT_SUPPORTED_TYPES = {
|
||||||
"NestedDict": NestedDict,
|
"NestedDict": NestedDict,
|
||||||
"Data": Data,
|
"Data": Data,
|
||||||
"Message": Message,
|
"Message": Message,
|
||||||
"Text": Text,
|
"Text": Text, # noqa: UP019
|
||||||
"Object": Object,
|
"Object": Object,
|
||||||
"Callable": Callable,
|
"Callable": Callable,
|
||||||
"LanguageModel": LanguageModel,
|
"LanguageModel": LanguageModel,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
|
@ -8,7 +10,7 @@ from collections.abc import Generator, Iterable
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import TYPE_CHECKING, Any, Optional, cast
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
|
|
||||||
import nest_asyncio
|
import nest_asyncio
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
@ -53,8 +55,8 @@ class Graph:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
start: Optional["Component"] = None,
|
start: Component | None = None,
|
||||||
end: Optional["Component"] = None,
|
end: Component | None = None,
|
||||||
flow_id: str | None = None,
|
flow_id: str | None = None,
|
||||||
flow_name: str | None = None,
|
flow_name: str | None = None,
|
||||||
description: str | None = None,
|
description: str | None = None,
|
||||||
|
|
@ -115,7 +117,7 @@ class Graph:
|
||||||
self._call_order: list[str] = []
|
self._call_order: list[str] = []
|
||||||
self._snapshots: list[dict[str, Any]] = []
|
self._snapshots: list[dict[str, Any]] = []
|
||||||
try:
|
try:
|
||||||
self.tracing_service: "TracingService" | None = get_tracing_service()
|
self.tracing_service: TracingService | None = get_tracing_service()
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(f"Error getting tracing service: {exc}")
|
logger.error(f"Error getting tracing service: {exc}")
|
||||||
self.tracing_service = None
|
self.tracing_service = None
|
||||||
|
|
@ -203,7 +205,7 @@ class Graph:
|
||||||
self._edges = self._graph_data["edges"]
|
self._edges = self._graph_data["edges"]
|
||||||
self.initialize()
|
self.initialize()
|
||||||
|
|
||||||
def add_component(self, component: "Component", component_id: Optional[str] = None) -> str:
|
def add_component(self, component: Component, component_id: str | None = None) -> str:
|
||||||
component_id = component_id or component._id
|
component_id = component_id or component._id
|
||||||
if component_id in self.vertex_map:
|
if component_id in self.vertex_map:
|
||||||
return component_id
|
return component_id
|
||||||
|
|
@ -225,7 +227,7 @@ class Graph:
|
||||||
|
|
||||||
return component_id
|
return component_id
|
||||||
|
|
||||||
def _set_start_and_end(self, start: "Component", end: "Component"):
|
def _set_start_and_end(self, start: Component, end: Component):
|
||||||
if not hasattr(start, "to_frontend_node"):
|
if not hasattr(start, "to_frontend_node"):
|
||||||
raise TypeError(f"start must be a Component. Got {type(start)}")
|
raise TypeError(f"start must be a Component. Got {type(start)}")
|
||||||
if not hasattr(end, "to_frontend_node"):
|
if not hasattr(end, "to_frontend_node"):
|
||||||
|
|
@ -613,7 +615,7 @@ class Graph:
|
||||||
stream: bool,
|
stream: bool,
|
||||||
session_id: str,
|
session_id: str,
|
||||||
fallback_to_env_vars: bool,
|
fallback_to_env_vars: bool,
|
||||||
) -> list[Optional["ResultData"]]:
|
) -> list[ResultData | None]:
|
||||||
"""
|
"""
|
||||||
Runs the graph with the given inputs.
|
Runs the graph with the given inputs.
|
||||||
|
|
||||||
|
|
@ -808,7 +810,7 @@ class Graph:
|
||||||
"flow_name": self.flow_name,
|
"flow_name": self.flow_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
def build_graph_maps(self, edges: list[CycleEdge] | None = None, vertices: list["Vertex"] | None = None):
|
def build_graph_maps(self, edges: list[CycleEdge] | None = None, vertices: list[Vertex] | None = None):
|
||||||
"""
|
"""
|
||||||
Builds the adjacency maps for the graph.
|
Builds the adjacency maps for the graph.
|
||||||
"""
|
"""
|
||||||
|
|
@ -878,7 +880,7 @@ class Graph:
|
||||||
return edge
|
return edge
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def build_parent_child_map(self, vertices: list["Vertex"]):
|
def build_parent_child_map(self, vertices: list[Vertex]):
|
||||||
parent_child_map = defaultdict(list)
|
parent_child_map = defaultdict(list)
|
||||||
for vertex in vertices:
|
for vertex in vertices:
|
||||||
parent_child_map[vertex.id] = [child.id for child in self.get_successors(vertex)]
|
parent_child_map[vertex.id] = [child.id for child in self.get_successors(vertex)]
|
||||||
|
|
@ -977,7 +979,7 @@ class Graph:
|
||||||
flow_id: str | None = None,
|
flow_id: str | None = None,
|
||||||
flow_name: str | None = None,
|
flow_name: str | None = None,
|
||||||
user_id: str | None = None,
|
user_id: str | None = None,
|
||||||
) -> "Graph":
|
) -> Graph:
|
||||||
"""
|
"""
|
||||||
Creates a graph from a payload.
|
Creates a graph from a payload.
|
||||||
|
|
||||||
|
|
@ -1016,7 +1018,7 @@ class Graph:
|
||||||
# both graphs have the same vertices and edges
|
# both graphs have the same vertices and edges
|
||||||
# but the data of the vertices might be different
|
# but the data of the vertices might be different
|
||||||
|
|
||||||
def update_edges_from_vertex(self, vertex: "Vertex", other_vertex: "Vertex") -> None:
|
def update_edges_from_vertex(self, vertex: Vertex, other_vertex: Vertex) -> None:
|
||||||
"""Updates the edges of a vertex in the Graph."""
|
"""Updates the edges of a vertex in the Graph."""
|
||||||
new_edges = []
|
new_edges = []
|
||||||
for edge in self.edges:
|
for edge in self.edges:
|
||||||
|
|
@ -1026,13 +1028,13 @@ class Graph:
|
||||||
new_edges += other_vertex.edges
|
new_edges += other_vertex.edges
|
||||||
self.edges = new_edges
|
self.edges = new_edges
|
||||||
|
|
||||||
def vertex_data_is_identical(self, vertex: "Vertex", other_vertex: "Vertex") -> bool:
|
def vertex_data_is_identical(self, vertex: Vertex, other_vertex: Vertex) -> bool:
|
||||||
data_is_equivalent = vertex == other_vertex
|
data_is_equivalent = vertex == other_vertex
|
||||||
if not data_is_equivalent:
|
if not data_is_equivalent:
|
||||||
return False
|
return False
|
||||||
return self.vertex_edges_are_identical(vertex, other_vertex)
|
return self.vertex_edges_are_identical(vertex, other_vertex)
|
||||||
|
|
||||||
def vertex_edges_are_identical(self, vertex: "Vertex", other_vertex: "Vertex") -> bool:
|
def vertex_edges_are_identical(self, vertex: Vertex, other_vertex: Vertex) -> bool:
|
||||||
same_length = len(vertex.edges) == len(other_vertex.edges)
|
same_length = len(vertex.edges) == len(other_vertex.edges)
|
||||||
if not same_length:
|
if not same_length:
|
||||||
return False
|
return False
|
||||||
|
|
@ -1041,7 +1043,7 @@ class Graph:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update(self, other: "Graph") -> "Graph":
|
def update(self, other: Graph) -> Graph:
|
||||||
# Existing vertices in self graph
|
# Existing vertices in self graph
|
||||||
existing_vertex_ids = {vertex.id for vertex in self.vertices}
|
existing_vertex_ids = {vertex.id for vertex in self.vertices}
|
||||||
# Vertex IDs in the other graph
|
# Vertex IDs in the other graph
|
||||||
|
|
@ -1091,7 +1093,7 @@ class Graph:
|
||||||
self.increment_update_count()
|
self.increment_update_count()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def update_vertex_from_another(self, vertex: "Vertex", other_vertex: "Vertex") -> None:
|
def update_vertex_from_another(self, vertex: Vertex, other_vertex: Vertex) -> None:
|
||||||
"""
|
"""
|
||||||
Updates a vertex from another vertex.
|
Updates a vertex from another vertex.
|
||||||
|
|
||||||
|
|
@ -1129,12 +1131,12 @@ class Graph:
|
||||||
self.vertices.append(vertex)
|
self.vertices.append(vertex)
|
||||||
self.vertex_map[vertex.id] = vertex
|
self.vertex_map[vertex.id] = vertex
|
||||||
|
|
||||||
def add_vertex(self, vertex: "Vertex") -> None:
|
def add_vertex(self, vertex: Vertex) -> None:
|
||||||
"""Adds a new vertex to the graph."""
|
"""Adds a new vertex to the graph."""
|
||||||
self._add_vertex(vertex)
|
self._add_vertex(vertex)
|
||||||
self._update_edges(vertex)
|
self._update_edges(vertex)
|
||||||
|
|
||||||
def _update_edges(self, vertex: "Vertex") -> None:
|
def _update_edges(self, vertex: Vertex) -> None:
|
||||||
"""Updates the edges of a vertex."""
|
"""Updates the edges of a vertex."""
|
||||||
# Vertex has edges, so we need to update the edges
|
# Vertex has edges, so we need to update the edges
|
||||||
for edge in vertex.edges:
|
for edge in vertex.edges:
|
||||||
|
|
@ -1169,19 +1171,19 @@ class Graph:
|
||||||
for vertex in self.vertices:
|
for vertex in self.vertices:
|
||||||
vertex._build_params()
|
vertex._build_params()
|
||||||
|
|
||||||
def _validate_vertex(self, vertex: "Vertex") -> bool:
|
def _validate_vertex(self, vertex: Vertex) -> bool:
|
||||||
"""Validates a vertex."""
|
"""Validates a vertex."""
|
||||||
# All vertices that do not have edges are invalid
|
# All vertices that do not have edges are invalid
|
||||||
return len(self.get_vertex_edges(vertex.id)) > 0
|
return len(self.get_vertex_edges(vertex.id)) > 0
|
||||||
|
|
||||||
def get_vertex(self, vertex_id: str, silent: bool = False) -> "Vertex":
|
def get_vertex(self, vertex_id: str, silent: bool = False) -> Vertex:
|
||||||
"""Returns a vertex by id."""
|
"""Returns a vertex by id."""
|
||||||
try:
|
try:
|
||||||
return self.vertex_map[vertex_id]
|
return self.vertex_map[vertex_id]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise ValueError(f"Vertex {vertex_id} not found")
|
raise ValueError(f"Vertex {vertex_id} not found")
|
||||||
|
|
||||||
def get_root_of_group_node(self, vertex_id: str) -> "Vertex":
|
def get_root_of_group_node(self, vertex_id: str) -> Vertex:
|
||||||
"""Returns the root of a group node."""
|
"""Returns the root of a group node."""
|
||||||
if vertex_id in self.top_level_vertices:
|
if vertex_id in self.top_level_vertices:
|
||||||
# Get all vertices with vertex_id as .parent_node_id
|
# Get all vertices with vertex_id as .parent_node_id
|
||||||
|
|
@ -1205,7 +1207,7 @@ class Graph:
|
||||||
|
|
||||||
async def astep(
|
async def astep(
|
||||||
self,
|
self,
|
||||||
inputs: Optional["InputValueRequest"] = None,
|
inputs: InputValueRequest | None = None,
|
||||||
files: list[str] | None = None,
|
files: list[str] | None = None,
|
||||||
user_id: str | None = None,
|
user_id: str | None = None,
|
||||||
event_manager: EventManager | None = None,
|
event_manager: EventManager | None = None,
|
||||||
|
|
@ -1259,7 +1261,7 @@ class Graph:
|
||||||
|
|
||||||
def step(
|
def step(
|
||||||
self,
|
self,
|
||||||
inputs: Optional["InputValueRequest"] = None,
|
inputs: InputValueRequest | None = None,
|
||||||
files: list[str] | None = None,
|
files: list[str] | None = None,
|
||||||
user_id: str | None = None,
|
user_id: str | None = None,
|
||||||
):
|
):
|
||||||
|
|
@ -1382,9 +1384,9 @@ class Graph:
|
||||||
or (edge.target_id == vertex_id and is_target is not False)
|
or (edge.target_id == vertex_id and is_target is not False)
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_vertices_with_target(self, vertex_id: str) -> list["Vertex"]:
|
def get_vertices_with_target(self, vertex_id: str) -> list[Vertex]:
|
||||||
"""Returns the vertices connected to a vertex."""
|
"""Returns the vertices connected to a vertex."""
|
||||||
vertices: list["Vertex"] = []
|
vertices: list[Vertex] = []
|
||||||
for edge in self.edges:
|
for edge in self.edges:
|
||||||
if edge.target_id == vertex_id:
|
if edge.target_id == vertex_id:
|
||||||
vertex = self.get_vertex(edge.source_id)
|
vertex = self.get_vertex(edge.source_id)
|
||||||
|
|
@ -1393,7 +1395,7 @@ class Graph:
|
||||||
vertices.append(vertex)
|
vertices.append(vertex)
|
||||||
return vertices
|
return vertices
|
||||||
|
|
||||||
async def process(self, fallback_to_env_vars: bool, start_component_id: str | None = None) -> "Graph":
|
async def process(self, fallback_to_env_vars: bool, start_component_id: str | None = None) -> Graph:
|
||||||
"""Processes the graph with vertices in each layer run in parallel."""
|
"""Processes the graph with vertices in each layer run in parallel."""
|
||||||
|
|
||||||
first_layer = self.sort_vertices(start_component_id=start_component_id)
|
first_layer = self.sort_vertices(start_component_id=start_component_id)
|
||||||
|
|
@ -1450,7 +1452,7 @@ class Graph:
|
||||||
|
|
||||||
return list(next_runnable_vertices)
|
return list(next_runnable_vertices)
|
||||||
|
|
||||||
async def get_next_runnable_vertices(self, lock: asyncio.Lock, vertex: "Vertex", cache: bool = True) -> list[str]:
|
async def get_next_runnable_vertices(self, lock: asyncio.Lock, vertex: Vertex, cache: bool = True) -> list[str]:
|
||||||
v_id = vertex.id
|
v_id = vertex.id
|
||||||
v_successors_ids = vertex.successors_ids
|
v_successors_ids = vertex.successors_ids
|
||||||
async with lock:
|
async with lock:
|
||||||
|
|
@ -1471,7 +1473,7 @@ class Graph:
|
||||||
"""Executes tasks in parallel, handling exceptions for each task."""
|
"""Executes tasks in parallel, handling exceptions for each task."""
|
||||||
results = []
|
results = []
|
||||||
completed_tasks = await asyncio.gather(*tasks, return_exceptions=True)
|
completed_tasks = await asyncio.gather(*tasks, return_exceptions=True)
|
||||||
vertices: list["Vertex"] = []
|
vertices: list[Vertex] = []
|
||||||
|
|
||||||
for i, result in enumerate(completed_tasks):
|
for i, result in enumerate(completed_tasks):
|
||||||
task_name = tasks[i].get_name()
|
task_name = tasks[i].get_name()
|
||||||
|
|
@ -1500,7 +1502,7 @@ class Graph:
|
||||||
no_duplicate_results = list(set(results))
|
no_duplicate_results = list(set(results))
|
||||||
return no_duplicate_results
|
return no_duplicate_results
|
||||||
|
|
||||||
def topological_sort(self) -> list["Vertex"]:
|
def topological_sort(self) -> list[Vertex]:
|
||||||
"""
|
"""
|
||||||
Performs a topological sort of the vertices in the graph.
|
Performs a topological sort of the vertices in the graph.
|
||||||
|
|
||||||
|
|
@ -1533,7 +1535,7 @@ class Graph:
|
||||||
|
|
||||||
return list(reversed(sorted_vertices))
|
return list(reversed(sorted_vertices))
|
||||||
|
|
||||||
def generator_build(self) -> Generator["Vertex", None, None]:
|
def generator_build(self) -> Generator[Vertex, None, None]:
|
||||||
"""Builds each vertex in the graph and yields it."""
|
"""Builds each vertex in the graph and yields it."""
|
||||||
sorted_vertices = self.topological_sort()
|
sorted_vertices = self.topological_sort()
|
||||||
logger.debug("There are %s vertices in the graph", len(sorted_vertices))
|
logger.debug("There are %s vertices in the graph", len(sorted_vertices))
|
||||||
|
|
@ -1543,7 +1545,7 @@ class Graph:
|
||||||
"""Returns the predecessors of a vertex."""
|
"""Returns the predecessors of a vertex."""
|
||||||
return [self.get_vertex(source_id) for source_id in self.predecessor_map.get(vertex.id, [])]
|
return [self.get_vertex(source_id) for source_id in self.predecessor_map.get(vertex.id, [])]
|
||||||
|
|
||||||
def get_all_successors(self, vertex: "Vertex", recursive=True, flat=True, visited=None):
|
def get_all_successors(self, vertex: Vertex, recursive=True, flat=True, visited=None):
|
||||||
if visited is None:
|
if visited is None:
|
||||||
visited = set()
|
visited = set()
|
||||||
|
|
||||||
|
|
@ -1576,13 +1578,13 @@ class Graph:
|
||||||
|
|
||||||
return successors_result
|
return successors_result
|
||||||
|
|
||||||
def get_successors(self, vertex: "Vertex") -> list["Vertex"]:
|
def get_successors(self, vertex: Vertex) -> list[Vertex]:
|
||||||
"""Returns the successors of a vertex."""
|
"""Returns the successors of a vertex."""
|
||||||
return [self.get_vertex(target_id) for target_id in self.successor_map.get(vertex.id, [])]
|
return [self.get_vertex(target_id) for target_id in self.successor_map.get(vertex.id, [])]
|
||||||
|
|
||||||
def get_vertex_neighbors(self, vertex: "Vertex") -> dict["Vertex", int]:
|
def get_vertex_neighbors(self, vertex: Vertex) -> dict[Vertex, int]:
|
||||||
"""Returns the neighbors of a vertex."""
|
"""Returns the neighbors of a vertex."""
|
||||||
neighbors: dict["Vertex", int] = {}
|
neighbors: dict[Vertex, int] = {}
|
||||||
for edge in self.edges:
|
for edge in self.edges:
|
||||||
if edge.source_id == vertex.id:
|
if edge.source_id == vertex.id:
|
||||||
neighbor = self.get_vertex(edge.target_id)
|
neighbor = self.get_vertex(edge.target_id)
|
||||||
|
|
@ -1638,7 +1640,7 @@ class Graph:
|
||||||
new_edge = Edge(source, target, edge)
|
new_edge = Edge(source, target, edge)
|
||||||
return new_edge
|
return new_edge
|
||||||
|
|
||||||
def _get_vertex_class(self, node_type: str, node_base_type: str, node_id: str) -> type["Vertex"]:
|
def _get_vertex_class(self, node_type: str, node_base_type: str, node_id: str) -> type[Vertex]:
|
||||||
"""Returns the node class based on the node type."""
|
"""Returns the node class based on the node type."""
|
||||||
# First we check for the node_base_type
|
# First we check for the node_base_type
|
||||||
node_name = node_id.split("-")[0]
|
node_name = node_id.split("-")[0]
|
||||||
|
|
@ -1655,9 +1657,9 @@ class Graph:
|
||||||
return lazy_load_vertex_dict.VERTEX_TYPE_MAP[node_type]
|
return lazy_load_vertex_dict.VERTEX_TYPE_MAP[node_type]
|
||||||
return Vertex
|
return Vertex
|
||||||
|
|
||||||
def _build_vertices(self) -> list["Vertex"]:
|
def _build_vertices(self) -> list[Vertex]:
|
||||||
"""Builds the vertices of the graph."""
|
"""Builds the vertices of the graph."""
|
||||||
vertices: list["Vertex"] = []
|
vertices: list[Vertex] = []
|
||||||
for frontend_data in self._vertices:
|
for frontend_data in self._vertices:
|
||||||
if frontend_data.get("type") == NodeTypeEnum.NoteNode:
|
if frontend_data.get("type") == NodeTypeEnum.NoteNode:
|
||||||
continue
|
continue
|
||||||
|
|
@ -1730,7 +1732,7 @@ class Graph:
|
||||||
|
|
||||||
def layered_topological_sort(
|
def layered_topological_sort(
|
||||||
self,
|
self,
|
||||||
vertices: list["Vertex"],
|
vertices: list[Vertex],
|
||||||
filter_graphs: bool = False,
|
filter_graphs: bool = False,
|
||||||
) -> list[list[str]]:
|
) -> list[list[str]]:
|
||||||
"""Performs a layered topological sort of the vertices in the graph."""
|
"""Performs a layered topological sort of the vertices in the graph."""
|
||||||
|
|
@ -1986,7 +1988,7 @@ class Graph:
|
||||||
runnable_vertices = []
|
runnable_vertices = []
|
||||||
visited = set()
|
visited = set()
|
||||||
|
|
||||||
def find_runnable_predecessors(predecessor: "Vertex"):
|
def find_runnable_predecessors(predecessor: Vertex):
|
||||||
predecessor_id = predecessor.id
|
predecessor_id = predecessor.id
|
||||||
if predecessor_id in visited:
|
if predecessor_id in visited:
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
|
@ -12,7 +14,7 @@ if TYPE_CHECKING:
|
||||||
class GraphStateManager:
|
class GraphStateManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
try:
|
try:
|
||||||
self.state_service: "StateService" = get_state_service()
|
self.state_service: StateService = get_state_service()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(f"Error getting state service. Defaulting to InMemoryStateService: {e}")
|
logger.debug(f"Error getting state service. Defaulting to InMemoryStateService: {e}")
|
||||||
from langflow.services.state.service import InMemoryStateService
|
from langflow.services.state.service import InMemoryStateService
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue