refactor: reorganize memory components and enhance model inputs with improved documentation (#4529)

* new components improvements

* ✨ (create_data.py): introduce a new 'legacy' attribute to mark the component as legacy code

* [autofix.ci] apply automated fixes

* chaing langchain hub name

* 📝 (run_flow.py): remove beta flag from RunFlowComponent to indicate it is no longer in beta
📝 (extract_key.py): remove beta flag from ExtractDataKeyComponent to indicate it is no longer in beta

* Updated generic icon component to load icons if already not lazy imported

* [autofix.ci] apply automated fixes

* merge fix

* 📝 (store_message.py): add 'advanced' parameter to the 'Session ID' field to indicate it is an advanced setting

* [autofix.ci] apply automated fixes

* new components sweep

* [autofix.ci] apply automated fixes

* fix tests

* [autofix.ci] apply automated fixes

* ✨ (filterSidebar.spec.ts): Update test descriptions to reflect the correct component names for better clarity and maintainability
♻️ (freeze.spec.ts): Refactor test to use the correct component name for consistency and readability
♻️ (stop-building.spec.ts): Refactor test to use the correct component name for consistency and readability
♻️ (generalBugs-shard-9.spec.ts): Refactor test to use the correct component name for consistency and readability
♻️ (filterEdge-shard-1.spec.ts): Refactor test to use the correct component name for consistency and readability

* style: Improve YahooFinanceToolComponent description and code readability

Enhance clarity in the component's purpose and refine inline formatting to boost maintainability.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Lucas Oliveira <lucas.edu.oli@hotmail.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
Cristhian Zanforlin Lousa 2024-11-13 01:19:24 -03:00 • committed by GitHub
commit 8d89bf4ff4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 63 additions and 58 deletions

View file

@ -4,8 +4,8 @@ from langflow.base.agents.agent import LCToolsAgentComponent
from langflow.base.models.model_input_constants import ALL_PROVIDER_FIELDS, MODEL_PROVIDERS_DICT from langflow.base.models.model_input_constants import ALL_PROVIDER_FIELDS, MODEL_PROVIDERS_DICT
from langflow.base.models.model_utils import get_model_name from langflow.base.models.model_utils import get_model_name
from langflow.components.helpers import CurrentDateComponent from langflow.components.helpers import CurrentDateComponent
from langflow.components.helpers.memory import MemoryComponent
from langflow.components.langchain_utilities.tool_calling import ToolCallingAgentComponent from langflow.components.langchain_utilities.tool_calling import ToolCallingAgentComponent
from langflow.components.memories.memory import MemoryComponent
from langflow.io import BoolInput, DropdownInput, MultilineInput, Output from langflow.io import BoolInput, DropdownInput, MultilineInput, Output
from langflow.schema.dotdict import dotdict from langflow.schema.dotdict import dotdict
from langflow.schema.message import Message from langflow.schema.message import Message

View file

@ -11,8 +11,8 @@ class CSVToDataComponent(Component):
display_name = "Load CSV" display_name = "Load CSV"
description = "Load a CSV file, CSV from a file path, or a valid CSV string and convert it to a list of Data" description = "Load a CSV file, CSV from a file path, or a valid CSV string and convert it to a list of Data"
icon = "file-spreadsheet" icon = "file-spreadsheet"
beta = True
name = "CSVtoData" name = "CSVtoData"
legacy = True
inputs = [ inputs = [
FileInput( FileInput(

View file

@ -14,8 +14,8 @@ class JSONToDataComponent(Component):
"Convert a JSON file, JSON from a file path, or a JSON string to a Data object or a list of Data objects" "Convert a JSON file, JSON from a file path, or a JSON string to a Data object or a list of Data objects"
) )
icon = "braces" icon = "braces"
beta = True
name = "JSONtoData" name = "JSONtoData"
legacy = True
inputs = [ inputs = [
FileInput( FileInput(

View file

@ -6,7 +6,7 @@ from langflow.field_typing import Text
class SQLExecutorComponent(CustomComponent): class SQLExecutorComponent(CustomComponent):
display_name = "SQL Executor" display_name = "SQL Query"
description = "Execute SQL query." description = "Execute SQL query."
name = "SQLExecutor" name = "SQLExecutor"
beta: bool = True beta: bool = True

View file

@ -14,7 +14,7 @@ class WebhookComponent(Component):
MultilineInput( MultilineInput(
name="data", name="data",
display_name="Payload", display_name="Payload",
info="Use this field to quickly test the webhook component by providing a JSON payload.", info="Receives a payload from external systems via HTTP POST.",
) )
] ]
outputs = [ outputs = [

View file

@ -1,8 +1,9 @@
from .create_list import CreateListComponent from .create_list import CreateListComponent
from .current_date import CurrentDateComponent from .current_date import CurrentDateComponent
from .id_generator import IDGeneratorComponent from .id_generator import IDGeneratorComponent
from .memory import MemoryComponent
from .output_parser import OutputParserComponent from .output_parser import OutputParserComponent
from .split_text import SplitTextComponent from .store_message import StoreMessageComponent
from .structured_output import StructuredOutputComponent from .structured_output import StructuredOutputComponent
__all__ = [ __all__ = [
@ -10,6 +11,7 @@ __all__ = [
"CurrentDateComponent", "CurrentDateComponent",
"IDGeneratorComponent", "IDGeneratorComponent",
"OutputParserComponent", "OutputParserComponent",
"SplitTextComponent",
"StructuredOutputComponent", "StructuredOutputComponent",
"StoreMessageComponent",
"MemoryComponent",
] ]

View file

@ -12,7 +12,7 @@ from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER
class MemoryComponent(Component): class MemoryComponent(Component):
display_name = "Chat Memory" display_name = "Message History"
description = "Retrieves stored chat messages from Langflow tables or an external memory." description = "Retrieves stored chat messages from Langflow tables or an external memory."
icon = "message-square-more" icon = "message-square-more"
name = "Memory" name = "Memory"

View file

@ -11,6 +11,7 @@ class OutputParserComponent(Component):
description = "Transforms the output of an LLM into a specified format." description = "Transforms the output of an LLM into a specified format."
icon = "type" icon = "type"
name = "OutputParser" name = "OutputParser"
legacy = True
inputs = [ inputs = [
DropdownInput( DropdownInput(

View file

@ -39,6 +39,7 @@ class StoreMessageComponent(Component):
display_name="Session ID", display_name="Session ID",
info="The session ID of the chat. If empty, the current session ID parameter will be used.", info="The session ID of the chat. If empty, the current session ID parameter will be used.",
value="", value="",
advanced=True,
), ),
] ]

View file

@ -9,7 +9,7 @@ from langflow.schema.message import Message
class LangChainHubPromptComponent(Component): class LangChainHubPromptComponent(Component):
display_name: str = "LangChain Hub" display_name: str = "Prompt Hub"
description: str = "Prompt Component that uses LangChain Hub prompts" description: str = "Prompt Component that uses LangChain Hub prompts"
beta = True beta = True
icon = "LangChain" icon = "LangChain"

View file

@ -8,7 +8,6 @@ class ConditionalRouterComponent(Component):
description = "Routes an input message to a corresponding output based on text comparison." description = "Routes an input message to a corresponding output based on text comparison."
icon = "split" icon = "split"
name = "ConditionalRouter" name = "ConditionalRouter"
legacy = True
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)

View file

@ -9,7 +9,6 @@ class DataConditionalRouterComponent(Component):
display_name = "Condition" display_name = "Condition"
description = "Route Data object(s) based on a condition applied to a specified key, including boolean validation." description = "Route Data object(s) based on a condition applied to a specified key, including boolean validation."
icon = "split" icon = "split"
beta = True
name = "DataConditionalRouter" name = "DataConditionalRouter"
legacy = True legacy = True

View file

@ -15,7 +15,6 @@ class RunFlowComponent(Component):
display_name = "Run Flow" display_name = "Run Flow"
description = "A component to run a flow." description = "A component to run a flow."
name = "RunFlow" name = "RunFlow"
beta: bool = True
legacy: bool = True legacy: bool = True
icon = "workflow" icon = "workflow"

View file

@ -1,5 +0,0 @@
from .mem0_chat_memory import Mem0MemoryComponent
__all__ = [
"Mem0MemoryComponent",
]

View file

@ -1,15 +1,13 @@
from .astra_db import AstraDBChatMemory from .astra_db import AstraDBChatMemory
from .cassandra import CassandraChatMemory from .cassandra import CassandraChatMemory
from .memory import MemoryComponent from .mem0_chat_memory import Mem0MemoryComponent
from .redis import RedisIndexChatMemory from .redis import RedisIndexChatMemory
from .store_message import StoreMessageComponent
from .zep import ZepChatMemory from .zep import ZepChatMemory
__all__ = [ __all__ = [
"AstraDBChatMemory", "AstraDBChatMemory",
"CassandraChatMemory", "CassandraChatMemory",
"MemoryComponent",
"RedisIndexChatMemory", "RedisIndexChatMemory",
"ZepChatMemory", "ZepChatMemory",
"StoreMessageComponent", "Mem0MemoryComponent",
] ]

View file

@ -70,7 +70,6 @@ class ChatOllamaComponent(LCModelComponent):
raise ValueError(msg) from e raise ValueError(msg) from e
inputs = [ inputs = [
*LCModelComponent._base_inputs,
StrInput( StrInput(
name="base_url", name="base_url",
display_name="Base URL", display_name="Base URL",
@ -151,7 +150,7 @@ class ChatOllamaComponent(LCModelComponent):
name="top_k", display_name="Top K", info="Limits token selection to top K. (Default: 40)", advanced=True name="top_k", display_name="Top K", info="Limits token selection to top K. (Default: 40)", advanced=True
), ),
FloatInput(name="top_p", display_name="Top P", info="Works together with top-k. (Default: 0.9)", advanced=True), FloatInput(name="top_p", display_name="Top P", info="Works together with top-k. (Default: 0.9)", advanced=True),
BoolInput(name="verbose", display_name="Verbose", info="Whether to print out response text."), BoolInput(name="verbose", display_name="Verbose", info="Whether to print out response text.", advanced=True),
StrInput( StrInput(
name="tags", name="tags",
display_name="Tags", display_name="Tags",
@ -173,6 +172,7 @@ class ChatOllamaComponent(LCModelComponent):
advanced=True, advanced=True,
input_types=["OutputParser"], input_types=["OutputParser"],
), ),
*LCModelComponent._base_inputs,
] ]
def build_model(self) -> LanguageModel: # type: ignore[type-var] def build_model(self) -> LanguageModel: # type: ignore[type-var]

View file

@ -8,6 +8,7 @@ from .message_to_data import MessageToDataComponent
from .parse_data import ParseDataComponent from .parse_data import ParseDataComponent
from .parse_json_data import ParseJSONDataComponent from .parse_json_data import ParseJSONDataComponent
from .select_data import SelectDataComponent from .select_data import SelectDataComponent
from .split_text import SplitTextComponent
from .update_data import UpdateDataComponent from .update_data import UpdateDataComponent
__all__ = [ __all__ = [
@ -22,4 +23,5 @@ __all__ = [
"ParseJSONDataComponent", "ParseJSONDataComponent",
"JSONCleaner", "JSONCleaner",
"CombineTextComponent", "CombineTextComponent",
"SplitTextComponent",
] ]

View file

@ -13,6 +13,7 @@ class CreateDataComponent(Component):
description: str = "Dynamically create a Data with a specified number of fields." description: str = "Dynamically create a Data with a specified number of fields."
name: str = "CreateData" name: str = "CreateData"
MAX_FIELDS = 15 # Define a constant for maximum number of fields MAX_FIELDS = 15 # Define a constant for maximum number of fields
legacy = True
inputs = [ inputs = [
IntInput( IntInput(

View file

@ -10,8 +10,8 @@ class ExtractDataKeyComponent(Component):
"Data objects and return the extracted value(s) as Data object(s)." "Data objects and return the extracted value(s) as Data object(s)."
) )
icon = "key" icon = "key"
beta = True
name = "ExtractaKey" name = "ExtractaKey"
legacy = True
inputs = [ inputs = [
DataInput( DataInput(

View file

@ -10,6 +10,7 @@ class SelectDataComponent(Component):
description: str = "Select a single data from a list of data." description: str = "Select a single data from a list of data."
name: str = "SelectData" name: str = "SelectData"
icon = "prototypes" icon = "prototypes"
legacy = True
inputs = [ inputs = [
DataInput( DataInput(

View file

@ -10,7 +10,7 @@ from langflow.schema import Data
class AstraDBToolComponent(LCToolComponent): class AstraDBToolComponent(LCToolComponent):
display_name: str = "Astra DB Tool" display_name: str = "Astra DB"
description: str = "Create a tool to get data from DataStax Astra DB Collection" description: str = "Create a tool to get data from DataStax Astra DB Collection"
documentation: str = "https://astra.datastax.com" documentation: str = "https://astra.datastax.com"
icon: str = "AstraDB" icon: str = "AstraDB"

View file

@ -12,7 +12,7 @@ from langflow.schema import Data
class AstraDBCQLToolComponent(LCToolComponent): class AstraDBCQLToolComponent(LCToolComponent):
display_name: str = "Astra DB CQL Tool" display_name: str = "Astra DB CQL"
description: str = "Create a tool to get data from DataStax Astra DB CQL Table" description: str = "Create a tool to get data from DataStax Astra DB CQL Table"
documentation: str = "https://astra.datastax.com" documentation: str = "https://astra.datastax.com"
icon: str = "AstraDB" icon: str = "AstraDB"

View file

@ -37,7 +37,7 @@ class PythonCodeStructuredTool(LCToolComponent):
"_classes", "_classes",
"_functions", "_functions",
] ]
display_name = "Python Code Structured Tool" display_name = "Python Code Structured"
description = "structuredtool dataclass code to tool" description = "structuredtool dataclass code to tool"
documentation = "https://python.langchain.com/docs/modules/tools/custom_tools/#structuredtool-dataclass" documentation = "https://python.langchain.com/docs/modules/tools/custom_tools/#structuredtool-dataclass"
name = "PythonCodeStructuredTool" name = "PythonCodeStructuredTool"

View file

@ -13,7 +13,7 @@ from langflow.schema import Data
class PythonREPLToolComponent(LCToolComponent): class PythonREPLToolComponent(LCToolComponent):
display_name = "Python REPL Tool" display_name = "Python REPL"
description = "A tool for running Python code in a REPL environment." description = "A tool for running Python code in a REPL environment."
name = "PythonREPLTool" name = "PythonREPLTool"

View file

@ -16,7 +16,7 @@ from langflow.schema.dotdict import dotdict
class SearXNGToolComponent(LCToolComponent): class SearXNGToolComponent(LCToolComponent):
search_headers: dict = {} search_headers: dict = {}
display_name = "SearXNG Search Tool" display_name = "SearXNG Search"
description = "A component that searches for tools using SearXNG." description = "A component that searches for tools using SearXNG."
name = "SearXNGTool" name = "SearXNGTool"
legacy: bool = True legacy: bool = True

View file

@ -9,13 +9,12 @@ from langflow.schema import Data
class WolframAlphaAPIComponent(LCToolComponent): class WolframAlphaAPIComponent(LCToolComponent):
display_name = "WolframAlpha API" display_name = "WolframAlpha API"
description = """Enables queries to Wolfram Alpha for computational data, facts, and calculations across various \ description = """Enables queries to Wolfram Alpha for computational data, facts, and calculations across various \
topics, delivering structured responses. Example query: 'What is the population of France?'""" topics, delivering structured responses."""
name = "WolframAlphaAPI" name = "WolframAlphaAPI"
inputs = [ inputs = [
MultilineInput( MultilineInput(
name="input_value", name="input_value", display_name="Input Query", info="Example query: 'What is the population of France?'"
display_name="Input Query",
), ),
SecretStrInput(name="app_id", display_name="App ID", required=True), SecretStrInput(name="app_id", display_name="App ID", required=True),
] ]

View file

@ -50,7 +50,8 @@ class YahooFinanceSchema(BaseModel):
class YfinanceToolComponent(LCToolComponent): class YfinanceToolComponent(LCToolComponent):
display_name = "Yahoo Finance" display_name = "Yahoo Finance"
description = "Access financial data and market information using Yahoo Finance." description = """Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) \
to access financial data and market information from Yahoo Finance."""
icon = "trending-up" icon = "trending-up"
name = "YahooFinanceTool" name = "YahooFinanceTool"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2956,7 +2956,7 @@
"show": true, "show": true,
"title_case": false, "title_case": false,
"type": "code", "type": "code",
"value": "import ast\nimport pprint\nfrom enum import Enum\n\nimport yfinance as yf\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DropdownInput, IntInput, MessageTextInput\nfrom langflow.schema import Data\n\n\nclass YahooFinanceMethod(Enum):\n GET_INFO = \"get_info\"\n GET_NEWS = \"get_news\"\n GET_ACTIONS = \"get_actions\"\n GET_ANALYSIS = \"get_analysis\"\n GET_BALANCE_SHEET = \"get_balance_sheet\"\n GET_CALENDAR = \"get_calendar\"\n GET_CASHFLOW = \"get_cashflow\"\n GET_INSTITUTIONAL_HOLDERS = \"get_institutional_holders\"\n GET_RECOMMENDATIONS = \"get_recommendations\"\n GET_SUSTAINABILITY = \"get_sustainability\"\n GET_MAJOR_HOLDERS = \"get_major_holders\"\n GET_MUTUALFUND_HOLDERS = \"get_mutualfund_holders\"\n GET_INSIDER_PURCHASES = \"get_insider_purchases\"\n GET_INSIDER_TRANSACTIONS = \"get_insider_transactions\"\n GET_INSIDER_ROSTER_HOLDERS = \"get_insider_roster_holders\"\n GET_DIVIDENDS = \"get_dividends\"\n GET_CAPITAL_GAINS = \"get_capital_gains\"\n GET_SPLITS = \"get_splits\"\n GET_SHARES = \"get_shares\"\n GET_FAST_INFO = \"get_fast_info\"\n GET_SEC_FILINGS = \"get_sec_filings\"\n GET_RECOMMENDATIONS_SUMMARY = \"get_recommendations_summary\"\n GET_UPGRADES_DOWNGRADES = \"get_upgrades_downgrades\"\n GET_EARNINGS = \"get_earnings\"\n GET_INCOME_STMT = \"get_income_stmt\"\n\n\nclass YahooFinanceSchema(BaseModel):\n symbol: str = Field(..., description=\"The stock symbol to retrieve data for.\")\n method: YahooFinanceMethod = Field(YahooFinanceMethod.GET_INFO, description=\"The type of data to retrieve.\")\n num_news: int | None = Field(5, description=\"The number of news articles to retrieve.\")\n\n\nclass YfinanceToolComponent(LCToolComponent):\n display_name = \"Yahoo Finance\"\n description = \"Access financial data and market information using Yahoo Finance.\"\n icon = \"trending-up\"\n name = \"YahooFinanceTool\"\n\n inputs = [\n MessageTextInput(\n name=\"symbol\",\n display_name=\"Stock Symbol\",\n info=\"The stock symbol to retrieve data for (e.g., AAPL, GOOG).\",\n ),\n DropdownInput(\n name=\"method\",\n display_name=\"Data Method\",\n info=\"The type of data to retrieve.\",\n options=list(YahooFinanceMethod),\n value=\"get_news\",\n ),\n IntInput(\n name=\"num_news\",\n display_name=\"Number of News\",\n info=\"The number of news articles to retrieve (only applicable for get_news).\",\n value=5,\n ),\n ]\n\n def run_model(self) -> list[Data]:\n return self._yahoo_finance_tool(\n self.symbol,\n self.method,\n self.num_news,\n )\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"yahoo_finance\",\n description=\"Access financial data and market information from Yahoo Finance.\",\n func=self._yahoo_finance_tool,\n args_schema=YahooFinanceSchema,\n )\n\n def _yahoo_finance_tool(\n self,\n symbol: str,\n method: YahooFinanceMethod,\n num_news: int | None = 5,\n ) -> list[Data]:\n ticker = yf.Ticker(symbol)\n\n try:\n if method == YahooFinanceMethod.GET_INFO:\n result = ticker.info\n elif method == YahooFinanceMethod.GET_NEWS:\n result = ticker.news[:num_news]\n else:\n result = getattr(ticker, method.value)()\n\n result = pprint.pformat(result)\n\n if method == YahooFinanceMethod.GET_NEWS:\n data_list = [Data(data=article) for article in ast.literal_eval(result)]\n else:\n data_list = [Data(data={\"result\": result})]\n\n except Exception as e:\n error_message = f\"Error retrieving data: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n return data_list\n" "value": "import ast\nimport pprint\nfrom enum import Enum\n\nimport yfinance as yf\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DropdownInput, IntInput, MessageTextInput\nfrom langflow.schema import Data\n\n\nclass YahooFinanceMethod(Enum):\n GET_INFO = \"get_info\"\n GET_NEWS = \"get_news\"\n GET_ACTIONS = \"get_actions\"\n GET_ANALYSIS = \"get_analysis\"\n GET_BALANCE_SHEET = \"get_balance_sheet\"\n GET_CALENDAR = \"get_calendar\"\n GET_CASHFLOW = \"get_cashflow\"\n GET_INSTITUTIONAL_HOLDERS = \"get_institutional_holders\"\n GET_RECOMMENDATIONS = \"get_recommendations\"\n GET_SUSTAINABILITY = \"get_sustainability\"\n GET_MAJOR_HOLDERS = \"get_major_holders\"\n GET_MUTUALFUND_HOLDERS = \"get_mutualfund_holders\"\n GET_INSIDER_PURCHASES = \"get_insider_purchases\"\n GET_INSIDER_TRANSACTIONS = \"get_insider_transactions\"\n GET_INSIDER_ROSTER_HOLDERS = \"get_insider_roster_holders\"\n GET_DIVIDENDS = \"get_dividends\"\n GET_CAPITAL_GAINS = \"get_capital_gains\"\n GET_SPLITS = \"get_splits\"\n GET_SHARES = \"get_shares\"\n GET_FAST_INFO = \"get_fast_info\"\n GET_SEC_FILINGS = \"get_sec_filings\"\n GET_RECOMMENDATIONS_SUMMARY = \"get_recommendations_summary\"\n GET_UPGRADES_DOWNGRADES = \"get_upgrades_downgrades\"\n GET_EARNINGS = \"get_earnings\"\n GET_INCOME_STMT = \"get_income_stmt\"\n\n\nclass YahooFinanceSchema(BaseModel):\n symbol: str = Field(..., description=\"The stock symbol to retrieve data for.\")\n method: YahooFinanceMethod = Field(YahooFinanceMethod.GET_INFO, description=\"The type of data to retrieve.\")\n num_news: int | None = Field(5, description=\"The number of news articles to retrieve.\")\n\n\nclass YfinanceToolComponent(LCToolComponent):\n display_name = \"Yahoo Finance\"\n description = \"\"\"Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) \\\nto access financial data and market information from Yahoo Finance.\"\"\"\n icon = \"trending-up\"\n name = \"YahooFinanceTool\"\n\n inputs = [\n MessageTextInput(\n name=\"symbol\",\n display_name=\"Stock Symbol\",\n info=\"The stock symbol to retrieve data for (e.g., AAPL, GOOG).\",\n ),\n DropdownInput(\n name=\"method\",\n display_name=\"Data Method\",\n info=\"The type of data to retrieve.\",\n options=list(YahooFinanceMethod),\n value=\"get_news\",\n ),\n IntInput(\n name=\"num_news\",\n display_name=\"Number of News\",\n info=\"The number of news articles to retrieve (only applicable for get_news).\",\n value=5,\n ),\n ]\n\n def run_model(self) -> list[Data]:\n return self._yahoo_finance_tool(\n self.symbol,\n self.method,\n self.num_news,\n )\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"yahoo_finance\",\n description=\"Access financial data and market information from Yahoo Finance.\",\n func=self._yahoo_finance_tool,\n args_schema=YahooFinanceSchema,\n )\n\n def _yahoo_finance_tool(\n self,\n symbol: str,\n method: YahooFinanceMethod,\n num_news: int | None = 5,\n ) -> list[Data]:\n ticker = yf.Ticker(symbol)\n\n try:\n if method == YahooFinanceMethod.GET_INFO:\n result = ticker.info\n elif method == YahooFinanceMethod.GET_NEWS:\n result = ticker.news[:num_news]\n else:\n result = getattr(ticker, method.value)()\n\n result = pprint.pformat(result)\n\n if method == YahooFinanceMethod.GET_NEWS:\n data_list = [Data(data=article) for article in ast.literal_eval(result)]\n else:\n data_list = [Data(data={\"result\": result})]\n\n except Exception as e:\n error_message = f\"Error retrieving data: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n return data_list\n"
}, },
"method": { "method": {
"_input_type": "DropdownInput", "_input_type": "DropdownInput",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
from langflow.components.helpers.memory import MemoryComponent
from langflow.components.inputs import ChatInput from langflow.components.inputs import ChatInput
from langflow.components.memories import MemoryComponent
from langflow.components.models import OpenAIModelComponent from langflow.components.models import OpenAIModelComponent
from langflow.components.outputs import ChatOutput from langflow.components.outputs import ChatOutput
from langflow.components.prompts import PromptComponent from langflow.components.prompts import PromptComponent

View file

@ -2,11 +2,11 @@ from textwrap import dedent
from langflow.components.data import FileComponent from langflow.components.data import FileComponent
from langflow.components.embeddings import OpenAIEmbeddingsComponent from langflow.components.embeddings import OpenAIEmbeddingsComponent
from langflow.components.helpers import SplitTextComponent
from langflow.components.inputs import ChatInput from langflow.components.inputs import ChatInput
from langflow.components.models import OpenAIModelComponent from langflow.components.models import OpenAIModelComponent
from langflow.components.outputs import ChatOutput from langflow.components.outputs import ChatOutput
from langflow.components.processing import ParseDataComponent from langflow.components.processing import ParseDataComponent
from langflow.components.processing.split_text import SplitTextComponent
from langflow.components.prompts import PromptComponent from langflow.components.prompts import PromptComponent
from langflow.components.vectorstores import AstraVectorStoreComponent from langflow.components.vectorstores import AstraVectorStoreComponent
from langflow.graph import Graph from langflow.graph import Graph

View file

@ -1,8 +1,8 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import pytest import pytest
from langflow.components.helpers.memory import MemoryComponent
from langflow.components.inputs import ChatInput from langflow.components.inputs import ChatInput
from langflow.components.memories import MemoryComponent
from langflow.components.models import OpenAIModelComponent from langflow.components.models import OpenAIModelComponent
from langflow.components.outputs import ChatOutput from langflow.components.outputs import ChatOutput
from langflow.components.prompts import PromptComponent from langflow.components.prompts import PromptComponent

View file

@ -3,8 +3,8 @@ from collections import deque
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import pytest import pytest
from langflow.components.helpers.memory import MemoryComponent
from langflow.components.inputs import ChatInput from langflow.components.inputs import ChatInput
from langflow.components.memories import MemoryComponent
from langflow.components.models import OpenAIModelComponent from langflow.components.models import OpenAIModelComponent
from langflow.components.outputs import ChatOutput from langflow.components.outputs import ChatOutput
from langflow.components.prompts import PromptComponent from langflow.components.prompts import PromptComponent

View file

@ -5,11 +5,11 @@ from textwrap import dedent
import pytest import pytest
from langflow.components.data import FileComponent from langflow.components.data import FileComponent
from langflow.components.embeddings import OpenAIEmbeddingsComponent from langflow.components.embeddings import OpenAIEmbeddingsComponent
from langflow.components.helpers import SplitTextComponent
from langflow.components.inputs import ChatInput from langflow.components.inputs import ChatInput
from langflow.components.models import OpenAIModelComponent from langflow.components.models import OpenAIModelComponent
from langflow.components.outputs import ChatOutput from langflow.components.outputs import ChatOutput
from langflow.components.processing import ParseDataComponent from langflow.components.processing import ParseDataComponent
from langflow.components.processing.split_text import SplitTextComponent
from langflow.components.prompts import PromptComponent from langflow.components.prompts import PromptComponent
from langflow.components.vectorstores import AstraVectorStoreComponent from langflow.components.vectorstores import AstraVectorStoreComponent
from langflow.graph import Graph from langflow.graph import Graph

View file

@ -32,7 +32,14 @@ export const ForwardedIconComponent = memo(
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, []); }, []);
let TargetIcon = nodeIconsLucide[name]; let TargetIcon =
nodeIconsLucide[name] ||
nodeIconsLucide[
name
.split("-")
.map((x) => String(x[0]).toUpperCase() + String(x).slice(1))
.join("")
];
if (!TargetIcon) { if (!TargetIcon) {
if (!dynamicIconImports[name]) { if (!dynamicIconImports[name]) {
TargetIcon = nodeIconsLucide["unknown"]; TargetIcon = nodeIconsLucide["unknown"];

View file

@ -470,8 +470,8 @@ export const SIDEBAR_CATEGORIES = [
{ display_name: "Outputs", name: "outputs", icon: "Upload" }, { display_name: "Outputs", name: "outputs", icon: "Upload" },
{ display_name: "Prompts", name: "prompts", icon: "TerminalSquare" }, { display_name: "Prompts", name: "prompts", icon: "TerminalSquare" },
{ display_name: "Data", name: "data", icon: "Database" }, { display_name: "Data", name: "data", icon: "Database" },
{ display_name: "Processing", name: "processing", icon: "ListFilter" },
{ display_name: "Models", name: "models", icon: "BrainCircuit" }, { display_name: "Models", name: "models", icon: "BrainCircuit" },
{ display_name: "Helpers", name: "helpers", icon: "Wand2" },
{ display_name: "Vector Stores", name: "vectorstores", icon: "Layers" }, { display_name: "Vector Stores", name: "vectorstores", icon: "Layers" },
{ display_name: "Embeddings", name: "embeddings", icon: "Binary" }, { display_name: "Embeddings", name: "embeddings", icon: "Binary" },
{ display_name: "Agents", name: "agents", icon: "Bot" }, { display_name: "Agents", name: "agents", icon: "Bot" },
@ -486,7 +486,7 @@ export const SIDEBAR_CATEGORIES = [
{ display_name: "Toolkits", name: "toolkits", icon: "Package2" }, { display_name: "Toolkits", name: "toolkits", icon: "Package2" },
{ display_name: "Tools", name: "tools", icon: "Hammer" }, { display_name: "Tools", name: "tools", icon: "Hammer" },
{ display_name: "Logic", name: "logic", icon: "ArrowRightLeft" }, { display_name: "Logic", name: "logic", icon: "ArrowRightLeft" },
{ display_name: "Processing", name: "processing", icon: "ListFilter" }, { display_name: "Helpers", name: "helpers", icon: "Wand2" },
]; ];
export const SIDEBAR_BUNDLES = [ export const SIDEBAR_BUNDLES = [

View file

@ -84,7 +84,7 @@ test("user must see on handle click the possibility connections - LLMChain", asy
await expect(page.getByTestId("outputsChat Output")).toBeVisible(); await expect(page.getByTestId("outputsChat Output")).toBeVisible();
await expect(page.getByTestId("promptsPrompt")).toBeVisible(); await expect(page.getByTestId("promptsPrompt")).toBeVisible();
await expect(page.getByTestId("modelsAmazon Bedrock")).toBeVisible(); await expect(page.getByTestId("modelsAmazon Bedrock")).toBeVisible();
await expect(page.getByTestId("memoriesChat Memory")).toBeVisible(); await expect(page.getByTestId("helpersMessage History")).toBeVisible();
await expect(page.getByTestId("langchain_utilitiesCSVAgent")).toBeVisible(); await expect(page.getByTestId("langchain_utilitiesCSVAgent")).toBeVisible();
await expect( await expect(
page.getByTestId("langchain_utilitiesConversationChain"), page.getByTestId("langchain_utilitiesConversationChain"),
@ -106,7 +106,7 @@ test("user must see on handle click the possibility connections - LLMChain", asy
await expect(page.getByTestId("outputsChat Output")).not.toBeVisible(); await expect(page.getByTestId("outputsChat Output")).not.toBeVisible();
await expect(page.getByTestId("promptsPrompt")).not.toBeVisible(); await expect(page.getByTestId("promptsPrompt")).not.toBeVisible();
await expect(page.getByTestId("modelsAmazon Bedrock")).not.toBeVisible(); await expect(page.getByTestId("modelsAmazon Bedrock")).not.toBeVisible();
await expect(page.getByTestId("memoriesChat Memory")).not.toBeVisible(); await expect(page.getByTestId("helpersMessage History")).not.toBeVisible();
await expect(page.getByTestId("agentsTool Calling Agent")).not.toBeVisible(); await expect(page.getByTestId("agentsTool Calling Agent")).not.toBeVisible();
await expect( await expect(
page.getByTestId("langchain_utilitiesConversationChain"), page.getByTestId("langchain_utilitiesConversationChain"),
@ -123,7 +123,7 @@ test("user must see on handle click the possibility connections - LLMChain", asy
await expect(page.getByTestId("disclosure-tools")).toBeVisible(); await expect(page.getByTestId("disclosure-tools")).toBeVisible();
await expect(page.getByTestId("dataAPI Request")).toBeVisible(); await expect(page.getByTestId("dataAPI Request")).toBeVisible();
await expect(page.getByTestId("memoriesChat Memory")).toBeVisible(); await expect(page.getByTestId("helpersMessage History")).toBeVisible();
await expect(page.getByTestId("vectorstoresAstra DB")).toBeVisible(); await expect(page.getByTestId("vectorstoresAstra DB")).toBeVisible();
await expect(page.getByTestId("toolsSearch API")).toBeVisible(); await expect(page.getByTestId("toolsSearch API")).toBeVisible();
await expect(page.getByTestId("logicSub Flow")).not.toBeVisible(); await expect(page.getByTestId("logicSub Flow")).not.toBeVisible();
@ -136,17 +136,17 @@ test("user must see on handle click the possibility connections - LLMChain", asy
await expect(page.getByTestId("logicSub Flow")).toBeVisible(); await expect(page.getByTestId("logicSub Flow")).toBeVisible();
await expect(page.getByTestId("helpersSplit Text")).toBeVisible(); await expect(page.getByTestId("processingSplit Text")).toBeVisible();
await expect(page.getByTestId("toolsSearch API")).toBeVisible(); await expect(page.getByTestId("toolsSearch API")).toBeVisible();
await page.getByTestId("icon-X").first().click(); await page.getByTestId("icon-X").first().click();
await expect(page.getByTestId("dataAPI Request")).not.toBeVisible(); await expect(page.getByTestId("dataAPI Request")).not.toBeVisible();
await expect(page.getByTestId("memoriesChat Memory")).not.toBeVisible(); await expect(page.getByTestId("helpersMessage History")).not.toBeVisible();
await expect(page.getByTestId("vectorstoresAstra DB")).not.toBeVisible(); await expect(page.getByTestId("vectorstoresAstra DB")).not.toBeVisible();
await expect(page.getByTestId("toolsSearch API")).not.toBeVisible(); await expect(page.getByTestId("toolsSearch API")).not.toBeVisible();
await expect(page.getByTestId("logicSub Flow")).not.toBeVisible(); await expect(page.getByTestId("logicSub Flow")).not.toBeVisible();
await expect(page.getByTestId("helpersSplit Text")).not.toBeVisible(); await expect(page.getByTestId("processingSplit Text")).not.toBeVisible();
await expect(page.getByTestId("toolsSearch API")).not.toBeVisible(); await expect(page.getByTestId("toolsSearch API")).not.toBeVisible();
}); });

View file

@ -77,7 +77,7 @@ test("user must be able to freeze a component", async ({ page }) => {
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await page await page
.getByTestId("helpersSplit Text") .getByTestId("processingSplit Text")
.dragTo(page.locator('//*[@id="react-flow-id"]')); .dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.getByTestId("zoom_out").click(); await page.getByTestId("zoom_out").click();

View file

@ -82,7 +82,7 @@ test("user must be able to stop a building", async ({ page }) => {
// await page.waitForTimeout(1000); // await page.waitForTimeout(1000);
await page await page
.getByTestId("helpersSplit Text") .getByTestId("processingSplit Text")
.dragTo(page.locator('//*[@id="react-flow-id"]')); .dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.getByTestId("zoom_out").click(); await page.getByTestId("zoom_out").click();

View file

@ -76,7 +76,7 @@ test("memory should work as expect", async ({ page }) => {
await page.mouse.up(); await page.mouse.up();
await page await page
.getByTestId("memoriesChat Memory") .getByTestId("helpersMessage History")
.first() .first()
.dragTo(page.locator('//*[@id="react-flow-id"]')); .dragTo(page.locator('//*[@id="react-flow-id"]'));

View file

@ -97,7 +97,7 @@ test("user must see on handle click the possibility connections - RetrievalQA",
"outputsChat Output", "outputsChat Output",
"dataAPI Request", "dataAPI Request",
"modelsAmazon Bedrock", "modelsAmazon Bedrock",
"memoriesChat Memory", "helpersMessage History",
"vectorstoresAstra DB", "vectorstoresAstra DB",
"embeddingsAmazon Bedrock Embeddings", "embeddingsAmazon Bedrock Embeddings",
"langchain_utilitiesTool Calling Agent", "langchain_utilitiesTool Calling Agent",