mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-09-20 18:13:49 +00:00
* fix(flow): a resumed flow must emit flow_started, not only flow_finished _resume_async_body gated FlowStartedEvent behind suppress_flow_events while the matching FlowFinishedEvent a few hundred lines below stayed ungated. A suppressed resume therefore emitted an unpaired finish: a flow that reported finishing without ever having started. That is worse than a missing row - it breaks every started/finished pairing and any duration or funnel built on it, and it removed the resumed leg from telemetry entirely. suppress_flow_events is also the wrong gate for emission. It asks for console quiet: _flow_origin in events/event_listener.py says so explicitly and notes it "can legitimately be set on a caller's own flow", and the listener already honours it at each point where it prints. So a user who set it on their own flow for quiet output silently lost their resumed runs from telemetry. The emit is now unconditional, matching both the kickoff path - which never gated it - and the FlowFinishedEvent it pairs with. The method-execution gates in this function are left alone: _execute_method gates the same events on the same flag, so those are symmetric and intended. Internal flows that set this flag (agent_executor, the memory recall/encoding flows) will now emit a started event when resumed. That is the point, and the is_crewai_internal marker already keeps them out of user-facing flow metrics - a distinction _flow_origin draws precisely because this flag cannot carry it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RfV2uMqWRcdfufMvtdCVoN * fix(flow): emit the whole lifecycle on a suppressed resume, not just the start The first commit on this branch ungated FlowStartedEvent on the resume path while FlowFinishedEvent stayed gated, which left a suppressed resume emitting a start with no terminal event. CodeRabbit and cursor both caught it. The premise that commit was written against was wrong: origin/main gated the started event and the finished event, so it emitted neither and was symmetric. It was the detection that was broken, not the code -- a fixed-line lookback for the enclosing condition missed the multi-line `if (not self.suppress_flow_events and not self._should_defer_trace_finalization()):` guarding the finish. The defect is therefore not an unpaired event on main but a silent one: a resumed run with suppress_flow_events set emits no lifecycle events at all, so it never reaches a listener or the trace exporter and the run is invisible downstream. kickoff_async emits them either way and lets listeners filter, and suppress_flow_events asks for console quiet rather than for telemetry to be dropped, so resume now matches kickoff. _should_defer_trace_finalization() still withholds the finish, which is a real reason: finalize_session_traces() emits it later instead. respect_suppression is deleted rather than left defaulting to False -- the resume call site was its only caller, so nothing passes True any more. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RfV2uMqWRcdfufMvtdCVoN --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>