Files
crewAI/lib/crewai/tests/utilities
João Moura 85c467dfe2
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
feat(cli): run declarative flows on the TUI (headless terminal fallback) (#6484)
* feat(cli): run declarative flows on the TUI with a headless terminal fallback

Declarative flows now run on the CrewRunApp TUI when interactive, matching
declarative crews and conversational flows. Headless contexts — CREWAI_DMN
(deploy), piped output, CI, any non-TTY — fall back to the direct-terminal
kickoff, gated by is_interactive() (folds in the CREWAI_DMN check and requires
a real TTY).

The TUI shows per-method progress: a new STEPS panel driven by flow method
events (FlowStarted / MethodExecutionStarted/Finished/Failed), each labeled
with its declarative call type (crew/agent/expression/…) read from the flow
definition. Crews/agents inside a method keep streaming in the main panel via
the existing crew/task/LLM handlers.

- crew_run_tui.py: _run_flow_worker (flow.kickoff in a thread worker; reuses
  _on_crew_done/_on_crew_failed + _stringify_output), _is_flow_run gate so crew
  rendering is byte-identical, flow-event subscriptions building _flow_steps,
  and the STEPS sidebar + flow-aware header.
- run_declarative_flow.py: is_interactive() branch → _run_declarative_flow_tui
  (EventListener, method-type map from flow._definition, crew-parity exit codes
  and deploy chaining) or the existing terminal path.

Deviation from the approved plan: gate on is_interactive() rather than
is_dmn_mode_enabled() alone, so non-TTY runs (CI/pipes/CliRunner) never launch
a TUI — this also keeps existing headless flow tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh

* fix(cli): force flow events on for the TUI so STEPS renders under suppress_flow_events

Review follow-up: the STEPS panel and header are driven by flow method events
(FlowStarted / MethodExecution*), but the declarative runtime skips emitting
those when the flow declared config.suppress_flow_events. Interactive TUI runs
would then keep STEPS on "waiting…" and the header on "Starting flow…" while
nested crews still execute.

_run_declarative_flow_tui now forces flow.suppress_flow_events = False for the
interactive run (mirroring how the conversational path mutates the flow for the
TUI). The headless/terminal path never reaches this and keeps the flow's
declared setting. Regression test: test_run_declarative_flow_tui_enables_flow_events.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh

* fix(cli): clear flow header's current method when a method ends

Review follow-up: the flow header keys off _current_method, which was set on
MethodExecutionStarted but never cleared on Finished/Failed. Between steps (or
after a failed method before kickoff exits) the header kept spinning the old
method name while the STEPS sidebar already showed it done/failed.

_clear_current_method now drops the header's active method when it ends,
falling back to another still-active step (methods can overlap) or none. The
header's idle fallback shows "Working…" once a step has run and "Starting
flow…" only before the first method.

Tests: test_current_method_clears_and_falls_back_across_overlap, plus a
_current_method assertion in test_flow_method_events_build_steps.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh

* fix: suppress flow console panels in TUI mode; clear header agent on method change

Two review follow-ups:

1) Method panels break Textual TUI (Cursor): forcing suppress_flow_events off
   so the STEPS panel receives events also un-gated the EventListener's Rich
   flow/method panels (ConsoleFormatter.print_panel prints is_flow=True panels
   regardless of verbose), which interleave with Textual and corrupt the TUI.
   print_panel now skips is_flow panels when is_tui_mode() is set (the same
   context the TUI worker already establishes and the tracing listeners already
   honor). Non-TUI/headless flow runs are unaffected. Test:
   test_console_formatter_tui_mode.

2) Flow header showed a stale agent (CodeRabbit): _current_agent persisted
   across methods. It's now cleared when a method starts and when the active
   method changes, so the header never shows the previous method's agent until
   a new agent event arrives. Test: test_flow_method_transitions_clear_current_agent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh

* fix(cli): keep flow name over nested crews; show paused flow methods

Two review follow-ups on the flow TUI:

1) Crew kickoff renamed the flow (Cursor): CrewKickoffStartedEvent overwrote
   _crew_name / the app title with a nested `call: crew` step's crew name, so
   the post-run summary could be labeled with a child crew. The rename is now
   gated on `not _is_flow_run`, preserving the flow's name; crew runs still
   adopt the crew name. Tests: test_crew_kickoff_does_not_rename_flow_run,
   test_crew_kickoff_renames_in_crew_mode.

2) Paused methods showed active (Cursor): the TUI didn't handle
   MethodExecutionPausedEvent, so a @human_feedback pause left the STEPS
   spinner running (flow status panels are suppressed in TUI mode). It now
   marks the step "paused" (⏸, teal) and the header shows "waiting for
   feedback" instead of a spinner. Test: test_method_paused_marks_step_paused.

Note: interactively *providing* human feedback from the flow TUI is a separate
follow-up; this only makes the pause visible instead of a silent stuck spinner.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh

* fix(cli): run human-feedback declarative flows on the terminal, not the TUI

Two review follow-ups, both rooted in @human_feedback methods:

- Paused flow marked complete (Cursor): async human feedback makes kickoff
  RETURN a HumanFeedbackPending marker (not raise), which _run_flow_worker
  would stringify and report as a successful completion with exit 0.
- Sync feedback breaks TUI (Cursor): default (sync) @human_feedback collects
  input via the flow runtime's Rich console.print + blocking input(), which
  interleaves with Textual and leaves the user unable to review output or
  submit feedback.

run_declarative_flow now routes any flow whose declarative definition declares
human feedback (_flow_uses_human_feedback) to the terminal path, where blocking
input and Rich prompts work natively — regardless of interactivity. Non-feedback
flows still get the TUI. Tests: test_flow_uses_human_feedback_detection,
test_human_feedback_flow_uses_terminal_even_when_interactive.

Fully interactive human feedback inside the TUI remains a separate follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh

* refactor(cli): address review — Flow typing, debug logging, flow-vs-crew naming

Review follow-ups from @lucasgomide:

- Type flow helpers as Flow[Any] (via TYPE_CHECKING import) instead of Any and
  drop the defensive getattr chains — _definition is a typed PrivateAttr and
  name/suppress_flow_events are typed fields, so attribute access is safe.
- Replace the silent `except Exception: pass` blocks with logger.debug(...,
  exc_info=True) so unexpected failures are diagnosable in the field
  (_flow_method_types, _flow_uses_human_feedback, suppress_flow_events toggle).
- Flow-vs-crew naming: the flow worker now uses group="flow" (was the
  misleading "crew"), and the shared completion/failure handlers report the
  run with an entity-aware noun ("flow" vs "crew") via _run_noun.

Deferred (separate PR): the os._exit(130) hard-kill on user quit is kept as-is
to match the existing crew convention (run_crew._run_json_crew).

Tests: test_flow_done_uses_flow_wording_for_unfinished_tool; existing crew
wording tests unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RBYGqJHC2TMC6fonFziuuh

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 11:42:12 -03:00
..
2025-10-20 14:10:19 -07:00
2025-10-20 14:10:19 -07:00
2025-10-20 14:10:19 -07:00
2025-10-20 14:10:19 -07:00
2025-10-20 14:10:19 -07:00
2025-10-20 14:10:19 -07:00
2026-06-14 04:19:48 -03:00