Skip to content

fix(agents): show final result before human feedback when not verbose#6189

Open
HumphreySun98 wants to merge 1 commit into
crewAIInc:mainfrom
HumphreySun98:fix/human-input-show-result-non-verbose
Open

fix(agents): show final result before human feedback when not verbose#6189
HumphreySun98 wants to merge 1 commit into
crewAIInc:mainfrom
HumphreySun98:fix/human-input-show-result-non-verbose

Conversation

@HumphreySun98

@HumphreySun98 HumphreySun98 commented Jun 16, 2026

Copy link
Copy Markdown

Problem

When a Task has human_input=True but neither the agent nor the crew is verbose, CrewAI shows the 💬 Human Feedback Required panel — "Provide feedback on the Final Result above" — but the result is never printed. The two behaviours are gated independently:

  • the result render (AgentLogsExecutionEvent, and streaming) is gated on verbose;
  • the feedback prompt fires whenever human_input=True.

So a non-verbose human-in-the-loop run asks the operator to approve output they cannot see.

Fix

Render the result through the existing console formatter (handle_agent_logs_execution) right before each feedback prompt when verbose is off — reusing the existing rendering path rather than an ad-hoc print. Covers both the sync and async providers and every feedback round. It is a no-op when verbose, to avoid a duplicate panel.

Tests

Added lib/crewai/tests/core/providers/test_human_input.py asserting the result is rendered before the prompt when not verbose, and not re-rendered when verbose. Verified failing-without/passing-with the fix; ruff and mypy clean.

Fixes #6072


This PR was authored with Claude Code. Per CONTRIBUTING.md, AI-generated contributions require the llm-generated label — I don't have triage permission to set it, so could a maintainer please add it? 🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Ensured agent execution results are displayed before prompting operators for feedback when not in verbose mode, preventing feedback requests on hidden output.
  • Tests

    • Added regression tests to verify result display ordering and prevent duplicate rendering during feedback cycles.

…verbose

With human_input=True the feedback panel asks the operator to review "the
Final Result above", but the result is only rendered when the agent or crew
runs verbose (AgentLogsExecutionEvent and streaming are both verbose-gated).
So a non-verbose human-in-the-loop run prompts the operator to approve output
that was never displayed.

Render the result through the existing console formatter before each feedback
prompt when verbose is off, covering both the sync and async paths and every
feedback round. No-op when verbose to avoid a duplicate panel.

Fixes crewAIInc#6072

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a _ensure_result_displayed static helper to SyncHumanInputProvider that conditionally renders the agent's final result via the event listener formatter when neither the agent nor crew is in verbose mode. The helper is called before the feedback prompt in handle_feedback, handle_feedback_async, and within both sync and async re-run loops. A new regression test module verifies the ordering and deduplication behavior.

Changes

Result display guard before human feedback prompt

Layer / File(s) Summary
_ensure_result_displayed helper and call sites
lib/crewai/src/crewai/core/providers/human_input.py
Adds static _ensure_result_displayed(answer, context) that checks agent.verbose/crew.verbose and calls event_listener.formatter.handle_agent_logs_execution(..., verbose=True) when verbose is off; inserts calls at all four feedback prompt sites — handle_feedback, handle_feedback_async, and both sync/async re-run loop bodies.
Regression tests
lib/crewai/tests/core/providers/test_human_input.py
New test module with _FakeAgent, _FakeCrew, _FakeContext, and _answer() stubs; two tests verify that handle_agent_logs_execution is invoked before console.print when not verbose, and is skipped entirely when the crew is verbose.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: displaying the final result before human feedback when not in verbose mode.
Linked Issues check ✅ Passed The PR fully addresses issue #6072 by rendering the result before feedback prompts in non-verbose mode and skipping re-rendering in verbose mode.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the human input feedback mechanism and its tests; no unrelated modifications are present.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/crewai/tests/core/providers/test_human_input.py (1)

41-82: ⚡ Quick win

Add async-path regression coverage for the new display hook.

These tests validate the sync path, but this PR also changes async entry/loop paths. Please add async parity tests so ordering and dedup behavior are protected there too.

Suggested test additions
+from unittest.mock import AsyncMock
+import asyncio
...
+    def test_result_shown_before_prompt_async_when_not_verbose(self) -> None:
+        provider = SyncHumanInputProvider()
+        context = _FakeContext(_FakeAgent(verbose=False), _FakeCrew(verbose=False))
+        answer = _answer()
+
+        formatter = MagicMock()
+        with (
+            patch.object(event_listener, "formatter", formatter),
+            patch(
+                "crewai.core.providers.human_input._async_readline",
+                new=AsyncMock(return_value=""),
+            ),
+        ):
+            result = asyncio.run(provider.handle_feedback_async(answer, context))  # type: ignore[arg-type]
+
+        formatter.handle_agent_logs_execution.assert_called_once_with(
+            "Researcher", answer, verbose=True
+        )
+        method_calls = [c[0] for c in formatter.mock_calls]
+        assert method_calls.index("handle_agent_logs_execution") < method_calls.index("console.print")
+        assert result is answer
+
+    def test_result_not_reshown_async_when_verbose(self) -> None:
+        provider = SyncHumanInputProvider()
+        context = _FakeContext(_FakeAgent(verbose=False), _FakeCrew(verbose=True))
+
+        formatter = MagicMock()
+        with (
+            patch.object(event_listener, "formatter", formatter),
+            patch(
+                "crewai.core.providers.human_input._async_readline",
+                new=AsyncMock(return_value=""),
+            ),
+        ):
+            asyncio.run(provider.handle_feedback_async(_answer(), context))  # type: ignore[arg-type]
+
+        formatter.handle_agent_logs_execution.assert_not_called()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/tests/core/providers/test_human_input.py` around lines 41 - 82,
Add async parity tests to cover the async code paths in the human input
provider, similar to the existing sync tests in TestResultDisplayBeforeFeedback.
Create async test methods (using async def and pytest.mark.asyncio or similar)
that mirror test_result_shown_before_prompt_when_not_verbose and
test_result_not_reshown_when_verbose by testing the async entry/loop paths of
SyncHumanInputProvider or its async equivalent, ensuring the same ordering
behavior (result displayed before feedback prompt) and deduplication behavior
(no re-render when verbose) are validated for both synchronous and asynchronous
execution paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/crewai/tests/core/providers/test_human_input.py`:
- Around line 41-82: Add async parity tests to cover the async code paths in the
human input provider, similar to the existing sync tests in
TestResultDisplayBeforeFeedback. Create async test methods (using async def and
pytest.mark.asyncio or similar) that mirror
test_result_shown_before_prompt_when_not_verbose and
test_result_not_reshown_when_verbose by testing the async entry/loop paths of
SyncHumanInputProvider or its async equivalent, ensuring the same ordering
behavior (result displayed before feedback prompt) and deduplication behavior
(no re-render when verbose) are validated for both synchronous and asynchronous
execution paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ff177527-8ce0-4a7d-85c9-b6cb730060ca

📥 Commits

Reviewing files that changed from the base of the PR and between e9d568d and ffa5f20.

📒 Files selected for processing (4)
  • lib/crewai/src/crewai/core/providers/human_input.py
  • lib/crewai/tests/core/__init__.py
  • lib/crewai/tests/core/providers/__init__.py
  • lib/crewai/tests/core/providers/test_human_input.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] human_input=True: the feedback prompt references a "Final Result above" that is never displayed unless verbose=True

1 participant