Repository: crewAIInc/crewAI
Pull request #2865 (2025-05-20 05:40:21)

Add markdown attribute to Task class
# Add markdown attribute to Task class

This PR adds a new boolean attribute to the Task class called `markdown` that, when set to True, will automatically inject instructions into the task prompt to return the final answer formatted in Markdown.

## Changes
- Added `markdown` boolean attribute to the Task class with default=False
- Modified the `prompt()` method to include markdown formatting instructions when markdown=True
- Added a test to verify that when markdown=True, the prompt includes the markdown formatting instructions

## Example Usage
```python
task = Task(
    description="Research advances in AI",
    expected_output="A comprehensive summary",
    markdown=True,
    agent=researcher
)
```

This will include an instruction in the prompt telling the agent to format its final answer in Markdown.

## Testing
- Added new test file: test_markdown_task.py with two test cases:
  - test_markdown_option_in_task_prompt
  - test_markdown_option_not_in_task_prompt_by_default

Note: There's a conflict between pytest-recording and pytest-vcr in the test environment that prevented running the tests locally. The implementation follows the existing patterns in the codebase and should work correctly once the environment issue is resolved.

Link to Devin run: https://app.devin.ai/sessions/4a9dee4334a74a16bb3b44d859a5461c
Requested by: Joe Moura (joao@crewai.com)



Patch:
diff --git a/src/crewai/task.py b/src/crewai/task.py
index 754fab49..96e52cad 100644
--- a/src/crewai/task.py
+++ b/src/crewai/task.py
@@ -135,6 +135,10 @@ class Task(BaseModel):
         description="Whether the task should have a human review the final answer of the agent",
         default=False,
     )
+    markdown: Optional[bool] = Field(
+        description="Whether the task should instruct the agent to return the final answer formatted in Markdown",
+        default=False,
+    )
     converter_cls: Optional[Type[Converter]] = Field(
         description="A converter class used to export structured output",
         default=None,
@@ -522,10 +526,14 @@ class Task(BaseModel):
         return guardrail_result
 
     def prompt(self) -> str:
-        """Prompt the task.
-
+        """Generates the task prompt with optional markdown formatting.
+        
+        When the markdown attribute is True, instructions for formatting the
+        response in Markdown syntax will be added to the prompt.
+        
         Returns:
-            Prompt of the task.
+            str: The formatted prompt string containing the task description,
+                 expected output, and optional markdown formatting instructions.
         """
         tasks_slices = [self.description]
 
@@ -533,6 +541,17 @@ class Task(BaseModel):
             expected_output=self.expected_output
         )
         tasks_slices = [self.description, output]
+        
+        if self.markdown:
+            markdown_instruction = """Your final answer MUST be formatted in Markdown syntax.
+Follow these guidelines:
+- Use # for headers
+- Use ** for bold text
+- Use * for italic text
+- Use - or * for bullet points
+- Use `code` for inline code
+- Use ```language for code blocks"""
+            tasks_slices.append(markdown_instruction)
         return "\n".join(tasks_slices)
 
     def interpolate_inputs_and_add_conversation_history(


Test patch:
diff --git a/tests/test_markdown_task.py b/tests/test_markdown_task.py
new file mode 100644
index 00000000..873d1855
--- /dev/null
+++ b/tests/test_markdown_task.py
@@ -0,0 +1,96 @@
+"""Test the markdown attribute in Task class."""
+
+import pytest
+from pydantic import BaseModel
+
+from crewai import Agent, Task
+
+
+@pytest.mark.parametrize(
+    "markdown_enabled,should_contain_instructions",
+    [
+        (True, True),
+        (False, False),
+    ],
+)
+def test_markdown_option_in_task_prompt(markdown_enabled, should_contain_instructions):
+    """Test that markdown flag correctly controls the inclusion of markdown formatting instructions."""
+    
+    researcher = Agent(
+        role="Researcher",
+        goal="Research a topic",
+        backstory="You're a researcher specialized in providing well-formatted content.",
+        allow_delegation=False,
+    )
+
+    task = Task(
+        description="Research advances in AI in 2023",
+        expected_output="A summary of key AI advances in 2023",
+        markdown=markdown_enabled,
+        agent=researcher,
+    )
+
+    prompt = task.prompt()
+    
+    assert "Research advances in AI in 2023" in prompt
+    assert "A summary of key AI advances in 2023" in prompt
+    
+    if should_contain_instructions:
+        assert "Your final answer MUST be formatted in Markdown syntax." in prompt
+        assert "Use # for headers" in prompt
+        assert "Use ** for bold text" in prompt
+    else:
+        assert "Your final answer MUST be formatted in Markdown syntax." not in prompt
+
+
+def test_markdown_with_empty_description():
+    """Test markdown formatting with empty description."""
+    
+    researcher = Agent(
+        role="Researcher",
+        goal="Research a topic",
+        backstory="You're a researcher.",
+        allow_delegation=False,
+    )
+
+    task = Task(
+        description="",
+        expected_output="A summary",
+        markdown=True,
+        agent=researcher,
+    )
+
+    prompt = task.prompt()
+    
+    assert prompt.strip() != ""
+    assert "A summary" in prompt
+    assert "Your final answer MUST be formatted in Markdown syntax." in prompt
+
+
+def test_markdown_with_complex_output_format():
+    """Test markdown with JSON output format to ensure compatibility."""
+    
+    class ResearchOutput(BaseModel):
+        title: str
+        findings: list[str]
+    
+    researcher = Agent(
+        role="Researcher",
+        goal="Research a topic",
+        backstory="You're a researcher.",
+        allow_delegation=False,
+    )
+
+    task = Task(
+        description="Research topic",
+        expected_output="Research results",
+        markdown=True,
+        output_json=ResearchOutput,
+        agent=researcher,
+    )
+
+    prompt = task.prompt()
+    
+    assert "Your final answer MUST be formatted in Markdown syntax." in prompt
+    assert "Research topic" in prompt
+    assert "Research results" in prompt