Skip to content

Commit

Permalink
Merge branch 'main' into fix-run_flow_json_env
Browse files Browse the repository at this point in the history
  • Loading branch information
ogabrielluiz authored Jan 31, 2025
2 parents 8fdbbb6 + e15fddd commit 7077a94
Show file tree
Hide file tree
Showing 29 changed files with 252 additions and 46 deletions.
2 changes: 1 addition & 1 deletion src/backend/base/langflow/base/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class LCAgentComponent(Component):
]

outputs = [
Output(display_name="Agent", name="agent", method="build_agent", hidden=True),
Output(display_name="Agent", name="agent", method="build_agent", hidden=True, tool_mode=False),
Output(display_name="Response", name="response", method="message_response"),
]

Expand Down
20 changes: 19 additions & 1 deletion src/backend/base/langflow/base/tools/component_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,24 @@ def __init__(self, component: Component, metadata: pd.DataFrame | None = None):
self.component = component
self.metadata = metadata

def _should_skip_output(self, output: Output) -> bool:
"""Determines if an output should be skipped when creating tools.
Args:
output (Output): The output to check.
Returns:
bool: True if the output should be skipped, False otherwise.
The output will be skipped if:
- tool_mode is False (output is not meant to be used as a tool)
- output name matches TOOL_OUTPUT_NAME
- output types contain any of the tool types in TOOL_TYPES_SET
"""
return not output.tool_mode or (
output.name == TOOL_OUTPUT_NAME or any(tool_type in output.types for tool_type in TOOL_TYPES_SET)
)

def get_tools(
self,
tool_name: str | None = None,
Expand All @@ -178,7 +196,7 @@ def get_tools(
) -> list[BaseTool]:
tools = []
for output in self.component.outputs:
if output.name == TOOL_OUTPUT_NAME or any(tool_type in output.types for tool_type in TOOL_TYPES_SET):
if self._should_skip_output(output):
continue

if not output.method:
Expand Down
20 changes: 17 additions & 3 deletions src/backend/base/langflow/components/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
from langflow.components.helpers import CurrentDateComponent
from langflow.components.helpers.memory import MemoryComponent
from langflow.components.langchain_utilities.tool_calling import ToolCallingAgentComponent
from langflow.custom.custom_component.component import _get_component_toolkit
from langflow.custom.utils import update_component_build_config
from langflow.field_typing import Tool
from langflow.io import BoolInput, DropdownInput, MultilineInput, Output
from langflow.logging import logger
from langflow.schema.dotdict import dotdict
Expand Down Expand Up @@ -84,8 +86,7 @@ async def message_response(self) -> Message:
if not isinstance(self.tools, list): # type: ignore[has-type]
self.tools = []
# Convert CurrentDateComponent to a StructuredTool
current_date_tool = (await CurrentDateComponent().to_toolkit()).pop(0)
# current_date_tool = CurrentDateComponent().to_toolkit()[0]
current_date_tool = (await CurrentDateComponent(**self.get_base_args()).to_toolkit()).pop(0)
if isinstance(current_date_tool, StructuredTool):
self.tools.append(current_date_tool)
else:
Expand Down Expand Up @@ -122,7 +123,7 @@ async def get_memory_data(self):
# filter out empty values
memory_kwargs = {k: v for k, v in memory_kwargs.items() if v}

return await MemoryComponent().set(**memory_kwargs).retrieve_messages()
return await MemoryComponent(**self.get_base_args()).set(**memory_kwargs).retrieve_messages()

def get_llm(self):
if isinstance(self.agent_llm, str):
Expand Down Expand Up @@ -265,3 +266,16 @@ async def update_build_config(
component_class, build_config, field_value, "model_name"
)
return dotdict({k: v.to_dict() if hasattr(v, "to_dict") else v for k, v in build_config.items()})

async def to_toolkit(self) -> list[Tool]:
component_toolkit = _get_component_toolkit()
tools_names = self._build_tools_names()
agent_description = self.get_tool_description()
# TODO: Agent Description Depreciated Feature to be removed
description = f"{agent_description}{tools_names}"
tools = component_toolkit(component=self).get_tools(
tool_name=self.get_tool_name(), tool_description=description, callbacks=self.get_langchain_callbacks()
)
if hasattr(self, "tools_metadata"):
tools = component_toolkit(component=self, metadata=self.tools_metadata).update_tools_metadata(tools=tools)
return tools
30 changes: 5 additions & 25 deletions src/backend/base/langflow/components/embeddings/text_embedder.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,26 @@ def generate_embeddings(self) -> Data:
embedding_model: Embeddings = self.embedding_model
message: Message = self.message

# Validate embedding model
if not embedding_model:
msg = "Embedding model not provided"
# Combine validation checks to reduce nesting
if not embedding_model or not hasattr(embedding_model, "embed_documents"):
msg = "Invalid or incompatible embedding model"
raise ValueError(msg)

# Extract the text content from the message
text_content = message.text if message and message.text else ""
if not text_content:
msg = "No text content found in message"
raise ValueError(msg)

# Check if the embedding model has the required attributes
if not hasattr(embedding_model, "client") or not embedding_model.client:
msg = "Embedding model client not properly initialized"
raise ValueError(msg)

# Ensure the base URL has proper protocol
if hasattr(embedding_model.client, "base_url"):
base_url = embedding_model.client.base_url
if not base_url.startswith(("http://", "https://")):
embedding_model.client.base_url = f"https://{base_url}"

# Generate embeddings using the provided embedding model
embeddings = embedding_model.embed_documents([text_content])

# Validate embeddings output
if not embeddings or not isinstance(embeddings, list):
msg = "Invalid embeddings generated"
raise ValueError(msg)

embedding_vector = embeddings[0]

self.status = {"text": text_content, "embeddings": embedding_vector}
return Data(data={"text": text_content, "embeddings": embedding_vector})
except Exception as e:
logging.exception("Error generating embeddings")
# Return empty data with error status
error_data = Data(data={"text": "", "embeddings": [], "error": str(e)})
self.status = {"error": str(e)}
return error_data

# Create a Data object to encapsulate the results
result_data = Data(data={"text": text_content, "embeddings": embedding_vector})
self.status = {"text": text_content, "embeddings": embedding_vector}
return result_data
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class CSVAgentComponent(LCAgentComponent):

outputs = [
Output(display_name="Response", name="response", method="build_agent_response"),
Output(display_name="Agent", name="agent", method="build_agent", hidden=True),
Output(display_name="Agent", name="agent", method="build_agent", hidden=True, tool_mode=False),
]

def _path(self) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from langchain_core.prompts import ChatPromptTemplate

from langflow.base.agents.agent import LCToolsAgentComponent
from langflow.custom.custom_component.component import _get_component_toolkit
from langflow.field_typing import Tool
from langflow.inputs import MessageTextInput
from langflow.inputs.inputs import DataInput, HandleInput
from langflow.schema import Data
Expand Down Expand Up @@ -54,3 +56,11 @@ def create_agent_runnable(self):
except NotImplementedError as e:
message = f"{self.display_name} does not support tool calling. Please try using a compatible model."
raise NotImplementedError(message) from e

async def to_toolkit(self) -> list[Tool]:
component_toolkit = _get_component_toolkit()
toolkit = component_toolkit(component=self)
tools = toolkit.get_tools(callbacks=self.get_langchain_callbacks())
if hasattr(self, "tools_metadata"):
tools = toolkit.update_tools_metadata(tools=tools)
return tools
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ClickhouseVectorStoreComponent(LCVectorStoreComponent):
value=False,
advanced=True,
),
StrInput(name="index_param", display_name="Param of the index", value="'L2Distance',100", advanced=True),
StrInput(name="index_param", display_name="Param of the index", value="100,'L2Distance'", advanced=True),
DictInput(name="index_query_params", display_name="index query params", advanced=True),
*LCVectorStoreComponent.inputs,
HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]),
Expand All @@ -75,7 +75,9 @@ def build_vector_store(self) -> Clickhouse:
raise ImportError(msg) from e

try:
client = clickhouse_connect.get_client(host=self.host, username=self.username, password=self.password)
client = clickhouse_connect.get_client(
host=self.host, port=self.port, username=self.username, password=self.password
)
client.command("SELECT 1")
except Exception as e:
msg = f"Failed to connect to Clickhouse: {e}"
Expand Down
18 changes: 17 additions & 1 deletion src/backend/base/langflow/custom/custom_component/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
if TYPE_CHECKING:
from collections.abc import Callable

from langflow.base.tools.component_tool import ComponentToolkit
from langflow.events.event_manager import EventManager
from langflow.graph.edge.schema import EdgeData
from langflow.graph.vertex.base import Vertex
Expand Down Expand Up @@ -173,6 +174,21 @@ def _there_is_overlap_in_inputs_and_outputs(self) -> set[str]:
# Return the intersection of the sets
return input_names & output_names

def get_base_args(self):
"""Get the base arguments required for component initialization.
Returns:
dict: A dictionary containing the base arguments:
- _user_id: The ID of the current user
- _session_id: The ID of the current session
- _tracing_service: The tracing service instance for logging/monitoring
"""
return {
"_user_id": self.user_id,
"_session_id": self.session_id,
"_tracing_service": self._tracing_service,
}

@property
def ctx(self):
if not hasattr(self, "graph") or self.graph is None:
Expand Down Expand Up @@ -1023,7 +1039,7 @@ def _get_fallback_input(self, **kwargs):
return Input(**kwargs)

async def to_toolkit(self) -> list[Tool]:
component_toolkit = _get_component_toolkit()
component_toolkit: type[ComponentToolkit] = _get_component_toolkit()
tools = component_toolkit(component=self).get_tools(callbacks=self.get_langchain_callbacks())
if hasattr(self, TOOLS_METADATA_INPUT_NAME):
tools = component_toolkit(component=self, metadata=self.tools_metadata).update_tools_metadata(tools=tools)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand Down Expand Up @@ -345,6 +346,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand Down Expand Up @@ -639,6 +641,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand Down Expand Up @@ -915,6 +918,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand Down Expand Up @@ -1041,6 +1045,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand Down Expand Up @@ -1251,6 +1256,7 @@
"name": "text_output",
"required_inputs": [],
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand All @@ -1266,6 +1272,7 @@
"api_key"
],
"selected": "LanguageModel",
"tool_mode": true,
"types": [
"LanguageModel"
],
Expand Down Expand Up @@ -1595,6 +1602,7 @@
"name": "text_output",
"required_inputs": [],
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand All @@ -1610,6 +1618,7 @@
"api_key"
],
"selected": "LanguageModel",
"tool_mode": true,
"types": [
"LanguageModel"
],
Expand Down Expand Up @@ -1939,6 +1948,7 @@
"name": "text_output",
"required_inputs": [],
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand All @@ -1954,6 +1964,7 @@
"api_key"
],
"selected": "LanguageModel",
"tool_mode": true,
"types": [
"LanguageModel"
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand Down Expand Up @@ -400,6 +401,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand Down Expand Up @@ -602,6 +604,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand Down Expand Up @@ -888,6 +891,7 @@
"name": "text_output",
"required_inputs": [],
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
Expand All @@ -903,6 +907,7 @@
"api_key"
],
"selected": "LanguageModel",
"tool_mode": true,
"types": [
"LanguageModel"
],
Expand Down
Loading

0 comments on commit 7077a94

Please sign in to comment.