diff --git a/src/crewai/project/crew_base.py b/src/crewai/project/crew_base.py index 44871f6a09..82937025e1 100644 --- a/src/crewai/project/crew_base.py +++ b/src/crewai/project/crew_base.py @@ -259,10 +259,14 @@ def _map_task_variables( callback_functions: dict[str, Callable], output_pydantic_functions: dict[str, Callable], ) -> None: + if context_list := task_info.get("context"): - self.tasks_config[task_name]["context"] = [ - tasks[context_task_name]() for context_task_name in context_list - ] + if isinstance(context_list, list): + self.tasks_config[task_name]["context"] = [ + tasks[context_task_name]() for context_task_name in context_list + ] + elif isinstance(context_list,str) and context_list == 'None': + self.tasks_config[task_name]["context"] = None if tools := task_info.get("tools"): self.tasks_config[task_name]["tools"] = [ diff --git a/tests/config/tasks_with_none_context.yaml b/tests/config/tasks_with_none_context.yaml new file mode 100644 index 0000000000..a59b1d77c4 --- /dev/null +++ b/tests/config/tasks_with_none_context.yaml @@ -0,0 +1,19 @@ +research_task: + description: > + Conduct a thorough research about {topic} + Make sure you find any interesting and relevant information given + the current year is 2025. + expected_output: > + A list with 10 bullet points of the most relevant information about {topic} + agent: researcher + guardrail: ensure each bullet contains its source + +reporting_task: + description: > + Review the context you got and expand each topic into a full section for a report. + Make sure the report is detailed and contains any and all relevant information. + expected_output: > + A fully fledge reports with the mains topics, each with a full section of information. + Formatted as markdown without '```' + agent: reporting_analyst + context: None diff --git a/tests/test_project.py b/tests/test_project.py index c6708d92ff..d32b7bfff5 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -107,6 +107,54 @@ def researcher(self): ) # type: ignore[index] +@CrewBase +class CrewWithTaskContextNone: + agents_config = "config/agents.yaml" + tasks_config = "config/tasks_with_none_context.yaml" + + agents: list[BaseAgent] + tasks: list[Task] + + @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"]) # type: ignore[index] + + @agent + def reporting_analyst(self): + return Agent(config=self.agents_config["reporting_analyst"]) # type: ignore[index] + + @task + def research_task(self): + return Task(config=self.tasks_config["research_task"]) # type: ignore[index] + + @task + def reporting_task(self): + return Task(config=self.tasks_config["reporting_task"]) # type: ignore[index] + + @before_kickoff + def modify_inputs(self, inputs): + if inputs: + inputs["topic"] = "Bicycles" + return inputs + + @after_kickoff + def modify_outputs(self, outputs): + outputs.raw = outputs.raw + " post processed" + return outputs + + @crew + def crew(self): + return Crew(agents=self.agents, tasks=self.tasks, verbose=True) + + def test_agent_memoization(): crew = SimpleCrew() first_call_result = crew.simple_agent() @@ -287,3 +335,11 @@ def test_internal_crew_with_mcp(): adapter_mock.assert_called_once_with( {"host": "localhost", "port": 8000}, connect_timeout=120 ) + + +def test_crew_with_task_context_none(): + crew = CrewWithTaskContextNone() + task_with_context_none = crew.reporting_task() + + assert task_with_context_none.context is None + assert task_with_context_none.context != 'None'