langflow-ai / langflow

Langflow is a low-code app builder for RAG and multi-agent AI applications. It’s Python-based and agnostic to any model, API, or database.
http://www.langflow.org
MIT License
27.96k stars 3.63k forks source link

TypeError: The last parameter to Concatenate should be a ParamSpec variable. #2818

Closed carlosrcoelho closed 1 month ago

carlosrcoelho commented 1 month ago

Bug Description

───── Traceback (most recent call last) ────────────────╮ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/directory_reader/directory_reader.py:349 in │ │ abuild_component_menu_list │ │ │ │ 346 │ │ │ │ │ 347 │ │ │ if validation_result: │ │ 348 │ │ │ │ try: │ │ ❱ 349 │ │ │ │ │ output_types = await │ │ self.get_output_types_from_code_async(result_content) │ │ 350 │ │ │ │ except Exception as exc: │ │ 351 │ │ │ │ │ logger.exception(f"Error while getting │ │ {str(exc)}") │ │ 352 │ │ │ │ │ output_types = [component_name_camelcas │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/directory_reader/directory_reader.py:319 in │ │ get_output_types_from_code_async │ │ │ │ 316 │ │ │ return True, file_content │ │ 317 │ │ │ 318 │ async def get_output_types_from_code_async(self, code: │ │ ❱ 319 │ │ return await asyncio.to_thread(self.get_output_type │ │ 320 │ │ │ 321 │ async def abuild_component_menu_list(self, file_paths): │ │ 322 │ │ response = {"menu": []} │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/asyncio/threads.py:25 in │ │ to_thread │ │ │ │ 22 │ loop = events.get_running_loop() │ │ 23 │ ctx = contextvars.copy_context() │ │ 24 │ func_call = functools.partial(ctx.run, func, *args, kw │ │ ❱ 25 │ return await loop.run_in_executor(None, func_call) │ │ 26 │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/asyncio/futures.py:285 in │ │ await │ │ │ │ 282 │ def await(self): │ │ 283 │ │ if not self.done(): │ │ 284 │ │ │ self._asyncio_future_blocking = True │ │ ❱ 285 │ │ │ yield self # This tells Task to wait for compl │ │ 286 │ │ if not self.done(): │ │ 287 │ │ │ raise RuntimeError("await wasn't used with futu │ │ 288 │ │ return self.result() # May raise too. │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/asyncio/tasks.py:304 in wakeup │ │ │ │ 301 │ │ │ 302 │ def wakeup(self, future): │ │ 303 │ │ try: │ │ ❱ 304 │ │ │ future.result() │ │ 305 │ │ except BaseException as exc: │ │ 306 │ │ │ # This may also be a cancellation. │ │ 307 │ │ │ self.step(exc) │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/asyncio/futures.py:201 in result │ │ │ │ 198 │ │ │ raise exceptions.InvalidStateError('Result is n │ │ 199 │ │ self.log_traceback = False │ │ 200 │ │ if self._exception is not None: │ │ ❱ 201 │ │ │ raise self._exception.with_traceback(self._exce │ │ 202 │ │ return self._result │ │ 203 │ │ │ 204 │ def exception(self): │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/concurrent/futures/thread.py:58 │ │ in run │ │ │ │ 55 │ │ │ return │ │ 56 │ │ │ │ 57 │ │ try: │ │ ❱ 58 │ │ │ result = self.fn(*self.args, *self.kwargs) │ │ 59 │ │ except BaseException as exc: │ │ 60 │ │ │ self.future.set_exception(exc) │ │ 61 │ │ │ # Break a reference cycle with the exception 'e │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/directory_reader/directory_reader.py:377 in │ │ get_output_types_from_code │ │ │ │ 374 │ │ Get the output types from the code. │ │ 375 │ │ """ │ │ 376 │ │ custom_component = CustomComponent(code=code) │ │ ❱ 377 │ │ types_list = custom_component.get_functionentrypoi │ │ 378 │ │ │ │ 379 │ │ # Get the name of types classes │ │ 380 │ │ return [type.name for type_ in types_list if h │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/custom_component/custom_component.py:352 in │ │ get_function_entrypoint_return_type │ │ │ │ 349 │ │ Returns: │ │ 350 │ │ │ List[Any]: The return type of the function entr │ │ 351 │ │ """ │ │ ❱ 352 │ │ return self.get_method_return_type(self.function_en │ │ 353 │ │ │ 354 │ def get_method_return_type(self, method_name: str): │ │ 355 │ │ build_method = self.get_method(method_name) │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/custom_component/custom_component.py:355 in │ │ get_method_return_type │ │ │ │ 352 │ │ return self.get_method_return_type(self.function_en │ │ 353 │ │ │ 354 │ def get_method_return_type(self, method_name: str): │ │ ❱ 355 │ │ build_method = self.get_method(method_name) │ │ 356 │ │ if not build_method or not build_method.get("has_re │ │ 357 │ │ │ return [] │ │ 358 │ │ return_type = build_method["return_type"] │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/custom_component/custom_component.py:333 in │ │ get_method │ │ │ │ 330 │ │ │ return {} │ │ 331 │ │ │ │ 332 │ │ component_classes = [ │ │ ❱ 333 │ │ │ cls for cls in self.tree["classes"] if "Compone │ │ "CustomComponent" in cls["bases"] │ │ 334 │ │ ] │ │ 335 │ │ if not component_classes: │ │ 336 │ │ │ return {} │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/custom_component/custom_component.py:229 in │ │ tree │ │ │ │ 226 │ │ Returns: │ │ 227 │ │ │ dict: The code tree of the custom component. │ │ 228 │ │ """ │ │ ❱ 229 │ │ return self.get_code_tree(self.code or "") │ │ 230 │ │ │ 231 │ def to_data(self, data: Any, keys: Optional[List[str]] │ │ False) -> List[Data]: │ │ 232 │ │ """ │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/cachetools/init.py:799 in wrapper │ │ │ │ 796 │ │ │ │ │ return c[k] │ │ 797 │ │ │ │ except KeyError: │ │ 798 │ │ │ │ │ pass # key not found │ │ ❱ 799 │ │ │ │ v = method(self, args, kwargs) │ │ 800 │ │ │ │ try: │ │ 801 │ │ │ │ │ c[k] = v │ │ 802 │ │ │ │ except ValueError: │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/custom_component/base_component.py:47 in │ │ get_code_tree │ │ │ │ 44 │ @cachedmethod(cache=operator.attrgetter("cache")) │ │ 45 │ def get_code_tree(self, code: str): │ │ 46 │ │ parser = CodeParser(code) │ │ ❱ 47 │ │ return parser.parse_code() │ │ 48 │ │ │ 49 │ def get_function(self): │ │ 50 │ │ if not self.code: │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/code_parser/code_parser.py:404 in parse_code │ │ │ │ 401 │ │ tree = self.get_tree() │ │ 402 │ │ │ │ 403 │ │ for node in ast.walk(tree): │ │ ❱ 404 │ │ │ self.parse_node(node) │ │ 405 │ │ return self.data │ │ 406 │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/code_parser/code_parser.py:108 in parse_node │ │ │ │ 105 │ │ dictionary with the relevant information. │ │ 106 │ │ """ │ │ 107 │ │ if handler := self.handlers.get(type(node)): # typ │ │ ❱ 108 │ │ │ handler(node) # type: ignore │ │ 109 │ │ │ 110 │ def parse_imports(self, node: Union[ast.Import, ast.Imp │ │ 111 │ │ """ │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/code_parser/code_parser.py:332 in │ │ parse_classes │ │ │ │ 329 │ │ """ │ │ 330 │ │ Extracts "classes" from the code, including inherit │ │ 331 │ │ """ │ │ ❱ 332 │ │ bases = self.get_base_classes() │ │ 333 │ │ nodes = [] │ │ 334 │ │ for base in bases: │ │ 335 │ │ │ if base.name == node.name or base.name │ │ "Component", "BaseComponent"]: │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/code_parser/code_parser.py:325 in │ │ get_base_classes │ │ │ │ 322 │ │ except Exception as e: │ │ 323 │ │ │ # If the code cannot be executed, return an emp │ │ 324 │ │ │ bases = [] │ │ ❱ 325 │ │ │ raise e │ │ 326 │ │ return bases │ │ 327 │ │ │ 328 │ def parse_classes(self, node: ast.ClassDef) -> None: │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/code_parser/code_parser.py:321 in │ │ get_base_classes │ │ │ │ 318 │ │ Returns the base classes of the custom component cl │ │ 319 │ │ """ │ │ 320 │ │ try: │ │ ❱ 321 │ │ │ bases = self.execute_and_inspect_classes(self.c │ │ 322 │ │ except Exception as e: │ │ 323 │ │ │ # If the code cannot be executed, return an emp │ │ 324 │ │ │ bases = [] │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/code_parser/code_parser.py:386 in │ │ execute_and_inspect_classes │ │ │ │ 383 │ │ self.data["global_vars"].append(global_var) │ │ 384 │ │ │ 385 │ def execute_and_inspect_classes(self, code: str): │ │ ❱ 386 │ │ custom_component_class = eval_custom_component_code │ │ 387 │ │ custom_component = custom_component_class() │ │ 388 │ │ dunder_class = custom_component.class │ │ 389 │ │ # Get the base classes at two levels of inheritance │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/custom/eval.py:12 in eval_custom_component_code │ │ │ │ 9 def eval_custom_component_code(code: str) -> Type["CustomCom │ │ 10 │ """Evaluate custom component code""" │ │ 11 │ class_name = validate.extract_class_name(code) │ │ ❱ 12 │ return validate.create_class(code, class_name) │ │ 13 │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/utils/validate.py:167 in create_class │ │ │ │ 164 │ │ "from langflow.custom import CustomComponent", │ │ 165 │ ) │ │ 166 │ module = ast.parse(code) │ │ ❱ 167 │ exec_globals = prepare_global_scope(code, module) │ │ 168 │ │ │ 169 │ class_code = extract_class_code(module, class_name) │ │ 170 │ compiled_class = compile_class_code(class_code) │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/utils/validate.py:206 in prepare_global_scope │ │ │ │ 203 │ │ │ │ │ raise ModuleNotFoundError(f"Module {ali │ │ install it and try again.") from e │ │ 204 │ │ elif isinstance(node, ast.ImportFrom) and node.modu │ │ 205 │ │ │ try: │ │ ❱ 206 │ │ │ │ imported_module = importlib.import_module(n │ │ 207 │ │ │ │ for alias in node.names: │ │ 208 │ │ │ │ │ exec_globals[alias.name] = getattr(impo │ │ 209 │ │ │ except ModuleNotFoundError: │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/importlib/init.py:126 in │ │ import_module │ │ │ │ 123 │ │ │ if character != '.': │ │ 124 │ │ │ │ break │ │ 125 │ │ │ level += 1 │ │ ❱ 126 │ return _bootstrap._gcd_import(name[level:], package, le │ │ 127 │ │ 128 │ │ 129 _RELOADING = {} │ │ in _gcd_import:1050 │ │ in _find_and_load:1027 │ │ in _find_and_load_unlocked:1006 │ │ in _load_unlocked:688 │ │ in exec_module:883 │ │ in _call_with_frames_removed:241 │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/base/agents/agent.py:9 in │ │ │ │ 6 from langchain_core.messages import BaseMessage │ │ 7 from langchain_core.runnables import Runnable │ │ 8 │ │ ❱ 9 from langflow.base.agents.callback import AgentAsyncHandler │ │ 10 from langflow.base.agents.utils import data_to_messages │ │ 11 from langflow.custom import Component │ │ 12 from langflow.field_typing import Text, Tool │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/base/agents/callback.py:10 in │ │ │ │ 7 from langflow.schema.log import LoggableType │ │ 8 │ │ 9 │ │ ❱ 10 class AgentAsyncHandler(AsyncCallbackHandler): │ │ 11 │ """Async callback handler that can be used to handle ca │ │ 12 │ │ │ 13 │ def init(self, log_function: Callable[Concatenate[L │ │ list[LoggableType], ...], None] | None = None): │ │ │ │ /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packa │ │ ges/langflow/base/agents/callback.py:13 in AgentAsyncHandler │ │ │ │ 10 class AgentAsyncHandler(AsyncCallbackHandler): │ │ 11 │ """Async callback handler that can be used to handle ca │ │ 12 │ │ │ ❱ 13 │ def init(self, log_function: Callable[Concatenate[L │ │ list[LoggableType], ...], None] | None = None): │ │ 14 │ │ self.log_function = log_function │ │ 15 │ │ │ 16 │ async def on_tool_start( │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/typing.py:312 in inner │ │ │ │ 309 │ │ │ │ return cached(*args, *kwds) │ │ 310 │ │ │ except TypeError: │ │ 311 │ │ │ │ pass # All real errors (not unhashable ar │ │ ❱ 312 │ │ │ return func(args, *kwds) │ │ 313 │ │ return inner │ │ 314 │ │ │ 315 │ if func is not None: │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/typing.py:403 in getitem │ │ │ │ 400 │ │ │ 401 │ @_tp_cache │ │ 402 │ def getitem(self, parameters): │ │ ❱ 403 │ │ return self._getitem(self, parameters) │ │ 404 │ │ 405 │ │ 406 class _LiteralSpecialForm(_SpecialForm, _root=True): │ │ │ │ /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framew │ │ ork/Versions/3.10/lib/python3.10/typing.py:599 in Concatenate │ │ │ │ 596 │ if not isinstance(parameters, tuple): │ │ 597 │ │ parameters = (parameters,) │ │ 598 │ if not isinstance(parameters[-1], ParamSpec): │ │ ❱ 599 │ │ raise TypeError("The last parameter to Concatenate │ │ 600 │ │ │ │ │ │ "ParamSpec variable.") │ │ 601 │ msg = "Concatenate[arg, ...]: each arg must be a type. │ │ 602 │ parameters = ((_type_check(p, msg) for p in parameter │ ╰───────────────────────────────────────────────────────────────────╯ TypeError: The last parameter to Concatenate should be a ParamSpec variable. /Users/carlos.coelho/repo/langflow-test/lib/python3.10/site-packages/langchain/tools/init.py:63: LangChainDeprecationWarning: Importing tools from langchain is deprecated. Importing from langchain will no longer be supported as of langchain==0.2.0. Please import from langchain-community instead:

from langchain_community.tools import WikipediaQueryRun.

To install langchain-community run pip install -U langchain-community. warnings.warn( ╭───────────────────────────────────────────────────────────────────╮ │ Welcome to ⛓ Langflow │ │ │ │ │ │ Collaborate, and contribute at our GitHub Repo 🌟 │ │ │ │ We collect anonymous usage data to improve Langflow. │ │ You can opt-out by setting DO_NOT_TRACK=true in your environment. │ │ │ │ Access http://127.0.0.1:7861 │ ╰───────────────────────────────────────────────────────────────────╯

Reproduction

The issue occurs when using the command python3 -m pip install langflow -U.

Expected behavior

run without errors

Who can help?

@ga

Operating System

macOS 14.5

Langflow Version

1.0.10

Python Version

LeeJaehyeok0802 commented 1 month ago

I met same error too.

carlosrcoelho commented 1 month ago

@ogabrielluiz made a PR here: https://github.com/langflow-ai/langflow/pull/2793