diff --git a/.gitignore b/.gitignore index 1a5729f02..6da8678bd 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,5 @@ agentops.log test_flow.html crewairules.mdc plan.md -conceptual_plan.md \ No newline at end of file +conceptual_plan.md +build_image \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 799efacb8..c6c32e2d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ Documentation = "https://docs.crewai.com" Repository = "https://github.com/crewAIInc/crewAI" [project.optional-dependencies] -tools = ["crewai-tools~=0.38.0"] +tools = ["crewai-tools~=0.40.1"] embeddings = [ "tiktoken~=0.7.0" ] diff --git a/src/crewai/__init__.py b/src/crewai/__init__.py index 67d63b82c..565f89065 100644 --- a/src/crewai/__init__.py +++ b/src/crewai/__init__.py @@ -2,12 +2,14 @@ import warnings from crewai.agent import Agent from crewai.crew import Crew +from crewai.crews.crew_output import CrewOutput from crewai.flow.flow import Flow from crewai.knowledge.knowledge import Knowledge from crewai.llm import LLM from crewai.llms.base_llm import BaseLLM from crewai.process import Process from crewai.task import Task +from crewai.tasks.task_output import TaskOutput warnings.filterwarnings( "ignore", @@ -19,10 +21,12 @@ __version__ = "0.108.0" __all__ = [ "Agent", "Crew", + "CrewOutput", "Process", "Task", "LLM", "BaseLLM", "Flow", "Knowledge", + "TaskOutput", ] diff --git a/src/crewai/cli/install_crew.py b/src/crewai/cli/install_crew.py index d1d0ab9da..9491932f1 100644 --- a/src/crewai/cli/install_crew.py +++ b/src/crewai/cli/install_crew.py @@ -3,6 +3,10 @@ import subprocess import click +# Be mindful about changing this. +# on some enviorments we don't use this command but instead uv sync directly +# so if you expect this to support more things you will need to replicate it there +# ask @joaomdmoura if you are unsure def install_crew(proxy_options: list[str]) -> None: """ Install the crew by running the UV command to lock and install. diff --git a/src/crewai/project/crew_base.py b/src/crewai/project/crew_base.py index 53d3d5f3c..385e49f3d 100644 --- a/src/crewai/project/crew_base.py +++ b/src/crewai/project/crew_base.py @@ -137,13 +137,11 @@ def CrewBase(cls: T) -> T: all_functions, "is_cache_handler" ) callbacks = self._filter_functions(all_functions, "is_callback") - agents = self._filter_functions(all_functions, "is_agent") for agent_name, agent_info in self.agents_config.items(): self._map_agent_variables( agent_name, agent_info, - agents, llms, tool_functions, cache_handler_functions, @@ -154,7 +152,6 @@ def CrewBase(cls: T) -> T: self, agent_name: str, agent_info: Dict[str, Any], - agents: Dict[str, Callable], llms: Dict[str, Callable], tool_functions: Dict[str, Callable], cache_handler_functions: Dict[str, Callable], @@ -172,9 +169,10 @@ def CrewBase(cls: T) -> T: ] if function_calling_llm := agent_info.get("function_calling_llm"): - self.agents_config[agent_name]["function_calling_llm"] = agents[ - function_calling_llm - ]() + try: + self.agents_config[agent_name]["function_calling_llm"] = llms[function_calling_llm]() + except KeyError: + self.agents_config[agent_name]["function_calling_llm"] = function_calling_llm if step_callback := agent_info.get("step_callback"): self.agents_config[agent_name]["step_callback"] = callbacks[ diff --git a/tests/config/agents.yaml b/tests/config/agents.yaml index 84e8ef3cc..866a93cb7 100644 --- a/tests/config/agents.yaml +++ b/tests/config/agents.yaml @@ -8,6 +8,7 @@ researcher: developments in {topic}. Known for your ability to find the most relevant information and present it in a clear and concise manner. verbose: true + function_calling_llm: "local_llm" reporting_analyst: role: > @@ -18,4 +19,5 @@ reporting_analyst: You're a meticulous analyst with a keen eye for detail. You're known for your ability to turn complex data into clear and concise reports, making it easy for others to understand and act on the information you provide. - verbose: true \ No newline at end of file + verbose: true + function_calling_llm: "online_llm" \ No newline at end of file diff --git a/tests/imports_test.py b/tests/imports_test.py new file mode 100644 index 000000000..0715e3c50 --- /dev/null +++ b/tests/imports_test.py @@ -0,0 +1,15 @@ +"""Test that all public API classes are properly importable.""" + + +def test_task_output_import(): + """Test that TaskOutput can be imported from crewai.""" + from crewai import TaskOutput + + assert TaskOutput is not None + + +def test_crew_output_import(): + """Test that CrewOutput can be imported from crewai.""" + from crewai import CrewOutput + + assert CrewOutput is not None diff --git a/tests/project_test.py b/tests/project_test.py index ed9d86f2f..e0813a13f 100644 --- a/tests/project_test.py +++ b/tests/project_test.py @@ -2,7 +2,16 @@ import pytest from crewai.agent import Agent from crewai.crew import Crew -from crewai.project import CrewBase, after_kickoff, agent, before_kickoff, crew, task +from crewai.llm import LLM +from crewai.project import ( + CrewBase, + after_kickoff, + agent, + before_kickoff, + crew, + llm, + task, +) from crewai.task import Task @@ -31,6 +40,13 @@ class InternalCrew: agents_config = "config/agents.yaml" tasks_config = "config/tasks.yaml" + @llm + def local_llm(self): + return LLM( + model='openai/model_name', + api_key="None", + base_url="http://xxx.xxx.xxx.xxx:8000/v1") + @agent def researcher(self): return Agent(config=self.agents_config["researcher"]) @@ -105,6 +121,20 @@ def test_task_name(): ), "Custom task name is not being set as expected" +def test_agent_function_calling_llm(): + crew = InternalCrew() + llm = crew.local_llm() + obj_llm_agent = crew.researcher() + assert ( + obj_llm_agent.function_calling_llm is llm + ), "agent's function_calling_llm is incorrect" + + str_llm_agent = crew.reporting_analyst() + assert ( + str_llm_agent.function_calling_llm.model == "online_llm" + ), "agent's function_calling_llm is incorrect" + + @pytest.mark.vcr(filter_headers=["authorization"]) def test_before_kickoff_modification(): crew = InternalCrew() diff --git a/uv.lock b/uv.lock index fea201520..7da642db8 100644 --- a/uv.lock +++ b/uv.lock @@ -695,7 +695,7 @@ requires-dist = [ { name = "blinker", specifier = ">=1.9.0" }, { name = "chromadb", specifier = ">=0.5.23" }, { name = "click", specifier = ">=8.1.7" }, - { name = "crewai-tools", marker = "extra == 'tools'", specifier = "~=0.38.0" }, + { name = "crewai-tools", marker = "extra == 'tools'", specifier = "~=0.40.1" }, { name = "docling", marker = "extra == 'docling'", specifier = ">=2.12.0" }, { name = "fastembed", marker = "extra == 'fastembed'", specifier = ">=0.4.1" }, { name = "instructor", specifier = ">=1.3.3" }, @@ -745,7 +745,7 @@ dev = [ [[package]] name = "crewai-tools" -version = "0.38.1" +version = "0.40.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "chromadb" }, @@ -760,9 +760,9 @@ dependencies = [ { name = "pytube" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/85/3f/d3b5697b4c6756cec65316c9ea9ccd9054f7b73670d1580befd3632ba031/crewai_tools-0.38.1.tar.gz", hash = "sha256:6abe75b3b339d53a9cf4e2d80124d863ff62a82b36753c30bec64318881876b2", size = 737620 } +sdist = { url = "https://files.pythonhosted.org/packages/16/ff/0c16c9943ec1501b12fc72aca7815f191ffe94d5f1fe4e9c353ee8c4ad1d/crewai_tools-0.40.1.tar.gz", hash = "sha256:6af5040b2277df8fd592238a17bf584f95dcc9ef7766236534999c8a9e9d0b52", size = 744094 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/2b/a6c9007647ffbb6a3c204b3ef26806030d6b041e3e012d4cec43c21335d6/crewai_tools-0.38.1-py3-none-any.whl", hash = "sha256:d9d3a88060f1f30c8f4ea044f6dd564a50d0a22b8a018a6fcec202b36246b9d8", size = 561414 }, + { url = "https://files.pythonhosted.org/packages/35/05/619c00bae2dda038f0d218dd5197120c938e9c9ccef1b9e50cfb037486f6/crewai_tools-0.40.1-py3-none-any.whl", hash = "sha256:8f459f74dee64364bfdbc524c815c4afcfb9ed532b51e6b8b4f616398d46cf1e", size = 573286 }, ] [[package]]