mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-09 17:05:08 +00:00
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
This commit is contained in:
@@ -553,6 +553,48 @@ def test_run_declarative_flow_tui_enables_flow_events(
|
||||
assert flow.suppress_flow_events is False
|
||||
|
||||
|
||||
def test_flow_uses_human_feedback_detection() -> None:
|
||||
hf_flow = SimpleNamespace(
|
||||
_definition=SimpleNamespace(
|
||||
methods={
|
||||
"ask": SimpleNamespace(human_feedback=SimpleNamespace(emit=None)),
|
||||
"plain": SimpleNamespace(human_feedback=None),
|
||||
}
|
||||
)
|
||||
)
|
||||
assert run_declarative_flow_module._flow_uses_human_feedback(hf_flow) is True
|
||||
|
||||
no_hf = SimpleNamespace(
|
||||
_definition=SimpleNamespace(
|
||||
methods={"a": SimpleNamespace(human_feedback=None)}
|
||||
)
|
||||
)
|
||||
assert run_declarative_flow_module._flow_uses_human_feedback(no_hf) is False
|
||||
# No definition → False, no error.
|
||||
assert run_declarative_flow_module._flow_uses_human_feedback(SimpleNamespace()) is False
|
||||
|
||||
|
||||
def test_human_feedback_flow_uses_terminal_even_when_interactive(
|
||||
tmp_path: Path, capsys: pytest.CaptureFixture[str], monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
# A human-feedback flow must run on the terminal (blocking input / Rich
|
||||
# prompts) even in an interactive session, never on the TUI.
|
||||
monkeypatch.setattr(run_declarative_flow_module, "is_interactive", lambda: True)
|
||||
monkeypatch.setattr(
|
||||
run_declarative_flow_module, "_flow_uses_human_feedback", lambda flow: True
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
run_declarative_flow_module,
|
||||
"_run_declarative_flow_tui",
|
||||
lambda *a, **k: pytest.fail("human-feedback flow must run on the terminal"),
|
||||
)
|
||||
path = _write(tmp_path, FLOW_YAML)
|
||||
|
||||
run_declarative_flow_module.run_declarative_flow(str(path), '{"topic":"AI"}')
|
||||
|
||||
assert capsys.readouterr().out == "AI\n"
|
||||
|
||||
|
||||
def test_flow_method_types_from_definition() -> None:
|
||||
flow = SimpleNamespace(
|
||||
_definition=SimpleNamespace(
|
||||
|
||||
Reference in New Issue
Block a user