From 59f34d900a06b0bd55ce834afde487f649941786 Mon Sep 17 00:00:00 2001 From: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com> Date: Mon, 28 Apr 2025 23:34:32 +0530 Subject: [PATCH] Fixes missing prompt template or system template (#2408) * Fix issue #2402: Handle missing templates gracefully Co-Authored-By: Joe Moura * Fix import sorting in test files Co-Authored-By: Joe Moura * Bluit in top of devin-ai integration * Fixed test cases * Fixed test cases * fixed linting issue * Added docs --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Joe Moura --- docs/concepts/agents.mdx | 6 ++++- src/crewai/utilities/prompts.py | 12 ++++++--- tests/agent_test.py | 47 ++++++++++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/docs/concepts/agents.mdx b/docs/concepts/agents.mdx index fa954d4fc..4234e6428 100644 --- a/docs/concepts/agents.mdx +++ b/docs/concepts/agents.mdx @@ -255,7 +255,11 @@ custom_agent = Agent( - `response_template`: Formats agent responses -When using custom templates, you can use variables like `{role}`, `{goal}`, and `{input}` in your templates. These will be automatically populated during execution. +When using custom templates, ensure that both `system_template` and `prompt_template` are defined. The `response_template` is optional but recommended for consistent output formatting. + + + +When using custom templates, you can use variables like `{role}`, `{goal}`, and `{backstory}` in your templates. These will be automatically populated during execution. ## Agent Tools diff --git a/src/crewai/utilities/prompts.py b/src/crewai/utilities/prompts.py index 0100f0f07..cd3577874 100644 --- a/src/crewai/utilities/prompts.py +++ b/src/crewai/utilities/prompts.py @@ -54,10 +54,12 @@ class Prompts(BaseModel): response_template=None, ) -> str: """Constructs a prompt string from specified components.""" - if not system_template and not prompt_template: + if not system_template or not prompt_template: + # If any of the required templates are missing, fall back to the default format prompt_parts = [self.i18n.slice(component) for component in components] prompt = "".join(prompt_parts) else: + # All templates are provided, use them prompt_parts = [ self.i18n.slice(component) for component in components @@ -67,8 +69,12 @@ class Prompts(BaseModel): prompt = prompt_template.replace( "{{ .Prompt }}", "".join(self.i18n.slice("task")) ) - response = response_template.split("{{ .Response }}")[0] - prompt = f"{system}\n{prompt}\n{response}" + # Handle missing response_template + if response_template: + response = response_template.split("{{ .Response }}")[0] + prompt = f"{system}\n{prompt}\n{response}" + else: + prompt = f"{system}\n{prompt}" prompt = ( prompt.replace("{goal}", self.agent.goal) diff --git a/tests/agent_test.py b/tests/agent_test.py index 94d68cab2..b3d243a53 100644 --- a/tests/agent_test.py +++ b/tests/agent_test.py @@ -72,9 +72,54 @@ def test_agent_creation(): assert agent.role == "test role" assert agent.goal == "test goal" assert agent.backstory == "test backstory" - assert agent.tools == [] + +def test_agent_with_only_system_template(): + """Test that an agent with only system_template works without errors.""" + agent = Agent( + role="Test Role", + goal="Test Goal", + backstory="Test Backstory", + allow_delegation=False, + system_template="You are a test agent...", + # prompt_template is intentionally missing + ) + + assert agent.role == "Test Role" + assert agent.goal == "Test Goal" + assert agent.backstory == "Test Backstory" + +def test_agent_with_only_prompt_template(): + """Test that an agent with only system_template works without errors.""" + agent = Agent( + role="Test Role", + goal="Test Goal", + backstory="Test Backstory", + allow_delegation=False, + prompt_template="You are a test agent...", + # prompt_template is intentionally missing + ) + + assert agent.role == "Test Role" + assert agent.goal == "Test Goal" + assert agent.backstory == "Test Backstory" +def test_agent_with_missing_response_template(): + """Test that an agent with system_template and prompt_template but no response_template works without errors.""" + agent = Agent( + role="Test Role", + goal="Test Goal", + backstory="Test Backstory", + allow_delegation=False, + system_template="You are a test agent...", + prompt_template="This is a test prompt...", + # response_template is intentionally missing + ) + + assert agent.role == "Test Role" + assert agent.goal == "Test Goal" + assert agent.backstory == "Test Backstory" + def test_agent_default_values(): agent = Agent(role="test role", goal="test goal", backstory="test backstory") assert agent.llm.model == "gpt-4o-mini"