Compare commits

...

9 Commits

Author SHA1 Message Date
Eduardo Chiarotti
4dc974a813 feat: Add report only for High severity issues 2024-08-15 18:10:04 -03:00
Eduardo Chiarotti
f98bac58cd feat: add useforsecurty false for bandit pipeline 2024-08-15 18:03:21 -03:00
Eduardo Chiarotti
e65e36b81b feat: Add bandit ci pipeline 2024-08-15 17:47:54 -03:00
Rip&Tear
92a77e5cac Merge pull request #1183 from crewAIInc/feature-templates
Feature templates
2024-08-15 11:29:36 +08:00
Rip&Tear
a2922c9ad5 Merge pull request #1182 from crewAIInc/git-temaplates
updated bug report template to yml for more control
2024-08-15 11:28:31 +08:00
Eduardo Chiarotti
9f9b52dd26 fix: Fix planning_llm issue (#1189)
* fix: Fix planning_llm issue

* fix: add poetry.lock updated version

* fix: type checking issues

* fix: tests
2024-08-14 18:54:53 -03:00
theCyberTech
2482c7ab68 Addded feature request template in YAML format
Added config .yml to remove blank template
2024-08-14 15:49:55 +08:00
theCyberTech
7fdabda97e updated bug report template to yml for more control 2024-08-14 15:08:59 +08:00
Eduardo Chiarotti
7306414de7 docs: fix references to annotations (#1176) 2024-08-13 12:58:12 -03:00
14 changed files with 291 additions and 52 deletions

116
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,116 @@
name: Bug report
description: Create a report to help us improve CrewAI
title: "[BUG]"
labels: ["bug"]
assignees: []
body:
- type: textarea
id: description
attributes:
label: Description
description: Provide a clear and concise description of what the bug is.
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to Reproduce
description: Provide a step-by-step process to reproduce the behavior.
placeholder: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
id: screenshots-code
attributes:
label: Screenshots/Code snippets
description: If applicable, add screenshots or code snippets to help explain your problem.
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
description: Select the operating system you're using
options:
- Ubuntu 20.04
- Ubuntu 22.04
- Ubuntu 24.04
- macOS Catalina
- macOS Big Sur
- macOS Monterey
- macOS Ventura
- macOS Sonoma
- Windows 10
- Windows 11
- Other (specify in additional context)
validations:
required: true
- type: dropdown
id: python-version
attributes:
label: Python Version
description: Version of Python your Crew is running on
options:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
validations:
required: true
- type: input
id: crewai-version
attributes:
label: crewAI Version
description: What version of CrewAI are you using
validations:
required: true
- type: input
id: crewai-tools-version
attributes:
label: crewAI Tools Version
description: What version of CrewAI Tools are you using
validations:
required: true
- type: dropdown
id: virtual-environment
attributes:
label: Virtual Environment
description: What Virtual Environment are you running your crew in.
options:
- Venv
- Conda
- Poetry
validations:
required: true
- type: textarea
id: evidence
attributes:
label: Evidence
description: Include relevant information, logs or error messages. These can be screenshots.
validations:
required: true
- type: textarea
id: possible-solution
attributes:
label: Possible Solution
description: Have a solution in mind? Please suggest it here, or write "None".
validations:
required: true
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Add any other context about the problem here.
validations:
required: true

0
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

View File

@@ -0,0 +1,65 @@
name: Feature request
description: Suggest a new feature for CrewAI
title: "[FEATURE]"
labels: ["feature-request"]
assignees: []
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this feature request!
- type: dropdown
id: feature-area
attributes:
label: Feature Area
description: Which area of CrewAI does this feature primarily relate to?
options:
- Core functionality
- Agent capabilities
- Task management
- Integration with external tools
- Performance optimization
- Documentation
- Other (please specify in additional context)
validations:
required: true
- type: textarea
id: problem
attributes:
label: Is your feature request related to a an existing bug? Please link it here.
description: A link to the bug or NA if not related to an existing bug.
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
validations:
required: false
- type: textarea
id: context
attributes:
label: Additional context
description: Add any other context, screenshots, or examples about the feature request here.
validations:
required: false
- type: dropdown
id: willingness-to-contribute
attributes:
label: Willingness to Contribute
description: Would you be willing to contribute to the implementation of this feature?
options:
- Yes, I'd be happy to submit a pull request
- I could provide more detailed specifications
- I can test the feature once it's implemented
- No, I'm just suggesting the idea
validations:
required: true

23
.github/workflows/security-checker.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Security Checker
on: [pull_request]
jobs:
security-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11.9"
- name: Install dependencies
run: pip install bandit
- name: Run Bandit
run: bandit -c pyproject.toml -r src/ -lll

View File

@@ -154,15 +154,15 @@ email_summarizer_task:
Use the annotations to properly reference the agent and task in the crew.py file. Use the annotations to properly reference the agent and task in the crew.py file.
### Annotations include: ### Annotations include:
* @agent * [@agent](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L17)
* @task * [@task](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L4)
* @crew * [@crew](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L69)
* @llm * [@llm](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L23)
* @tool * [@tool](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L39)
* @callback * [@callback](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L44)
* @output_json * [@output_json](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L29)
* @output_pydantic * [@output_pydantic](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L34)
* @cache_handler * [@cache_handler](https://github.com/crewAIInc/crewAI/blob/97d7bfb52ad49a9f04db360e1b6612d98c91971e/src/crewai/project/annotations.py#L49)
crew.py crew.py
```py ```py

61
poetry.lock generated
View File

@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
[[package]] [[package]]
name = "agentops" name = "agentops"
@@ -829,29 +829,27 @@ name = "crewai-tools"
version = "0.8.3" version = "0.8.3"
description = "Set of tools for the crewAI framework" description = "Set of tools for the crewAI framework"
optional = false optional = false
python-versions = ">=3.10,<=3.13" python-versions = "<=3.13,>=3.10"
files = [] files = [
develop = false {file = "crewai_tools-0.8.3-py3-none-any.whl", hash = "sha256:a54a10c36b8403250e13d6594bd37db7e7deb3f9fabc77e8720c081864ae6189"},
{file = "crewai_tools-0.8.3.tar.gz", hash = "sha256:f0317ea1d926221b22fcf4b816d71916fe870aa66ed7ee2a0067dba42b5634eb"},
]
[package.dependencies] [package.dependencies]
beautifulsoup4 = "^4.12.3" beautifulsoup4 = ">=4.12.3,<5.0.0"
chromadb = "^0.4.22" chromadb = ">=0.4.22,<0.5.0"
docker = "^7.1.0" docker = ">=7.1.0,<8.0.0"
docx2txt = "^0.8" docx2txt = ">=0.8,<0.9"
embedchain = "^0.1.114" embedchain = ">=0.1.114,<0.2.0"
lancedb = "^0.5.4" lancedb = ">=0.5.4,<0.6.0"
langchain = ">0.2,<=0.3" langchain = ">0.2,<=0.3"
openai = "^1.12.0" openai = ">=1.12.0,<2.0.0"
pydantic = "^2.6.1" pydantic = ">=2.6.1,<3.0.0"
pyright = "^1.1.350" pyright = ">=1.1.350,<2.0.0"
pytest = "^8.0.0" pytest = ">=8.0.0,<9.0.0"
pytube = "^15.0.0" pytube = ">=15.0.0,<16.0.0"
requests = "^2.31.0" requests = ">=2.31.0,<3.0.0"
selenium = "^4.18.1" selenium = ">=4.18.1,<5.0.0"
[package.source]
type = "directory"
url = "../crewai-tools"
[[package]] [[package]]
name = "cssselect2" name = "cssselect2"
@@ -1321,12 +1319,12 @@ files = [
google-auth = ">=2.14.1,<3.0.dev0" google-auth = ">=2.14.1,<3.0.dev0"
googleapis-common-protos = ">=1.56.2,<2.0.dev0" googleapis-common-protos = ">=1.56.2,<2.0.dev0"
grpcio = [ grpcio = [
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
{version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, {version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
] ]
grpcio-status = [ grpcio-status = [
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
{version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
] ]
proto-plus = ">=1.22.3,<2.0.0dev" proto-plus = ">=1.22.3,<2.0.0dev"
protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0"
@@ -3628,8 +3626,8 @@ files = [
[package.dependencies] [package.dependencies]
numpy = [ numpy = [
{version = ">=1.23.2", markers = "python_version == \"3.11\""},
{version = ">=1.22.4", markers = "python_version < \"3.11\""}, {version = ">=1.22.4", markers = "python_version < \"3.11\""},
{version = ">=1.23.2", markers = "python_version == \"3.11\""},
{version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""},
] ]
python-dateutil = ">=2.8.2" python-dateutil = ">=2.8.2"
@@ -4027,6 +4025,19 @@ files = [
{file = "pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7"}, {file = "pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7"},
{file = "pyarrow-17.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:af5ff82a04b2171415f1410cff7ebb79861afc5dae50be73ce06d6e870615204"}, {file = "pyarrow-17.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:af5ff82a04b2171415f1410cff7ebb79861afc5dae50be73ce06d6e870615204"},
{file = "pyarrow-17.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:edca18eaca89cd6382dfbcff3dd2d87633433043650c07375d095cd3517561d8"}, {file = "pyarrow-17.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:edca18eaca89cd6382dfbcff3dd2d87633433043650c07375d095cd3517561d8"},
{file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c7916bff914ac5d4a8fe25b7a25e432ff921e72f6f2b7547d1e325c1ad9d155"},
{file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f553ca691b9e94b202ff741bdd40f6ccb70cdd5fbf65c187af132f1317de6145"},
{file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:0cdb0e627c86c373205a2f94a510ac4376fdc523f8bb36beab2e7f204416163c"},
{file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:d7d192305d9d8bc9082d10f361fc70a73590a4c65cf31c3e6926cd72b76bc35c"},
{file = "pyarrow-17.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:02dae06ce212d8b3244dd3e7d12d9c4d3046945a5933d28026598e9dbbda1fca"},
{file = "pyarrow-17.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:13d7a460b412f31e4c0efa1148e1d29bdf18ad1411eb6757d38f8fbdcc8645fb"},
{file = "pyarrow-17.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9b564a51fbccfab5a04a80453e5ac6c9954a9c5ef2890d1bcf63741909c3f8df"},
{file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32503827abbc5aadedfa235f5ece8c4f8f8b0a3cf01066bc8d29de7539532687"},
{file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a155acc7f154b9ffcc85497509bcd0d43efb80d6f733b0dc3bb14e281f131c8b"},
{file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:dec8d129254d0188a49f8a1fc99e0560dc1b85f60af729f47de4046015f9b0a5"},
{file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a48ddf5c3c6a6c505904545c25a4ae13646ae1f8ba703c4df4a1bfe4f4006bda"},
{file = "pyarrow-17.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:42bf93249a083aca230ba7e2786c5f673507fa97bbd9725a1e2754715151a204"},
{file = "pyarrow-17.0.0.tar.gz", hash = "sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28"},
] ]
[package.dependencies] [package.dependencies]
@@ -6062,4 +6073,4 @@ tools = ["crewai-tools"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.10,<=3.13" python-versions = ">=3.10,<=3.13"
content-hash = "fc1b510ea9c814db67ac69d2454071b718cb7f6846bd845f7f48561cb0397ce1" content-hash = "91ba982ea96ca7be017d536784223d4ef83e86de05d11eb1c3ce0fc1b726f283"

View File

@@ -62,6 +62,9 @@ ignore_missing_imports = true
disable_error_code = 'import-untyped' disable_error_code = 'import-untyped'
exclude = ["cli/templates"] exclude = ["cli/templates"]
[tool.bandit]
exclude_dirs = ["src/crewai/cli/templates"]
[build-system] [build-system]
requires = ["poetry-core"] requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"

View File

@@ -170,7 +170,7 @@ class BaseAgent(ABC, BaseModel):
@property @property
def key(self): def key(self):
source = [self.role, self.goal, self.backstory] source = [self.role, self.goal, self.backstory]
return md5("|".join(source).encode()).hexdigest() return md5("|".join(source).encode(), usedforsecurity=False).hexdigest()
@abstractmethod @abstractmethod
def execute_task( def execute_task(

View File

@@ -1,9 +1,9 @@
import asyncio import asyncio
import json import json
import os
import uuid import uuid
from concurrent.futures import Future from concurrent.futures import Future
from hashlib import md5 from hashlib import md5
import os
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
@@ -48,11 +48,10 @@ from crewai.utilities.planning_handler import CrewPlanner
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
from crewai.utilities.training_handler import CrewTrainingHandler from crewai.utilities.training_handler import CrewTrainingHandler
agentops = None agentops = None
if os.environ.get("AGENTOPS_API_KEY"): if os.environ.get("AGENTOPS_API_KEY"):
try: try:
import agentops import agentops # type: ignore
except ImportError: except ImportError:
pass pass
@@ -364,7 +363,7 @@ class Crew(BaseModel):
source = [agent.key for agent in self.agents] + [ source = [agent.key for agent in self.agents] + [
task.key for task in self.tasks task.key for task in self.tasks
] ]
return md5("|".join(source).encode()).hexdigest() return md5("|".join(source).encode(), usedforsecurity=False).hexdigest()
def _setup_from_config(self): def _setup_from_config(self):
assert self.config is not None, "Config should not be None." assert self.config is not None, "Config should not be None."
@@ -541,7 +540,7 @@ class Crew(BaseModel):
)._handle_crew_planning() )._handle_crew_planning()
for task, step_plan in zip(self.tasks, result.list_of_plans_per_task): for task, step_plan in zip(self.tasks, result.list_of_plans_per_task):
task.description += step_plan task.description += step_plan.plan
def _store_execution_log( def _store_execution_log(
self, self,

View File

@@ -185,7 +185,7 @@ class Task(BaseModel):
expected_output = self._original_expected_output or self.expected_output expected_output = self._original_expected_output or self.expected_output
source = [description, expected_output] source = [description, expected_output]
return md5("|".join(source).encode()).hexdigest() return md5("|".join(source).encode(), usedforsecurity=False).hexdigest()
def execute_async( def execute_async(
self, self,

View File

@@ -295,7 +295,7 @@ class Telemetry:
pass pass
def individual_test_result_span( def individual_test_result_span(
self, crew: Crew, quality: int, exec_time: int, model_name: str self, crew: Crew, quality: float, exec_time: int, model_name: str
): ):
if self.ready: if self.ready:
try: try:

View File

@@ -1,6 +1,6 @@
import ast import ast
from difflib import SequenceMatcher
import os import os
from difflib import SequenceMatcher
from textwrap import dedent from textwrap import dedent
from typing import Any, List, Union from typing import Any, List, Union
@@ -15,7 +15,7 @@ from crewai.utilities import I18N, Converter, ConverterError, Printer
agentops = None agentops = None
if os.environ.get("AGENTOPS_API_KEY"): if os.environ.get("AGENTOPS_API_KEY"):
try: try:
import agentops import agentops # type: ignore
except ImportError: except ImportError:
pass pass
@@ -118,7 +118,7 @@ class ToolUsage:
tool: BaseTool, tool: BaseTool,
calling: Union[ToolCalling, InstructorToolCalling], calling: Union[ToolCalling, InstructorToolCalling],
) -> str: # TODO: Fix this return type ) -> str: # TODO: Fix this return type
tool_event = agentops.ToolEvent(name=calling.tool_name) if agentops else None tool_event = agentops.ToolEvent(name=calling.tool_name) if agentops else None # type: ignore
if self._check_tool_repeated_usage(calling=calling): # type: ignore # _check_tool_repeated_usage of "ToolUsage" does not return a value (it only ever returns None) if self._check_tool_repeated_usage(calling=calling): # type: ignore # _check_tool_repeated_usage of "ToolUsage" does not return a value (it only ever returns None)
try: try:
result = self._i18n.errors("task_repeated_usage").format( result = self._i18n.errors("task_repeated_usage").format(

View File

@@ -1,14 +1,25 @@
from typing import Any, List, Optional from typing import Any, List, Optional
from langchain_openai import ChatOpenAI from langchain_openai import ChatOpenAI
from pydantic import BaseModel from pydantic import BaseModel, Field
from crewai.agent import Agent from crewai.agent import Agent
from crewai.task import Task from crewai.task import Task
class PlanPerTask(BaseModel):
task: str = Field(..., description="The task for which the plan is created")
plan: str = Field(
...,
description="The step by step plan on how the agents can execute their tasks using the available tools with mastery",
)
class PlannerTaskPydanticOutput(BaseModel): class PlannerTaskPydanticOutput(BaseModel):
list_of_plans_per_task: List[str] list_of_plans_per_task: List[PlanPerTask] = Field(
...,
description="Step by step plan on how the agents can execute their tasks using the available tools with mastery",
)
class CrewPlanner: class CrewPlanner:

View File

@@ -6,7 +6,11 @@ from langchain_openai import ChatOpenAI
from crewai.agent import Agent from crewai.agent import Agent
from crewai.task import Task from crewai.task import Task
from crewai.tasks.task_output import TaskOutput from crewai.tasks.task_output import TaskOutput
from crewai.utilities.planning_handler import CrewPlanner, PlannerTaskPydanticOutput from crewai.utilities.planning_handler import (
CrewPlanner,
PlannerTaskPydanticOutput,
PlanPerTask,
)
class TestCrewPlanner: class TestCrewPlanner:
@@ -44,12 +48,17 @@ class TestCrewPlanner:
return CrewPlanner(tasks, planning_agent_llm) return CrewPlanner(tasks, planning_agent_llm)
def test_handle_crew_planning(self, crew_planner): def test_handle_crew_planning(self, crew_planner):
list_of_plans_per_task = [
PlanPerTask(task="Task1", plan="Plan 1"),
PlanPerTask(task="Task2", plan="Plan 2"),
PlanPerTask(task="Task3", plan="Plan 3"),
]
with patch.object(Task, "execute_sync") as execute: with patch.object(Task, "execute_sync") as execute:
execute.return_value = TaskOutput( execute.return_value = TaskOutput(
description="Description", description="Description",
agent="agent", agent="agent",
pydantic=PlannerTaskPydanticOutput( pydantic=PlannerTaskPydanticOutput(
list_of_plans_per_task=["Plan 1", "Plan 2", "Plan 3"] list_of_plans_per_task=list_of_plans_per_task
), ),
) )
result = crew_planner._handle_crew_planning() result = crew_planner._handle_crew_planning()
@@ -91,7 +100,9 @@ class TestCrewPlanner:
execute.return_value = TaskOutput( execute.return_value = TaskOutput(
description="Description", description="Description",
agent="agent", agent="agent",
pydantic=PlannerTaskPydanticOutput(list_of_plans_per_task=["Plan 1"]), pydantic=PlannerTaskPydanticOutput(
list_of_plans_per_task=[PlanPerTask(task="Task1", plan="Plan 1")]
),
) )
result = crew_planner_different_llm._handle_crew_planning() result = crew_planner_different_llm._handle_crew_planning()