Move kickoff callbacks to crew's domain

This commit is contained in:
Gui Vieira
2024-11-20 10:06:49 -03:00
parent 6c29ad29c9
commit d36c3644a6
6 changed files with 82 additions and 565 deletions

View File

@@ -5,7 +5,7 @@ import uuid
import warnings
from concurrent.futures import Future
from hashlib import md5
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union
from pydantic import (
UUID4,
@@ -36,9 +36,7 @@ from crewai.telemetry import Telemetry
from crewai.tools.agent_tools.agent_tools import AgentTools
from crewai.types.usage_metrics import UsageMetrics
from crewai.utilities import I18N, FileHandler, Logger, RPMController
from crewai.utilities.constants import (
TRAINING_DATA_FILE,
)
from crewai.utilities.constants import TRAINING_DATA_FILE
from crewai.utilities.evaluators.crew_evaluator_handler import CrewEvaluator
from crewai.utilities.evaluators.task_evaluator import TaskEvaluator
from crewai.utilities.formatter import (
@@ -165,6 +163,16 @@ class Crew(BaseModel):
default=None,
description="Callback to be executed after each task for all agents execution.",
)
before_kickoff_callbacks: List[
Callable[[Optional[Dict[str, Any]]], Optional[Dict[str, Any]]]
] = Field(
default_factory=list,
description="List of callbacks to be executed before crew kickoff. It may be used to adjust inputs before the crew is executed.",
)
after_kickoff_callbacks: List[Callable[[CrewOutput], CrewOutput]] = Field(
default_factory=list,
description="List of callbacks to be executed after crew kickoff. It may be used to adjust the output of the crew.",
)
max_rpm: Optional[int] = Field(
default=None,
description="Maximum number of requests per minute for the crew execution to be respected.",
@@ -478,6 +486,9 @@ class Crew(BaseModel):
self,
inputs: Optional[Dict[str, Any]] = None,
) -> CrewOutput:
for callback in self.before_kickoff_callbacks:
inputs = callback(inputs)
"""Starts the crew to work on its assigned tasks."""
self._execution_span = self._telemetry.crew_execution_span(self, inputs)
self._task_output_handler.reset()
@@ -520,6 +531,9 @@ class Crew(BaseModel):
f"The process '{self.process}' is not implemented yet."
)
for callback in self.after_kickoff_callbacks:
result = callback(result)
metrics += [agent._token_process.get_summary() for agent in self.agents]
self.usage_metrics = UsageMetrics()

View File

@@ -1,5 +1,7 @@
from .annotations import (
after_kickoff,
agent,
before_kickoff,
cache_handler,
callback,
crew,
@@ -9,8 +11,6 @@ from .annotations import (
pipeline,
task,
tool,
before_crew,
after_crew,
)
from .crew_base import CrewBase
from .pipeline_base import PipelineBase
@@ -28,6 +28,6 @@ __all__ = [
"llm",
"cache_handler",
"pipeline",
"before_crew",
"after_crew",
"before_kickoff",
"after_kickoff",
]

View File

@@ -5,13 +5,13 @@ from crewai import Crew
from crewai.project.utils import memoize
def before_crew(func):
func.is_before_crew = True
def before_kickoff(func):
func.is_before_kickoff = True
return func
def after_crew(func):
func.is_after_crew = True
def after_kickoff(func):
func.is_after_kickoff = True
return func
@@ -109,6 +109,19 @@ def crew(func) -> Callable[..., Crew]:
self.agents = instantiated_agents
self.tasks = instantiated_tasks
return func(self, *args, **kwargs)
crew = func(self, *args, **kwargs)
return wrapper
def callback_wrapper(callback, instance):
def wrapper(*args, **kwargs):
return callback(instance, *args, **kwargs)
return wrapper
for _, callback in self._before_kickoff.items():
crew.before_kickoff_callbacks.append(callback_wrapper(callback, self))
for _, callback in self._after_kickoff.items():
crew.after_kickoff_callbacks.append(callback_wrapper(callback, self))
return crew
return memoize(wrapper)

View File

@@ -43,8 +43,8 @@ def CrewBase(cls: T) -> T:
for attr in [
"is_task",
"is_agent",
"is_before_crew",
"is_after_crew",
"is_before_kickoff",
"is_after_kickoff",
"is_kickoff",
]
)
@@ -57,11 +57,11 @@ def CrewBase(cls: T) -> T:
self._original_agents = self._filter_functions(
self._original_functions, "is_agent"
)
self._before_crew = self._filter_functions(
self._original_functions, "is_before_crew"
self._before_kickoff = self._filter_functions(
self._original_functions, "is_before_kickoff"
)
self._after_crew = self._filter_functions(
self._original_functions, "is_after_crew"
self._after_kickoff = self._filter_functions(
self._original_functions, "is_after_kickoff"
)
self._kickoff = self._filter_functions(
self._original_functions, "is_kickoff"
@@ -213,25 +213,4 @@ def CrewBase(cls: T) -> T:
callback_functions[callback]() for callback in callbacks
]
def kickoff(self, inputs=None):
# Execute before_crew functions and allow them to modify inputs
for _, func in self._before_crew.items():
modified_inputs = func(self, inputs)
if modified_inputs is not None:
inputs = modified_inputs
# Get the crew instance
crew_instance = self.crew()
# Execute the crew's tasks
result = crew_instance.kickoff(inputs=inputs)
# Execute after_crew functions and allow them to modify the output
for _, func in self._after_crew.items():
modified_result = func(self, result)
if modified_result is not None:
result = modified_result
return result
return cast(T, WrappedClass)

View File

@@ -1,450 +0,0 @@
interactions:
- request:
body: !!binary |
CuMOCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSug4KEgoQY3Jld2FpLnRl
bGVtZXRyeRKSDAoQiPNFpMW9CoeJ9Zm3+M0txRIIWLnalHui3g4qDENyZXcgQ3JlYXRlZDABOcAS
H7rirwgYQRBNIbrirwgYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjExLjdKLgoIY3Jld19rZXkSIgogZjM0NmE5YWQ2ZDczMDYzZTA2NzdiMTdjZTlj
NTAxNzdKMQoHY3Jld19pZBImCiQ1MTZhMTZiNi1mMWY2LTRlMzUtYjY3Ni05ZjRiMGY3MTBhZDRK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSqwFCgtjcmV3
X2FnZW50cxKcBQqZBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICI1N2ZhM2QwNC04ZTQ5LTQyMDMtOTg2OS1lNzliMDdiYWJkNGMiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4
X2l0ZXIiOiAyMCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwg
ImxsbSI6ICJncHQtNG8iLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29k
ZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMi
OiBbXX0sIHsia2V5IjogImJiMDY4Mzc3YzE2NDFiZTZkN2Q5N2E1MTY1OWRiNjEzIiwgImlkIjog
ImM5NzA4YTVjLTI4MjEtNDI4Ny05ZDkyLWE3MmU1NWEyMTZlYiIsICJyb2xlIjogInt0b3BpY30g
UmVwb3J0aW5nIEFuYWx5c3RcbiIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4X2l0ZXIiOiAyMCwg
Im1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJncHQt
NG8iLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/
IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpMECgpj
cmV3X3Rhc2tzEoQECoEEW3sia2V5IjogIjZhZmM0YjM5NjI1OWZiYjc2ODFmNTZjNzc1NWNjOTM3
IiwgImlkIjogIjYxOWYxNWFhLTc1NDItNDJiOC04MDZhLWJlNmVhZTQwYmYyMyIsICJhc3luY19l
eGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAi
e3RvcGljfSBTZW5pb3IgRGF0YSBSZXNlYXJjaGVyXG4iLCAiYWdlbnRfa2V5IjogIjczYzM0OWM5
M2MxNjNiNWQ0ZGY5OGE2NGZhYzFjNDMwIiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICJi
MTdiMTg4ZGJmMTRmOTNhOThlNWI5NWFhZDM2NzU3NyIsICJpZCI6ICJhNGIzOGJjYi1jN2Y3LTRk
MTMtYjFiNC00Yzc0ZmE4NzIxOTQiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5f
aW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInt0b3BpY30gUmVwb3J0aW5nIEFuYWx5c3Rc
biIsICJhZ2VudF9rZXkiOiAiYmIwNjgzNzdjMTY0MWJlNmQ3ZDk3YTUxNjU5ZGI2MTMiLCAidG9v
bHNfbmFtZXMiOiBbXX1degIYAYUBAAEAABKOAgoQaSYAFNgUUCxMT0z+KwJCrBIIrjh6pRvY2zEq
DFRhc2sgQ3JlYXRlZDABOag/LbrirwgYQTilLbrirwgYSi4KCGNyZXdfa2V5EiIKIGYzNDZhOWFk
NmQ3MzA2M2UwNjc3YjE3Y2U5YzUwMTc3SjEKB2NyZXdfaWQSJgokNTE2YTE2YjYtZjFmNi00ZTM1
LWI2NzYtOWY0YjBmNzEwYWQ0Si4KCHRhc2tfa2V5EiIKIDZhZmM0YjM5NjI1OWZiYjc2ODFmNTZj
Nzc1NWNjOTM3SjEKB3Rhc2tfaWQSJgokNjE5ZjE1YWEtNzU0Mi00MmI4LTgwNmEtYmU2ZWFlNDBi
ZjIzegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '1894'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Sun, 17 Nov 2024 07:10:46 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are LLMs Senior Data Researcher\n.
You''re a seasoned researcher with a knack for uncovering the latest developments
in LLMs. Known for your ability to find the most relevant information and present
it in a clear and concise manner.\n\nYour personal goal is: Uncover cutting-edge
developments in LLMs\n\nTo give my best complete final answer to the task use
the exact following format:\n\nThought: I now can give a great answer\nFinal
Answer: Your final answer must be the great and the most complete as possible,
it must be outcome described.\n\nI MUST use these formats, my job depends on
it!"}, {"role": "user", "content": "\nCurrent Task: Conduct a thorough research
about LLMs Make sure you find any interesting and relevant information given
the current year is 2024.\n\n\nThis is the expect criteria for your final answer:
A list with 10 bullet points of the most relevant information about LLMs\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nBegin!
This is VERY important to you, use the tools available and give your best Final
Answer, your job depends on it!\n\nThought:"}], "model": "gpt-4o", "stop": ["\nObservation:"],
"stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1235'
content-type:
- application/json
cookie:
- __cf_bm=08pKRcLhS1PDw0mYfL2jz19ac6M.T31GoiMuI5DlX6w-1731827382-1.0.1.1-UfOLu3AaIUuXP1sGzdV6oggJ1q7iMTC46t08FDhYVrKcW5YmD4CbifudOJiSgx8h0JLTwZdgk.aG05S0eAO_PQ;
_cfuvid=74kaPOoAcp8YRSA0XocQ1FFNksu9V0_KiWdQfo7wQuQ-1731827382509-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e3de71c79986217-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Sun, 17 Nov 2024 07:10:50 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '5446'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999713'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_dda88f1d73ab714daf68612f9936d111
status:
code: 200
message: OK
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQyRM1X58vc+Q8vTI/ofl1GBIIY3Nm20DB7JsqDFRhc2sgQ3JlYXRlZDABOZgm
aAvkrwgYQehgagvkrwgYSi4KCGNyZXdfa2V5EiIKIGYzNDZhOWFkNmQ3MzA2M2UwNjc3YjE3Y2U5
YzUwMTc3SjEKB2NyZXdfaWQSJgokNTE2YTE2YjYtZjFmNi00ZTM1LWI2NzYtOWY0YjBmNzEwYWQ0
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokYTRiMzhiY2ItYzdmNy00ZDEzLWIxYjQtNGM3NGZhODcyMTk0egIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Sun, 17 Nov 2024 07:10:51 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are LLMs Reporting Analyst\n.
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.\nYour personal
goal is: Create detailed reports based on LLMs data analysis and research findings\n\nTo
give my best complete final answer to the task use the exact following format:\n\nThought:
I now can give a great answer\nFinal Answer: Your final answer must be the great
and the most complete as possible, it must be outcome described.\n\nI MUST use
these formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent
Task: 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.\n\n\nThis is the expect criteria for your final answer: A fully
fledge reports with the mains topics, each with a full section of information.
Formatted as markdown without ''```''\n\nyou MUST return the actual complete
content as the final answer, not a summary.\n\nThis is the context you''re working
with:\n1. **Advancements in Architectural Design**: In 2024, LLMs have seen
significant improvements in architecture, with models adopting more layered
and complex structures that enhance contextual understanding and prevent degradation
in performance over long text sequences. This has improved accuracy and coherence
in generating human-like text.\n\n2. **Integration with Multimodal Data**: The
latest LLMs have integrated multimodal capabilities, allowing them to process
and generate not just text, but also integrate and interpret images, audio,
and video data. This integration significantly enhances user interaction capabilities
and widens practical applications, particularly in fields such as creative industries
and customer service.\n\n3. **Efficiency and Scalability**: There is a strong
focus on reducing the carbon footprint of training and deploying LLMs. Techniques
such as model distillation and the use of more efficient training processes
are commonplace. Models are also being designed for scalability to better serve
a wide range of applications without requiring extensive computational resources.\n\n4.
**Fine-Tuning and Customization**: The ability to finely tune LLMs for specific
industry or organizational needs has become more advanced. Developers can now
more easily customize these models to align with particular styles, industry
jargon, or brands, enhancing relevance and utility across diverse applications.\n\n5.
**Ethical AI and Safety Measures**: A growing emphasis is placed on ethical
considerations. Frameworks for ensuring fairness, reducing biases, and enhancing
transparency in outputs are being developed. New protocols are in place to predict
and mitigate potential misuses of LLMs to improve trust and reliability.\n\n6.
**Proliferation of Open Source Models**: With the community demanding transparency
and flexibility, many open-source LLMs have been developed to promote research
and innovation. These models provide robust alternatives to commercial counterparts
and enhance collaborative development efforts across the globe.\n\n7. **Emergence
of LLM-Driven Applications**: 2024 has seen a rise in applications based on
LLM technology, including advanced customer service bots, dynamic content creation
tools, and educational software that personalizes learning experiences. This
expands the role of LLMs beyond traditional academic or entertainment purposes.\n\n8.
**Focus on Low-Resource Language Support**: LLMs are becoming more adept at
understanding and generating languages with fewer resources, vastly improving
global accessibility and allowing technology to support a wider array of linguistic
communities. This helps bridge digital divides and promote inclusivity.\n\n9.
**Enhanced Interaction Techniques**: Novel interaction paradigms, such as real-time
adaptations and on-the-fly learning, enable LLMs to adjust tone, complexity,
and content more responsively to user feedback. This leads to more natural,
engaging, and personalized interactions in various interface environments.\n\n10.
**Collaborative Intelligence**: There''s an emerging trend of using LLMs in
collaborative settings where AI assists human decision-making by synthesizing
large datasets to suggest insights and trends. This symbiosis enhances productivity
and innovation in research and business contexts.\n\nBegin! This is VERY important
to you, use the tools available and give your best Final Answer, your job depends
on it!\n\nThought:"}], "model": "gpt-4o", "stop": ["\nObservation:"], "stream":
false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4742'
content-type:
- application/json
cookie:
- __cf_bm=08pKRcLhS1PDw0mYfL2jz19ac6M.T31GoiMuI5DlX6w-1731827382-1.0.1.1-UfOLu3AaIUuXP1sGzdV6oggJ1q7iMTC46t08FDhYVrKcW5YmD4CbifudOJiSgx8h0JLTwZdgk.aG05S0eAO_PQ;
_cfuvid=74kaPOoAcp8YRSA0XocQ1FFNksu9V0_KiWdQfo7wQuQ-1731827382509-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
L4f7OwUCdjevN/8BAAD//wMA9xdqlskdAAA=
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e3de74049116217-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Sun, 17 Nov 2024 07:11:00 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '9414'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29998843'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 2ms
x-request-id:
- req_ffd793f9d60c093888d2483ea4305dd6
status:
code: 200
message: OK
version: 1

View File

@@ -1,10 +1,10 @@
from crewai.agent import Agent
from crewai.project import agent, task, before_crew, after_crew, crew
from crewai.project import CrewBase
from crewai.task import Task
from crewai.crew import Crew
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.task import Task
class SimpleCrew:
@agent
@@ -47,13 +47,13 @@ class TestCrew:
def reporting_task(self):
return Task(config=self.tasks_config["reporting_task"])
@before_crew
@before_kickoff
def modify_inputs(self, inputs):
if inputs:
inputs["topic"] = "Bicycles"
return inputs
@after_crew
@after_kickoff
def modify_outputs(self, outputs):
outputs.raw = outputs.raw + " post processed"
return outputs
@@ -83,6 +83,16 @@ def test_task_memoization():
), "Task memoization is not working as expected"
def test_crew_memoization():
crew = TestCrew()
first_call_result = crew.crew()
second_call_result = crew.crew()
assert (
first_call_result is second_call_result
), "Crew references should point to the same object"
def test_task_name():
simple_task = SimpleCrew().simple_task()
assert (
@@ -96,32 +106,33 @@ def test_task_name():
@pytest.mark.vcr(filter_headers=["authorization"])
def test_before_crew_modification():
def test_before_kickoff_modification():
crew = TestCrew()
inputs = {"topic": "LLMs"}
result = crew.kickoff(inputs=inputs)
print(result.raw)
assert "bicycles" in result.raw, "Before crew function did not modify inputs"
result = crew.crew().kickoff(inputs=inputs)
assert "bicycles" in result.raw, "Before kickoff function did not modify inputs"
@pytest.mark.vcr(filter_headers=["authorization"])
def test_after_crew_modification():
def test_after_kickoff_modification():
crew = TestCrew()
# Assuming the crew execution returns a dict
result = crew.kickoff({"topic": "LLMs"})
result = crew.crew().kickoff({"topic": "LLMs"})
assert "post processed" in result.raw, "After crew function did not modify outputs"
assert (
"post processed" in result.raw
), "After kickoff function did not modify outputs"
@pytest.mark.vcr(filter_headers=["authorization"])
def test_before_crew_with_none_input():
def test_before_kickoff_with_none_input():
crew = TestCrew()
crew.crew().kickoff(None)
# Test should pass without raising exceptions
@pytest.mark.vcr(filter_headers=["authorization"])
def test_multiple_before_after_crew():
def test_multiple_before_after_kickoff():
@CrewBase
class MultipleHooksCrew:
agents_config = "config/agents.yaml"
@@ -143,22 +154,22 @@ def test_multiple_before_after_crew():
def reporting_task(self):
return Task(config=self.tasks_config["reporting_task"])
@before_crew
@before_kickoff
def first_before(self, inputs):
inputs["topic"] = "Bicycles"
return inputs
@before_crew
@before_kickoff
def second_before(self, inputs):
inputs["topic"] = "plants"
return inputs
@after_crew
@after_kickoff
def first_after(self, outputs):
outputs.raw = outputs.raw + " processed first"
return outputs
@after_crew
@after_kickoff
def second_after(self, outputs):
outputs.raw = outputs.raw + " processed second"
return outputs
@@ -168,58 +179,8 @@ def test_multiple_before_after_crew():
return Crew(agents=self.agents, tasks=self.tasks, verbose=True)
crew = MultipleHooksCrew()
result = crew.kickoff({"topic": "LLMs"})
result = crew.crew().kickoff({"topic": "LLMs"})
assert "plants" in result.raw, "First before_crew not executed"
assert "processed first" in result.raw, "First after_crew not executed"
assert "processed second" in result.raw, "Second after_crew not executed"
@pytest.mark.vcr(filter_headers=["authorization"])
def test_crew_execution_order():
execution_order = []
@CrewBase
class OrderTestCrew:
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self):
return Agent(config=self.agents_config["researcher"])
@agent
def reporting_analyst(self):
return Agent(config=self.agents_config["reporting_analyst"])
@task
def research_task(self):
execution_order.append("task")
return Task(config=self.tasks_config["research_task"])
@task
def reporting_task(self):
return Task(config=self.tasks_config["reporting_task"])
@before_crew
def before(self, inputs):
execution_order.append("before")
return inputs
@after_crew
def after(self, outputs):
execution_order.append("after")
return outputs
@crew
def crew(self):
return Crew(agents=self.agents, tasks=self.tasks, verbose=True)
crew = OrderTestCrew()
crew.kickoff({"topic": "LLMs"})
assert execution_order == [
"before",
"task",
"after",
], "Crew execution order is incorrect"
assert "plants" in result.raw, "First before_kickoff not executed"
assert "processed first" in result.raw, "First after_kickoff not executed"
assert "processed second" in result.raw, "Second after_kickoff not executed"