Remove telemetry and tracing dependencies from Task and Flow classes

- Remove telemetry-related imports and private attributes from Task class
- Remove `_telemetry` attribute from Flow class
- Update event handling to emit events without direct telemetry tracking
- Simplify task and flow execution by removing explicit telemetry spans
- Move telemetry-related event handling to EventListener
This commit is contained in:
Lorenze Jay
2025-02-13 17:54:45 -08:00
parent 00a98cd5c9
commit 184d08e6e7
9 changed files with 1036 additions and 87 deletions

View File

@@ -29,6 +29,7 @@ from crewai.utilities.events import (
FlowStartedEvent, FlowStartedEvent,
MethodExecutionFinishedEvent, MethodExecutionFinishedEvent,
MethodExecutionStartedEvent, MethodExecutionStartedEvent,
FlowCreatedEvent,
) )
from crewai.utilities.events.event_bus import event_bus from crewai.utilities.events.event_bus import event_bus
from crewai.utilities.printer import Printer from crewai.utilities.printer import Printer
@@ -428,7 +429,6 @@ class Flow(Generic[T], metaclass=FlowMeta):
Type parameter T must be either Dict[str, Any] or a subclass of BaseModel.""" Type parameter T must be either Dict[str, Any] or a subclass of BaseModel."""
_telemetry = Telemetry()
_printer = Printer() _printer = Printer()
_start_methods: List[str] = [] _start_methods: List[str] = []
@@ -469,7 +469,13 @@ class Flow(Generic[T], metaclass=FlowMeta):
if kwargs: if kwargs:
self._initialize_state(kwargs) self._initialize_state(kwargs)
self._telemetry.flow_creation_span(self.__class__.__name__) event_bus.emit(
self,
FlowCreatedEvent(
type="flow_created",
flow_name=self.__class__.__name__,
),
)
# Register all flow-related methods # Register all flow-related methods
for method_name in dir(self): for method_name in dir(self):
@@ -759,19 +765,13 @@ class Flow(Generic[T], metaclass=FlowMeta):
if not self._start_methods: if not self._start_methods:
raise ValueError("No start method defined") raise ValueError("No start method defined")
self._telemetry.flow_execution_span(
self.__class__.__name__, list(self._methods.keys())
)
tasks = [ tasks = [
self._execute_start_method(start_method) self._execute_start_method(start_method)
for start_method in self._start_methods for start_method in self._start_methods
] ]
await asyncio.gather(*tasks) await asyncio.gather(*tasks)
print(f"All method outputs: {self._method_outputs}") # Debug log
final_output = self._method_outputs[-1] if self._method_outputs else None final_output = self._method_outputs[-1] if self._method_outputs else None
print("final_output", final_output)
event_bus.emit( event_bus.emit(
self, self,
@@ -1029,8 +1029,8 @@ class Flow(Generic[T], metaclass=FlowMeta):
elif level == "warning": elif level == "warning":
logger.warning(message) logger.warning(message)
def plot(self, filename: str = "crewai_flow") -> None: def plot(self, filename: str = "crewai_flow") -> None:
self._telemetry.flow_plotting_span( Telemetry().flow_plotting_span(
self.__class__.__name__, list(self._methods.keys()) self.__class__.__name__, list(self._methods.keys())
) )
plot_flow(self, filename) plot_flow(self, filename)

View File

@@ -21,7 +21,6 @@ from typing import (
Union, Union,
) )
from opentelemetry.trace import Span
from pydantic import ( from pydantic import (
UUID4, UUID4,
BaseModel, BaseModel,
@@ -36,7 +35,6 @@ from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.tasks.guardrail_result import GuardrailResult from crewai.tasks.guardrail_result import GuardrailResult
from crewai.tasks.output_format import OutputFormat from crewai.tasks.output_format import OutputFormat
from crewai.tasks.task_output import TaskOutput from crewai.tasks.task_output import TaskOutput
from crewai.telemetry.telemetry import Telemetry
from crewai.tools.base_tool import BaseTool from crewai.tools.base_tool import BaseTool
from crewai.utilities.config import process_config from crewai.utilities.config import process_config
from crewai.utilities.converter import Converter, convert_to_model from crewai.utilities.converter import Converter, convert_to_model
@@ -189,8 +187,6 @@ class Task(BaseModel):
) )
return v return v
_telemetry: Telemetry = PrivateAttr(default_factory=Telemetry)
_execution_span: Optional[Span] = PrivateAttr(default=None)
_original_description: Optional[str] = PrivateAttr(default=None) _original_description: Optional[str] = PrivateAttr(default=None)
_original_expected_output: Optional[str] = PrivateAttr(default=None) _original_expected_output: Optional[str] = PrivateAttr(default=None)
_original_output_file: Optional[str] = PrivateAttr(default=None) _original_output_file: Optional[str] = PrivateAttr(default=None)
@@ -363,9 +359,6 @@ class Task(BaseModel):
) )
self.start_time = datetime.datetime.now() self.start_time = datetime.datetime.now()
self._execution_span = self._telemetry.task_started(
crew=agent.crew, task=self
)
self.prompt_context = context self.prompt_context = context
tools = tools or self.tools or [] tools = tools or self.tools or []
@@ -438,29 +431,20 @@ class Task(BaseModel):
if crew and crew.task_callback and crew.task_callback != self.callback: if crew and crew.task_callback and crew.task_callback != self.callback:
crew.task_callback(self.output) crew.task_callback(self.output)
if self._execution_span: if self.output_file:
self._telemetry.task_ended(self._execution_span, self, agent.crew) content = (
self._execution_span = None json_output
if json_output
if self.output_file: else pydantic_output.model_dump_json()
content = ( if pydantic_output
json_output else result
if json_output )
else pydantic_output.model_dump_json() self._save_file(content)
if pydantic_output
else result
)
self._save_file(content)
event_bus.emit(self, TaskCompletedEvent(output=task_output)) event_bus.emit(self, TaskCompletedEvent(output=task_output))
return task_output return task_output
except Exception as e: except Exception as e:
self.end_time = datetime.datetime.now() self.end_time = datetime.datetime.now()
if self._execution_span: event_bus.emit(self, TaskFailedEvent(error=str(e)))
if agent and agent.crew:
self._telemetry.task_ended(self._execution_span, self, agent.crew)
self._execution_span = None
event_bus.emit(self, TaskFailedEvent(task=self, error=str(e)))
raise e # Re-raise the exception after emitting the event raise e # Re-raise the exception after emitting the event
def prompt(self) -> str: def prompt(self) -> str:

View File

@@ -16,6 +16,7 @@ from .agent_events import (
) )
from .task_events import TaskStartedEvent, TaskCompletedEvent, TaskFailedEvent from .task_events import TaskStartedEvent, TaskCompletedEvent, TaskFailedEvent
from .flow_events import ( from .flow_events import (
FlowCreatedEvent,
FlowStartedEvent, FlowStartedEvent,
FlowFinishedEvent, FlowFinishedEvent,
MethodExecutionStartedEvent, MethodExecutionStartedEvent,

View File

@@ -92,4 +92,3 @@ class CrewTestFailedEvent(CrewEvent):
error: str error: str
crew_name: Optional[str] crew_name: Optional[str]
type: str = "crew_test_failed" type: str = "crew_test_failed"

View File

@@ -1,9 +1,7 @@
from re import S
from pydantic import PrivateAttr from pydantic import PrivateAttr
from crewai.telemetry.telemetry import Telemetry from crewai.telemetry.telemetry import Telemetry
from crewai.utilities import Logger from crewai.utilities import Logger
from crewai.utilities.evaluators.task_evaluator import TaskEvaluator
from crewai.utilities.events.base_event_listener import BaseEventListener from crewai.utilities.events.base_event_listener import BaseEventListener
from .agent_events import AgentExecutionCompletedEvent, AgentExecutionStartedEvent from .agent_events import AgentExecutionCompletedEvent, AgentExecutionStartedEvent
@@ -19,12 +17,13 @@ from .crew_events import (
CrewTrainStartedEvent, CrewTrainStartedEvent,
) )
from .flow_events import ( from .flow_events import (
FlowCreatedEvent,
FlowFinishedEvent, FlowFinishedEvent,
FlowStartedEvent, FlowStartedEvent,
MethodExecutionFinishedEvent, MethodExecutionFinishedEvent,
MethodExecutionStartedEvent, MethodExecutionStartedEvent,
) )
from .task_events import TaskCompletedEvent, TaskStartedEvent from .task_events import TaskCompletedEvent, TaskFailedEvent, TaskStartedEvent
class EventListener(BaseEventListener): class EventListener(BaseEventListener):
@@ -120,15 +119,44 @@ class EventListener(BaseEventListener):
event.timestamp, event.timestamp,
color=self.color, color=self.color,
) )
@event_bus.on(TaskStartedEvent)
def on_task_started(source, event: TaskStartedEvent):
source._execution_span = self._telemetry.task_started(
crew=source.agent.crew, task=source
)
context = event.context
self.logger.log(
f"📋 Task started: {source.description} Context: {context}",
event.timestamp,
color=self.color,
)
@event_bus.on(TaskCompletedEvent) @event_bus.on(TaskCompletedEvent)
def on_task_completed(source, event: TaskCompletedEvent): def on_task_completed(source, event: TaskCompletedEvent):
self._telemetry.task_ended(source._execution_span, source, source) if source._execution_span:
self._telemetry.task_ended(source._execution_span, source, source.agent.crew)
self.logger.log( self.logger.log(
f"📋 Task completed: {source.description}", f"📋 Task completed: {source.description}",
event.timestamp, event.timestamp,
color=self.color, color=self.color,
) )
source._execution_span = None
@event_bus.on(TaskFailedEvent)
def on_task_failed(source, event: TaskFailedEvent):
if source._execution_span:
if source.agent and source.agent.crew:
self._telemetry.task_ended(source._execution_span, source, source.agent.crew)
source._execution_span = None
self.logger.log(
f"❌ Task failed: {source.description}",
event.timestamp,
color=self.color,
)
@event_bus.on(AgentExecutionStartedEvent) @event_bus.on(AgentExecutionStartedEvent)
def on_agent_execution_started(source, event: AgentExecutionStartedEvent): def on_agent_execution_started(source, event: AgentExecutionStartedEvent):
@@ -147,8 +175,21 @@ class EventListener(BaseEventListener):
) )
# Flow Events # Flow Events
@event_bus.on(FlowCreatedEvent)
def on_flow_created(source, event: FlowCreatedEvent):
self._telemetry.flow_creation_span(self.__class__.__name__)
self.logger.log(
f"🌊 Flow Created: '{event.flow_name}'",
event.timestamp,
color=self.color,
)
@event_bus.on(FlowStartedEvent) @event_bus.on(FlowStartedEvent)
def on_flow_started(source, event: FlowStartedEvent): def on_flow_started(source, event: FlowStartedEvent):
self._telemetry.flow_execution_span(
source.__class__.__name__, list(source._methods.keys())
)
self.logger.log( self.logger.log(
f"🤖 Flow Started: '{event.flow_name}'", f"🤖 Flow Started: '{event.flow_name}'",
event.timestamp, event.timestamp,

View File

@@ -20,6 +20,13 @@ class FlowStartedEvent(FlowEvent):
type: str = "flow_started" type: str = "flow_started"
class FlowCreatedEvent(FlowEvent):
"""Event emitted when a flow is created"""
flow_name: str
type: str = "flow_created"
class MethodExecutionStartedEvent(FlowEvent): class MethodExecutionStartedEvent(FlowEvent):
"""Event emitted when a flow method starts execution""" """Event emitted when a flow method starts execution"""

View File

@@ -1,5 +1,4 @@
from typing import Any, Optional from typing import Any, Optional
from crewai.utilities.events.crew_events import CrewEvent from crewai.utilities.events.crew_events import CrewEvent
@@ -8,7 +7,6 @@ class TaskStartedEvent(CrewEvent):
type: str = "task_started" type: str = "task_started"
context: Optional[str] context: Optional[str]
model_config = {"arbitrary_types_allowed": True}
@@ -18,12 +16,11 @@ class TaskCompletedEvent(CrewEvent):
output: Any output: Any
type: str = "task_completed" type: str = "task_completed"
model_config = {"arbitrary_types_allowed": True}
class TaskFailedEvent(CrewEvent): class TaskFailedEvent(CrewEvent):
"""Event emitted when a task fails""" """Event emitted when a task fails"""
task: Any
error: str error: str
type: str = "task_failed" type: str = "task_failed"

View File

@@ -1,13 +1,19 @@
interactions: interactions:
- request: - request:
body: '{"messages": [{"role": "system", "content": "You are base_agent. You are body: '{"messages": [{"role": "system", "content": "You are base_agent. You are
a helpful assistant that just says hi\nYour personal goal is: Just say hi\nTo a helpful assistant that just says hi\nYour personal goal is: Just say hi\nYou
give my best complete final answer to the task respond using the exact following ONLY have access to the following tools, and should NEVER make up tools that
format:\n\nThought: I now can give a great answer\nFinal Answer: Your final are not listed here:\n\nTool Name: Say Hi\nTool Arguments: {}\nTool Description:
answer must be the great and the most complete as possible, it must be outcome This tool always raises an error\n\nIMPORTANT: Use the following format in your
described.\n\nI MUST use these formats, my job depends on it!"}, {"role": "user", response:\n\n```\nThought: you should always think about what to do\nAction:
"content": "\nCurrent Task: Just say hi\n\nThis is the expect criteria for your the action to take, only one name of [Say Hi], just the name, exactly as it''s
final answer: hi\nyou MUST return the actual complete content as the final answer, written.\nAction Input: the input to the action, just a simple JSON object,
enclosed in curly braces, using \" to wrap keys and values.\nObservation: the
result of the action\n```\n\nOnce all necessary information is gathered, return
the following format:\n\n```\nThought: I now know the final answer\nFinal Answer:
the final answer to the original input question\n```"}, {"role": "user", "content":
"\nCurrent Task: Just say hi\n\nThis is the expected criteria for your final
answer: hi\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 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": and give your best Final Answer, your job depends on it!\n\nThought:"}], "model":
"gpt-4o-mini", "stop": ["\nObservation:"]}' "gpt-4o-mini", "stop": ["\nObservation:"]}'
@@ -19,9 +25,11 @@ interactions:
connection: connection:
- keep-alive - keep-alive
content-length: content-length:
- '836' - '1303'
content-type: content-type:
- application/json - application/json
cookie:
- _cfuvid=Cl48aI8.jSRja0Pqr6Jrh3mAnigd4rDn6lhGicyjMPY-1738698987673-0.0.1.1-604800000
host: host:
- api.openai.com - api.openai.com
user-agent: user-agent:
@@ -47,20 +55,23 @@ interactions:
method: POST method: POST
uri: https://api.openai.com/v1/chat/completions uri: https://api.openai.com/v1/chat/completions
response: response:
content: "{\n \"id\": \"chatcmpl-Azq6WJmBZbITt0acwjRonlLua3QxT\",\n \"object\": content: "{\n \"id\": \"chatcmpl-B0ceNVvGO3iTja3ZJM0GHPp7fptc6\",\n \"object\":
\"chat.completion\",\n \"created\": 1739301660,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n \"chat.completion\",\n \"created\": 1739488271,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal \"assistant\",\n \"content\": \"```\\nThought: you should always think
Answer: hi\",\n \"refusal\": null\n },\n \"logprobs\": null,\n about what to do\\nAction: Say Hi\\nAction Input: {}\",\n \"refusal\":
\ \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n
161,\n \"completion_tokens\": 12,\n \"total_tokens\": 173,\n \"prompt_tokens_details\": \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 261,\n \"completion_tokens\":
{\n \"cached_tokens\": 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": 22,\n \"total_tokens\": 283,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
{\n \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\": 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\": 0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\":
\"default\",\n \"system_fingerprint\": \"fp_72ed7ab54c\"\n}\n" \"default\",\n \"system_fingerprint\": \"fp_bd83329f63\"\n}\n"
headers: headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY: CF-RAY:
- 9106b311e8c07e25-SJC - 91187efd98829e74-SJC
Connection: Connection:
- keep-alive - keep-alive
Content-Encoding: Content-Encoding:
@@ -68,14 +79,14 @@ interactions:
Content-Type: Content-Type:
- application/json - application/json
Date: Date:
- Tue, 11 Feb 2025 19:21:01 GMT - Thu, 13 Feb 2025 23:11:12 GMT
Server: Server:
- cloudflare - cloudflare
Set-Cookie: Set-Cookie:
- __cf_bm=BkEp5CX4ww8Vwy5oYVZjMyXHy_c9tXdEJGfsQ51m67c-1739301661-1.0.1.1-BUtQpsmDPsq5ZBEmUB.Zw8aq8D3MvPz5U8rR4oa.gsns9S9ve3SPfP8hmpYpSWYYYJPg1KJIBG0OTJwjC9lWkg; - __cf_bm=XgZ48Kh_Np19KQZFMcdhitEO1hYoQQZmGISmqGQyAew-1739488272-1.0.1.1-71ljflXRwwgMFHqNdbWAIPe5U0Svfer60TB92nqmufsvx_NnPNO.ShrjIwdWBpJ6cQIh6szfk6FrIoioemqHgg;
path=/; expires=Tue, 11-Feb-25 19:51:01 GMT; domain=.api.openai.com; HttpOnly; path=/; expires=Thu, 13-Feb-25 23:41:12 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None Secure; SameSite=None
- _cfuvid=4fxBBkCchurossCvL6LwAzMBGrP47yMs0bo0ZMKGz0I-1739301661039-0.0.1.1-604800000; - _cfuvid=eFYG1.FIv9a4z_Uqb0svvrE60EPh73_2qTAnZyFX9lA-1739488272138-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding: Transfer-Encoding:
- chunked - chunked
@@ -85,12 +96,139 @@ interactions:
- X-Request-ID - X-Request-ID
alt-svc: alt-svc:
- h3=":443"; ma=86400 - h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '782'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149999697'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_67df2b150e90b637ec98ad5796dfe71d
http_version: HTTP/1.1
status_code: 200
- request:
body: '{"messages": [{"role": "system", "content": "You are base_agent. You are
a helpful assistant that just says hi\nYour personal goal is: Just say hi\nYou
ONLY have access to the following tools, and should NEVER make up tools that
are not listed here:\n\nTool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error\n\nIMPORTANT: Use the following format in your
response:\n\n```\nThought: you should always think about what to do\nAction:
the action to take, only one name of [Say Hi], just the name, exactly as it''s
written.\nAction Input: the input to the action, just a simple JSON object,
enclosed in curly braces, using \" to wrap keys and values.\nObservation: the
result of the action\n```\n\nOnce all necessary information is gathered, return
the following format:\n\n```\nThought: I now know the final answer\nFinal Answer:
the final answer to the original input question\n```"}, {"role": "user", "content":
"\nCurrent Task: Just say hi\n\nThis is the expected criteria for your final
answer: hi\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:"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}], "model":
"gpt-4o-mini", "stop": ["\nObservation:"]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '2362'
content-type:
- application/json
cookie:
- _cfuvid=eFYG1.FIv9a4z_Uqb0svvrE60EPh73_2qTAnZyFX9lA-1739488272138-0.0.1.1-604800000;
__cf_bm=XgZ48Kh_Np19KQZFMcdhitEO1hYoQQZmGISmqGQyAew-1739488272-1.0.1.1-71ljflXRwwgMFHqNdbWAIPe5U0Svfer60TB92nqmufsvx_NnPNO.ShrjIwdWBpJ6cQIh6szfk6FrIoioemqHgg
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.61.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.61.0
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.8
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-B0ceOtrUJ80V8Li7rmZaP56XCp37M\",\n \"object\":
\"chat.completion\",\n \"created\": 1739488272,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"```\\nThought: you should always think
about what to do\\nAction: Say Hi\\nAction Input: {}\",\n \"refusal\":
null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n
\ }\n ],\n \"usage\": {\n \"prompt_tokens\": 494,\n \"completion_tokens\":
22,\n \"total_tokens\": 516,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\":
\"default\",\n \"system_fingerprint\": \"fp_bd83329f63\"\n}\n"
headers:
CF-RAY:
- 91187f05197b9e74-SJC
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 13 Feb 2025 23:11:12 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
cf-cache-status: cf-cache-status:
- DYNAMIC - DYNAMIC
openai-organization: openai-organization:
- crewai-iuxna1 - crewai-iuxna1
openai-processing-ms: openai-processing-ms:
- '499' - '545'
openai-version: openai-version:
- '2020-10-01' - '2020-10-01'
strict-transport-security: strict-transport-security:
@@ -102,13 +240,765 @@ interactions:
x-ratelimit-remaining-requests: x-ratelimit-remaining-requests:
- '29999' - '29999'
x-ratelimit-remaining-tokens: x-ratelimit-remaining-tokens:
- '149999810' - '149999447'
x-ratelimit-reset-requests: x-ratelimit-reset-requests:
- 2ms - 2ms
x-ratelimit-reset-tokens: x-ratelimit-reset-tokens:
- 0s - 0s
x-request-id: x-request-id:
- req_92c40fec00fb98496f76bdaa7b0842a2 - req_d7c1f2c3bae845e5083c5092852e051f
http_version: HTTP/1.1
status_code: 200
- request:
body: '{"messages": [{"role": "system", "content": "You are base_agent. You are
a helpful assistant that just says hi\nYour personal goal is: Just say hi\nYou
ONLY have access to the following tools, and should NEVER make up tools that
are not listed here:\n\nTool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error\n\nIMPORTANT: Use the following format in your
response:\n\n```\nThought: you should always think about what to do\nAction:
the action to take, only one name of [Say Hi], just the name, exactly as it''s
written.\nAction Input: the input to the action, just a simple JSON object,
enclosed in curly braces, using \" to wrap keys and values.\nObservation: the
result of the action\n```\n\nOnce all necessary information is gathered, return
the following format:\n\n```\nThought: I now know the final answer\nFinal Answer:
the final answer to the original input question\n```"}, {"role": "user", "content":
"\nCurrent Task: Just say hi\n\nThis is the expected criteria for your final
answer: hi\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:"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}], "model":
"gpt-4o-mini", "stop": ["\nObservation:"]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '3421'
content-type:
- application/json
cookie:
- _cfuvid=eFYG1.FIv9a4z_Uqb0svvrE60EPh73_2qTAnZyFX9lA-1739488272138-0.0.1.1-604800000;
__cf_bm=XgZ48Kh_Np19KQZFMcdhitEO1hYoQQZmGISmqGQyAew-1739488272-1.0.1.1-71ljflXRwwgMFHqNdbWAIPe5U0Svfer60TB92nqmufsvx_NnPNO.ShrjIwdWBpJ6cQIh6szfk6FrIoioemqHgg
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.61.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.61.0
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.8
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-B0cePLitBGIhHl5SUU1C8s7cmjIEX\",\n \"object\":
\"chat.completion\",\n \"created\": 1739488273,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"```\\nThought: you should always think
about what to do\\nAction: Say Hi\\nAction Input: {}\",\n \"refusal\":
null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n
\ }\n ],\n \"usage\": {\n \"prompt_tokens\": 727,\n \"completion_tokens\":
22,\n \"total_tokens\": 749,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\":
\"default\",\n \"system_fingerprint\": \"fp_bd83329f63\"\n}\n"
headers:
CF-RAY:
- 91187f098ead9e74-SJC
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 13 Feb 2025 23:11:13 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
cf-cache-status:
- DYNAMIC
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '632'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149999196'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_6c82a00bbf8ab599a6a6cf521cb4bf52
http_version: HTTP/1.1
status_code: 200
- request:
body: '{"messages": [{"role": "system", "content": "You are base_agent. You are
a helpful assistant that just says hi\nYour personal goal is: Just say hi\nYou
ONLY have access to the following tools, and should NEVER make up tools that
are not listed here:\n\nTool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error\n\nIMPORTANT: Use the following format in your
response:\n\n```\nThought: you should always think about what to do\nAction:
the action to take, only one name of [Say Hi], just the name, exactly as it''s
written.\nAction Input: the input to the action, just a simple JSON object,
enclosed in curly braces, using \" to wrap keys and values.\nObservation: the
result of the action\n```\n\nOnce all necessary information is gathered, return
the following format:\n\n```\nThought: I now know the final answer\nFinal Answer:
the final answer to the original input question\n```"}, {"role": "user", "content":
"\nCurrent Task: Just say hi\n\nThis is the expected criteria for your final
answer: hi\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:"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}], "model":
"gpt-4o-mini", "stop": ["\nObservation:"]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4480'
content-type:
- application/json
cookie:
- _cfuvid=eFYG1.FIv9a4z_Uqb0svvrE60EPh73_2qTAnZyFX9lA-1739488272138-0.0.1.1-604800000;
__cf_bm=XgZ48Kh_Np19KQZFMcdhitEO1hYoQQZmGISmqGQyAew-1739488272-1.0.1.1-71ljflXRwwgMFHqNdbWAIPe5U0Svfer60TB92nqmufsvx_NnPNO.ShrjIwdWBpJ6cQIh6szfk6FrIoioemqHgg
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.61.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.61.0
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.8
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-B0cePDnVjWCsyTlSfvSmP1uUWVqJV\",\n \"object\":
\"chat.completion\",\n \"created\": 1739488273,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"```\\nThought: you should always think
about what to do\\nAction: Say Hi\\nAction Input: {}\",\n \"refusal\":
null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n
\ }\n ],\n \"usage\": {\n \"prompt_tokens\": 960,\n \"completion_tokens\":
22,\n \"total_tokens\": 982,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\":
\"default\",\n \"system_fingerprint\": \"fp_bd83329f63\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 91187f0e0bd19e74-SJC
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 13 Feb 2025 23:11:14 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:
- '757'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149998945'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_83956b8df7f7137fec9ae6450f3c9a7b
http_version: HTTP/1.1
status_code: 200
- request:
body: !!binary |
CqIiCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkS+SEKEgoQY3Jld2FpLnRl
bGVtZXRyeRKkBwoQy3yskK/xR1Awm7D0OKZhbxIIH0xxCLM8S5cqDENyZXcgQ3JlYXRlZDABOXBZ
LLZd5yMYQYCpOrZd5yMYShsKDmNyZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjFKGgoOcHl0aG9uX3Zl
cnNpb24SCAoGMy4xMi44Si4KCGNyZXdfa2V5EiIKIGU1ODA3MDFkNTJlYjY1YWZmMjRlZWZlNzhj
NzQ2MjhjSjEKB2NyZXdfaWQSJgokOGQ4NDY3OGYtMDU0NC00MWFiLWIwMjQtMTFkYTRhMTgxNzhj
ShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3
X251bWJlcl9vZl90YXNrcxICGAFKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrRAgoLY3Jl
d19hZ2VudHMSwQIKvgJbeyJrZXkiOiAiYWQxNTMxNjFjNWM1YTg1NmFhMGQwNmIyNDljNGM2NGEi
LCAiaWQiOiAiYWQ5OTg5ZTEtNDY5YS00YmQxLTg0ZjQtZWVlNjZhYTBiMjk3IiwgInJvbGUiOiAi
YmFzZV9hZ2VudCIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4X2l0ZXIiOiAyNSwgIm1heF9ycG0i
OiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJncHQtNG8tbWluaSIs
ICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBm
YWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfV1K/wEKCmNyZXdf
dGFza3MS8AEK7QFbeyJrZXkiOiAiMWIxNWVmMjM5MTViMjc1NWU4OWEwZWMzYjI2YTEzZDIiLCAi
aWQiOiAiNWUyMWIxOTQtMzE5Ni00NDBhLTg3ZTAtMWEyOGJkZjUxMGUzIiwgImFzeW5jX2V4ZWN1
dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJiYXNl
X2FnZW50IiwgImFnZW50X2tleSI6ICJhZDE1MzE2MWM1YzVhODU2YWEwZDA2YjI0OWM0YzY0YSIs
ICJ0b29sc19uYW1lcyI6IFtdfV16AhgBhQEAAQAAEo4CChCvtNCi6SXalRPxb+3e9KHyEggbtBZr
f+eAqioMVGFzayBDcmVhdGVkMAE5oJFLtl3nIxhBkOdLtl3nIxhKLgoIY3Jld19rZXkSIgogZTU4
MDcwMWQ1MmViNjVhZmYyNGVlZmU3OGM3NDYyOGNKMQoHY3Jld19pZBImCiQ4ZDg0Njc4Zi0wNTQ0
LTQxYWItYjAyNC0xMWRhNGExODE3OGNKLgoIdGFza19rZXkSIgogMWIxNWVmMjM5MTViMjc1NWU4
OWEwZWMzYjI2YTEzZDJKMQoHdGFza19pZBImCiQ1ZTIxYjE5NC0zMTk2LTQ0MGEtODdlMC0xYTI4
YmRmNTEwZTN6AhgBhQEAAQAAEqQHChBgHAng7xhBnfS2/GYvkdYbEggsqqZdYq4kICoMQ3JldyBD
cmVhdGVkMAE5MC09t13nIxhBMPdFt13nIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoHMC4xMDAuMUoa
Cg5weXRob25fdmVyc2lvbhIICgYzLjEyLjhKLgoIY3Jld19rZXkSIgogZTU4MDcwMWQ1MmViNjVh
ZmYyNGVlZmU3OGM3NDYyOGNKMQoHY3Jld19pZBImCiRiMDQ0Njk5NC1jNzMxLTQ4MTQtYjQ0Zi04
MGUzNmY0NmVlNjdKHAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkS
AhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUobChVjcmV3X251bWJlcl9vZl9hZ2VudHMS
AhgBStECCgtjcmV3X2FnZW50cxLBAgq+Alt7ImtleSI6ICJhZDE1MzE2MWM1YzVhODU2YWEwZDA2
YjI0OWM0YzY0YSIsICJpZCI6ICJhZDk5ODllMS00NjlhLTRiZDEtODRmNC1lZWU2NmFhMGIyOTci
LCAicm9sZSI6ICJiYXNlX2FnZW50IiwgInZlcmJvc2U/IjogZmFsc2UsICJtYXhfaXRlciI6IDI1
LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdw
dC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhl
Y3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119
XUr/AQoKY3Jld190YXNrcxLwAQrtAVt7ImtleSI6ICIxYjE1ZWYyMzkxNWIyNzU1ZTg5YTBlYzNi
MjZhMTNkMiIsICJpZCI6ICI1ZTIxYjE5NC0zMTk2LTQ0MGEtODdlMC0xYTI4YmRmNTEwZTMiLCAi
YXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2VudF9y
b2xlIjogImJhc2VfYWdlbnQiLCAiYWdlbnRfa2V5IjogImFkMTUzMTYxYzVjNWE4NTZhYTBkMDZi
MjQ5YzRjNjRhIiwgInRvb2xzX25hbWVzIjogW119XXoCGAGFAQABAAASjgIKEPPkDbccpJ9jDuUl
rzqUoqQSCL6irICbXoxyKgxUYXNrIENyZWF0ZWQwATn4sVm3XecjGEGIF1q3XecjGEouCghjcmV3
X2tleRIiCiBlNTgwNzAxZDUyZWI2NWFmZjI0ZWVmZTc4Yzc0NjI4Y0oxCgdjcmV3X2lkEiYKJGIw
NDQ2OTk0LWM3MzEtNDgxNC1iNDRmLTgwZTM2ZjQ2ZWU2N0ouCgh0YXNrX2tleRIiCiAxYjE1ZWYy
MzkxNWIyNzU1ZTg5YTBlYzNiMjZhMTNkMkoxCgd0YXNrX2lkEiYKJDVlMjFiMTk0LTMxOTYtNDQw
YS04N2UwLTFhMjhiZGY1MTBlM3oCGAGFAQABAAASpAcKEOZUZG2c1vI5V6bNLpPk3ygSCIKZQpuE
HMQfKgxDcmV3IENyZWF0ZWQwATlwnAC4XecjGEGQMQq4XecjGEobCg5jcmV3YWlfdmVyc2lvbhIJ
CgcwLjEwMC4xShoKDnB5dGhvbl92ZXJzaW9uEggKBjMuMTIuOEouCghjcmV3X2tleRIiCiBlNTgw
NzAxZDUyZWI2NWFmZjI0ZWVmZTc4Yzc0NjI4Y0oxCgdjcmV3X2lkEiYKJGM2ZGQ0OTYwLTU3ZTMt
NGQ5Mi1iZTQzLTg3OTQ0N2NmZjJjNEocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtj
cmV3X21lbW9yeRICEABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVy
X29mX2FnZW50cxICGAFK0QIKC2NyZXdfYWdlbnRzEsECCr4CW3sia2V5IjogImFkMTUzMTYxYzVj
NWE4NTZhYTBkMDZiMjQ5YzRjNjRhIiwgImlkIjogImFkOTk4OWUxLTQ2OWEtNGJkMS04NGY0LWVl
ZTY2YWEwYjI5NyIsICJyb2xlIjogImJhc2VfYWdlbnQiLCAidmVyYm9zZT8iOiBmYWxzZSwgIm1h
eF9pdGVyIjogMjUsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIs
ICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxs
b3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNf
bmFtZXMiOiBbXX1dSv8BCgpjcmV3X3Rhc2tzEvABCu0BW3sia2V5IjogIjFiMTVlZjIzOTE1YjI3
NTVlODlhMGVjM2IyNmExM2QyIiwgImlkIjogIjVlMjFiMTk0LTMxOTYtNDQwYS04N2UwLTFhMjhi
ZGY1MTBlMyIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxz
ZSwgImFnZW50X3JvbGUiOiAiYmFzZV9hZ2VudCIsICJhZ2VudF9rZXkiOiAiYWQxNTMxNjFjNWM1
YTg1NmFhMGQwNmIyNDljNGM2NGEiLCAidG9vbHNfbmFtZXMiOiBbXX1degIYAYUBAAEAABKOAgoQ
vhlU4CgyTyrgPRf0wlb8eRIIqtS4lWPuJuYqDFRhc2sgQ3JlYXRlZDABOSA9Gbhd5yMYQWiuGbhd
5yMYSi4KCGNyZXdfa2V5EiIKIGU1ODA3MDFkNTJlYjY1YWZmMjRlZWZlNzhjNzQ2MjhjSjEKB2Ny
ZXdfaWQSJgokYzZkZDQ5NjAtNTdlMy00ZDkyLWJlNDMtODc5NDQ3Y2ZmMmM0Si4KCHRhc2tfa2V5
EiIKIDFiMTVlZjIzOTE1YjI3NTVlODlhMGVjM2IyNmExM2QySjEKB3Rhc2tfaWQSJgokNWUyMWIx
OTQtMzE5Ni00NDBhLTg3ZTAtMWEyOGJkZjUxMGUzegIYAYUBAAEAABKOAgoQr7izSc/LzkAmDVE4
TCRtVxIIlEdWL3gr4vAqDFRhc2sgQ3JlYXRlZDABOajMq7hd5yMYQUCErLhd5yMYSi4KCGNyZXdf
a2V5EiIKIGU1ODA3MDFkNTJlYjY1YWZmMjRlZWZlNzhjNzQ2MjhjSjEKB2NyZXdfaWQSJgokYzZk
ZDQ5NjAtNTdlMy00ZDkyLWJlNDMtODc5NDQ3Y2ZmMmM0Si4KCHRhc2tfa2V5EiIKIDFiMTVlZjIz
OTE1YjI3NTVlODlhMGVjM2IyNmExM2QySjEKB3Rhc2tfaWQSJgokYmNhMmRkYmMtZmM4MC00ZTM4
LWE2ZTAtNTU0MmM2OTIzYTE5egIYAYUBAAEAABJpChAW++bDmEo222QymLgbmnOnEggC9Fj1KYqp
iCoQVG9vbCBVc2FnZSBFcnJvcjABOQja5wRe5yMYQdjm+wRe5yMYShsKDmNyZXdhaV92ZXJzaW9u
EgkKBzAuMTAwLjF6AhgBhQEAAQAAEmkKEOeYSHtVxHT42vgh6qJWipASCG4YjIxTPsQrKhBUb29s
IFVzYWdlIEVycm9yMAE58JKtL17nIxhBeEy8L17nIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoHMC4x
MDAuMXoCGAGFAQABAAASaQoQd2xGQ0N0fRjEAZb3m591vhII9yEmZE84dukqEFRvb2wgVXNhZ2Ug
RXJyb3IwATkIXzBaXucjGEHgTEJaXucjGEobCg5jcmV3YWlfdmVyc2lvbhIJCgcwLjEwMC4xegIY
AYUBAAEAABJpChCuKrUoVTHcaqSma3csnzpOEgjdvJJFFn7JYioQVG9vbCBVc2FnZSBFcnJvcjAB
OVjIbJFe5yMYQTgIf5Fe5yMYShsKDmNyZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjF6AhgBhQEAAQAA
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '4389'
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:
- Thu, 13 Feb 2025 23:11:15 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are base_agent. You are
a helpful assistant that just says hi\nYour personal goal is: Just say hi\nYou
ONLY have access to the following tools, and should NEVER make up tools that
are not listed here:\n\nTool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error\n\nIMPORTANT: Use the following format in your
response:\n\n```\nThought: you should always think about what to do\nAction:
the action to take, only one name of [Say Hi], just the name, exactly as it''s
written.\nAction Input: the input to the action, just a simple JSON object,
enclosed in curly braces, using \" to wrap keys and values.\nObservation: the
result of the action\n```\n\nOnce all necessary information is gathered, return
the following format:\n\n```\nThought: I now know the final answer\nFinal Answer:
the final answer to the original input question\n```"}, {"role": "user", "content":
"\nCurrent Task: Just say hi\n\nThis is the expected criteria for your final
answer: hi\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:"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}], "model":
"gpt-4o-mini", "stop": ["\nObservation:"]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '5539'
content-type:
- application/json
cookie:
- _cfuvid=eFYG1.FIv9a4z_Uqb0svvrE60EPh73_2qTAnZyFX9lA-1739488272138-0.0.1.1-604800000;
__cf_bm=XgZ48Kh_Np19KQZFMcdhitEO1hYoQQZmGISmqGQyAew-1739488272-1.0.1.1-71ljflXRwwgMFHqNdbWAIPe5U0Svfer60TB92nqmufsvx_NnPNO.ShrjIwdWBpJ6cQIh6szfk6FrIoioemqHgg
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.61.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.61.0
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.8
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-B0ceQN5mVVSLXPfYhoXL7kYKYC7js\",\n \"object\":
\"chat.completion\",\n \"created\": 1739488274,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"```\\nThought: you should always think
about what to do\\nAction: Say Hi\\nAction Input: {}\",\n \"refusal\":
null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n
\ }\n ],\n \"usage\": {\n \"prompt_tokens\": 1193,\n \"completion_tokens\":
22,\n \"total_tokens\": 1215,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\":
\"default\",\n \"system_fingerprint\": \"fp_bd83329f63\"\n}\n"
headers:
CF-RAY:
- 91187f13fb279e74-SJC
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 13 Feb 2025 23:11:15 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
cf-cache-status:
- DYNAMIC
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '615'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149998695'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_732a192814669f7e2fce3f349a4b1b8d
http_version: HTTP/1.1
status_code: 200
- request:
body: '{"messages": [{"role": "system", "content": "You are base_agent. You are
a helpful assistant that just says hi\nYour personal goal is: Just say hi\nYou
ONLY have access to the following tools, and should NEVER make up tools that
are not listed here:\n\nTool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error\n\nIMPORTANT: Use the following format in your
response:\n\n```\nThought: you should always think about what to do\nAction:
the action to take, only one name of [Say Hi], just the name, exactly as it''s
written.\nAction Input: the input to the action, just a simple JSON object,
enclosed in curly braces, using \" to wrap keys and values.\nObservation: the
result of the action\n```\n\nOnce all necessary information is gathered, return
the following format:\n\n```\nThought: I now know the final answer\nFinal Answer:
the final answer to the original input question\n```"}, {"role": "user", "content":
"\nCurrent Task: Just say hi\n\nThis is the expected criteria for your final
answer: hi\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:"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}, {"role":
"assistant", "content": "```\nThought: you should always think about what to
do\nAction: Say Hi\nAction Input: {}\nObservation: \nI encountered an error
while trying to use the tool. This was the error: Simulated tool error.\n Tool
Say Hi accepts these inputs: Tool Name: Say Hi\nTool Arguments: {}\nTool Description:
This tool always raises an error.\nMoving on then. I MUST either use a tool
(use one at time) OR give my best final answer not both at the same time. When
responding, I must use the following format:\n\n```\nThought: you should always
think about what to do\nAction: the action to take, should be one of [Say Hi]\nAction
Input: the input to the action, dictionary enclosed in curly braces\nObservation:
the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat
N times. Once I know the final answer, I must return the following format:\n\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\n```"}], "model":
"gpt-4o-mini", "stop": ["\nObservation:"]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '6598'
content-type:
- application/json
cookie:
- _cfuvid=eFYG1.FIv9a4z_Uqb0svvrE60EPh73_2qTAnZyFX9lA-1739488272138-0.0.1.1-604800000;
__cf_bm=XgZ48Kh_Np19KQZFMcdhitEO1hYoQQZmGISmqGQyAew-1739488272-1.0.1.1-71ljflXRwwgMFHqNdbWAIPe5U0Svfer60TB92nqmufsvx_NnPNO.ShrjIwdWBpJ6cQIh6szfk6FrIoioemqHgg
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.61.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.61.0
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.8
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-B0ceRVoFzoUPmiO0sOZVNpLbXD41f\",\n \"object\":
\"chat.completion\",\n \"created\": 1739488275,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"```\\nThought: I now know the final answer\\nFinal
Answer: hi\\n```\",\n \"refusal\": null\n },\n \"logprobs\":
null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
1426,\n \"completion_tokens\": 17,\n \"total_tokens\": 1443,\n \"prompt_tokens_details\":
{\n \"cached_tokens\": 1024,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\":
{\n \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\":
\"default\",\n \"system_fingerprint\": \"fp_bd83329f63\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 91187f1b3b1e9e74-SJC
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 13 Feb 2025 23:11:16 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:
- '618'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149998444'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_b12d08242d920f524028f18e6eb2ef1a
http_version: HTTP/1.1 http_version: HTTP/1.1
status_code: 200 status_code: 200
version: 1 version: 1

View File

@@ -23,6 +23,7 @@ from crewai.utilities.events.crew_events import (
from crewai.utilities.events.event_bus import event_bus from crewai.utilities.events.event_bus import event_bus
from crewai.utilities.events.event_types import ToolUsageFinishedEvent from crewai.utilities.events.event_types import ToolUsageFinishedEvent
from crewai.utilities.events.flow_events import ( from crewai.utilities.events.flow_events import (
FlowCreatedEvent,
FlowFinishedEvent, FlowFinishedEvent,
FlowStartedEvent, FlowStartedEvent,
MethodExecutionStartedEvent, MethodExecutionStartedEvent,
@@ -33,6 +34,7 @@ from crewai.utilities.events.task_events import (
TaskStartedEvent, TaskStartedEvent,
) )
from crewai.utilities.events.tool_usage_events import ToolUsageErrorEvent from crewai.utilities.events.tool_usage_events import ToolUsageErrorEvent
from requests.exceptions import RequestException
base_agent = Agent( base_agent = Agent(
role="base_agent", role="base_agent",
@@ -148,27 +150,35 @@ def test_crew_emits_end_task_event():
@pytest.mark.vcr(filter_headers=["authorization"]) @pytest.mark.vcr(filter_headers=["authorization"])
def test_task_emits_failed_event_on_execution_error(): def test_task_emits_failed_event_on_execution_error():
received_events = [] received_events = []
received_sources = []
@event_bus.on(TaskFailedEvent) @event_bus.on(TaskFailedEvent)
def handle_task_failed(source, event): def handle_task_failed(source, event):
received_events.append(event) received_events.append(event)
received_sources.append(source)
with patch.object(Task, "_execute_core",) as mock_execute:
error_message = "Simulated task failure"
mock_execute.side_effect = Exception(error_message)
agent = Agent(
role="base_agent",
goal="Just say hi",
backstory="You are a helpful assistant that just says hi",
)
task = Task(
description="Just say hi",
expected_output="hi",
agent=agent,
)
with pytest.raises(Exception):
agent.execute_task(task=task)
task = Task( assert len(received_events) == 1
description="Just say hi", assert received_sources[0] == task
expected_output="hi", assert received_events[0].error == error_message
agent=None, assert isinstance(received_events[0].timestamp, datetime)
) assert received_events[0].type == "task_failed"
with pytest.raises(Exception) as exc_info:
task._execute_core(agent=None, context=None, tools=None)
assert "has no agent assigned" in str(exc_info.value)
assert len(received_events) == 1
assert received_events[0].task == task
assert "has no agent assigned" in received_events[0].error
assert isinstance(received_events[0].timestamp, datetime)
assert received_events[0].type == "task_failed"
@pytest.mark.vcr(filter_headers=["authorization"]) @pytest.mark.vcr(filter_headers=["authorization"])
@@ -439,3 +449,23 @@ def test_multiple_handlers_for_same_event():
assert len(received_events_2) == 1 assert len(received_events_2) == 1
assert received_events_1[0].type == "crew_kickoff_started" assert received_events_1[0].type == "crew_kickoff_started"
assert received_events_2[0].type == "crew_kickoff_started" assert received_events_2[0].type == "crew_kickoff_started"
def test_flow_emits_created_event():
received_events = []
@event_bus.on(FlowCreatedEvent)
def handle_flow_created(source, event):
received_events.append(event)
class TestFlow(Flow[dict]):
@start()
def begin(self):
return "started"
flow = TestFlow()
flow.kickoff()
assert len(received_events) == 1
assert received_events[0].flow_name == "TestFlow"
assert received_events[0].type == "flow_created"