mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-08 15:48:29 +00:00
Add inject_date flag to Agent for automatic date injection (#2870)
* feat: Add inject_date flag to Agent for automatic date injection Co-Authored-By: Joe Moura <joao@crewai.com> * feat: Add date_format parameter and error handling to inject_date feature Co-Authored-By: Joe Moura <joao@crewai.com> * fix: Update test implementation for inject_date feature Co-Authored-By: Joe Moura <joao@crewai.com> * fix: Add date format validation to prevent invalid formats Co-Authored-By: Joe Moura <joao@crewai.com> * docs: Update documentation for inject_date feature Co-Authored-By: Joe Moura <joao@crewai.com> * unnecesary * new tests --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Joe Moura <joao@crewai.com> Co-authored-by: João Moura <joaomdmoura@gmail.com>
This commit is contained in:
committed by
GitHub
parent
9945da7dbe
commit
c1672613bc
File diff suppressed because one or more lines are too long
227
tests/cassettes/test_inject_date.yaml
Normal file
227
tests/cassettes/test_inject_date.yaml
Normal file
File diff suppressed because one or more lines are too long
232
tests/cassettes/test_inject_date_custom_format.yaml
Normal file
232
tests/cassettes/test_inject_date_custom_format.yaml
Normal file
File diff suppressed because one or more lines are too long
226
tests/cassettes/test_no_inject_date.yaml
Normal file
226
tests/cassettes/test_no_inject_date.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -78,4 +78,134 @@ interactions:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "system", "content": "You are Researcher. You''re
|
||||
an expert researcher, specialized in technology, software engineering, AI and
|
||||
startups. You work as a freelancer and are now working on doing research and
|
||||
analysis for a new customer.\nYour personal goal is: Make the best research
|
||||
and analysis on content about AI and AI agents. Use the tool provided to you.\nYou
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nTool Name: what amazing tool\nTool Arguments: {}\nTool
|
||||
Description: My tool\n\nIMPORTANT: Use the following format in your response:\n\n```\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [what amazing tool], just the name, exactly as it''s written.\nAction
|
||||
Input: the input to the action, just a simple JSON object, enclosed in curly
|
||||
braces, using \" to wrap keys and values.\nObservation: the result of the action\n```\n\nOnce
|
||||
all necessary information is gathered, return the following format:\n\n```\nThought:
|
||||
I now know the final answer\nFinal Answer: the final answer to the original
|
||||
input question\n```"}, {"role": "user", "content": "\nCurrent Task: Give me
|
||||
a list of 5 interesting ideas to explore for an article, what makes them unique
|
||||
and interesting.\n\nThis is the expected criteria for your final answer: Bullet
|
||||
point list of 5 interesting ideas.\nyou MUST return the actual complete content
|
||||
as the final answer, not a summary.\n\nBegin! This is VERY important to you,
|
||||
use the tools available and give your best Final Answer, your job depends on
|
||||
it!\n\nThought:"}], "model": "gpt-4o-mini", "stop": ["\nObservation:"]}'
|
||||
headers:
|
||||
accept:
|
||||
- application/json
|
||||
accept-encoding:
|
||||
- gzip, deflate
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '1666'
|
||||
content-type:
|
||||
- application/json
|
||||
cookie:
|
||||
- _cfuvid=CW_cKQGYWY3cL.S6Xo5z0cmkmWHy5Q50OA_KjPEijNk-1735926034530-0.0.1.1-604800000
|
||||
host:
|
||||
- api.openai.com
|
||||
user-agent:
|
||||
- OpenAI/Python 1.68.2
|
||||
x-stainless-arch:
|
||||
- arm64
|
||||
x-stainless-async:
|
||||
- 'false'
|
||||
x-stainless-lang:
|
||||
- python
|
||||
x-stainless-os:
|
||||
- MacOS
|
||||
x-stainless-package-version:
|
||||
- 1.68.2
|
||||
x-stainless-raw-response:
|
||||
- 'true'
|
||||
x-stainless-read-timeout:
|
||||
- '600.0'
|
||||
x-stainless-retry-count:
|
||||
- '0'
|
||||
x-stainless-runtime:
|
||||
- CPython
|
||||
x-stainless-runtime-version:
|
||||
- 3.11.7
|
||||
method: POST
|
||||
uri: https://api.openai.com/v1/chat/completions
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAwAAAP//jJNPb9swDMXv+RSELrskRZukSZNbBxRbUWwYdhmwtTAYiba5ypQn0f2z
|
||||
It+9kNPW6dYBu9iAfnzP5BP9MAIw7MwajK1RbdP6yfvvG7r79PnDxYK/LPni5uO35uxstfp6fTvz
|
||||
1oyzImx+ktVn1YENTetJOcgO20iolF2PlvPlyfR4NZ/1oAmOfJZVrU7mYdKw8GR6OJ1PDpeTo5Mn
|
||||
dR3YUjJr+DECAHjon7lPcXRn1nA4fj5pKCWsyKxfigBMDD6fGEyJk6KoGQ/QBlGSvvVzECIHGqAi
|
||||
oYhKgOA5KYQSWJQiJWWpAKOy9QTsCBNE8nm4rDs9BxTXvyoSTWMog+1S1gQBrYkjdMK/OhJKqa+N
|
||||
5OkGxRKwgAaH9+8SKNlagg8VW/TgUVyy2NLBpVzKqc25ruG2RgVs8Hd21xA8wDOEc2k7XcPDFmB/
|
||||
1khllzDnLZ33ewBFgmKW9ilfPZHtS64+VG0Mm/SH1JQsnOoiEqYgOcOkoTU93Y4Arvr7615diWlj
|
||||
aFotNFxT/7nZdLHzM8PaDHR+9AQ1KPo91WI5fsOvcKTIPu1tgLFoa3KDdFgX7ByHPTDam/rvbt7y
|
||||
3k3OUv2P/QCspVbJFW0kx/b1xENZpPxX/avsJeW+YZMo3rClQplivglHJXZ+t+sm3SelpihZKopt
|
||||
5N3Cl21xPKfNfOMWq5kZbUePAAAA//8DALOFcXD+AwAA
|
||||
headers:
|
||||
CF-RAY:
|
||||
- 9433a372ec1069e6-LAS
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Wed, 21 May 2025 11:12:24 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Set-Cookie:
|
||||
- __cf_bm=SC.7rKr584CqggyyZVMEQ5_zFD.g4Q5djrKS1Kg2ifs-1747825944-1.0.1.1-M3vY0AX_JtRWZBGWsq8v4VWUTYLoQRB5_X2WbagS7emC73L80mIv3OUlMwPOwh7ag8LdkVtbkQ_hpAdM9kVJ_wyV7mhTNCoCPLE._sZWMeI;
|
||||
path=/; expires=Wed, 21-May-25 11:42:24 GMT; domain=.api.openai.com; HttpOnly;
|
||||
Secure; SameSite=None
|
||||
- _cfuvid=LMbhtXYRu2foKMlmDSxZF0LlpAWtafPdjq_4PWulGz0-1747825944424-0.0.1.1-604800000;
|
||||
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
access-control-expose-headers:
|
||||
- X-Request-ID
|
||||
alt-svc:
|
||||
- h3=":443"; ma=86400
|
||||
cf-cache-status:
|
||||
- DYNAMIC
|
||||
openai-organization:
|
||||
- crewai-iuxna1
|
||||
openai-processing-ms:
|
||||
- '819'
|
||||
openai-version:
|
||||
- '2020-10-01'
|
||||
strict-transport-security:
|
||||
- max-age=31536000; includeSubDomains; preload
|
||||
x-envoy-upstream-service-time:
|
||||
- '827'
|
||||
x-ratelimit-limit-requests:
|
||||
- '30000'
|
||||
x-ratelimit-limit-tokens:
|
||||
- '150000000'
|
||||
x-ratelimit-remaining-requests:
|
||||
- '29999'
|
||||
x-ratelimit-remaining-tokens:
|
||||
- '149999620'
|
||||
x-ratelimit-reset-requests:
|
||||
- 2ms
|
||||
x-ratelimit-reset-tokens:
|
||||
- 0s
|
||||
x-request-id:
|
||||
- req_93e3b862779b855ab166d171911fa9e0
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
|
||||
@@ -46,4 +46,6 @@ def setup_test_environment():
|
||||
def vcr_config(request) -> dict:
|
||||
return {
|
||||
"cassette_library_dir": "tests/cassettes",
|
||||
"record_mode": "new_episodes",
|
||||
"filter_headers": [("authorization", "AUTHORIZATION-XXX")],
|
||||
}
|
||||
|
||||
@@ -398,6 +398,79 @@ def test_output_json_hierarchical():
|
||||
assert result.json == '{"score": 4}'
|
||||
assert result.to_dict() == {"score": 4}
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_inject_date():
|
||||
reporter = Agent(
|
||||
role="Reporter",
|
||||
goal="Report the date",
|
||||
backstory="You're an expert reporter, specialized in reporting the date.",
|
||||
allow_delegation=False,
|
||||
inject_date=True,
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="What is the date today?",
|
||||
expected_output="The date today as you were told, same format as the date you were told.",
|
||||
agent=reporter,
|
||||
)
|
||||
|
||||
crew = Crew(
|
||||
agents=[reporter],
|
||||
tasks=[task],
|
||||
process=Process.sequential,
|
||||
)
|
||||
result = crew.kickoff()
|
||||
assert "2025-05-21" in result.raw
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_inject_date_custom_format():
|
||||
reporter = Agent(
|
||||
role="Reporter",
|
||||
goal="Report the date",
|
||||
backstory="You're an expert reporter, specialized in reporting the date.",
|
||||
allow_delegation=False,
|
||||
inject_date=True,
|
||||
date_format="%B %d, %Y",
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="What is the date today?",
|
||||
expected_output="The date today.",
|
||||
agent=reporter,
|
||||
)
|
||||
|
||||
crew = Crew(
|
||||
agents=[reporter],
|
||||
tasks=[task],
|
||||
process=Process.sequential,
|
||||
)
|
||||
result = crew.kickoff()
|
||||
assert "May 21, 2025" in result.raw
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_no_inject_date():
|
||||
reporter = Agent(
|
||||
role="Reporter",
|
||||
goal="Report the date",
|
||||
backstory="You're an expert reporter, specialized in reporting the date.",
|
||||
allow_delegation=False,
|
||||
inject_date=False,
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="What is the date today?",
|
||||
expected_output="The date today.",
|
||||
agent=reporter,
|
||||
)
|
||||
|
||||
crew = Crew(
|
||||
agents=[reporter],
|
||||
tasks=[task],
|
||||
process=Process.sequential,
|
||||
)
|
||||
result = crew.kickoff()
|
||||
assert "2025-05-21" not in result.raw
|
||||
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_json_property_without_output_json():
|
||||
|
||||
117
tests/test_agent_inject_date.py
Normal file
117
tests/test_agent_inject_date.py
Normal file
@@ -0,0 +1,117 @@
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from crewai.agent import Agent
|
||||
from crewai.task import Task
|
||||
|
||||
|
||||
def test_agent_inject_date():
|
||||
"""Test that the inject_date flag injects the current date into the task.
|
||||
|
||||
Tests that when inject_date=True, the current date is added to the task description.
|
||||
"""
|
||||
with patch('datetime.datetime') as mock_datetime:
|
||||
mock_datetime.now.return_value = datetime(2025, 1, 1)
|
||||
|
||||
agent = Agent(
|
||||
role="test_agent",
|
||||
goal="test_goal",
|
||||
backstory="test_backstory",
|
||||
inject_date=True,
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Test task",
|
||||
expected_output="Test output",
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
# Store original description
|
||||
original_description = task.description
|
||||
|
||||
agent._inject_date_to_task(task)
|
||||
|
||||
assert "Current Date: 2025-01-01" in task.description
|
||||
assert task.description != original_description
|
||||
|
||||
|
||||
def test_agent_without_inject_date():
|
||||
"""Test that without inject_date flag, no date is injected.
|
||||
|
||||
Tests that when inject_date=False (default), no date is added to the task description.
|
||||
"""
|
||||
agent = Agent(
|
||||
role="test_agent",
|
||||
goal="test_goal",
|
||||
backstory="test_backstory",
|
||||
# inject_date is False by default
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Test task",
|
||||
expected_output="Test output",
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
original_description = task.description
|
||||
|
||||
agent._inject_date_to_task(task)
|
||||
|
||||
assert task.description == original_description
|
||||
|
||||
|
||||
def test_agent_inject_date_custom_format():
|
||||
"""Test that the inject_date flag with custom date_format works correctly.
|
||||
|
||||
Tests that when inject_date=True with a custom date_format, the date is formatted correctly.
|
||||
"""
|
||||
with patch('datetime.datetime') as mock_datetime:
|
||||
mock_datetime.now.return_value = datetime(2025, 1, 1)
|
||||
|
||||
agent = Agent(
|
||||
role="test_agent",
|
||||
goal="test_goal",
|
||||
backstory="test_backstory",
|
||||
inject_date=True,
|
||||
date_format="%d/%m/%Y",
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Test task",
|
||||
expected_output="Test output",
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
# Store original description
|
||||
original_description = task.description
|
||||
|
||||
agent._inject_date_to_task(task)
|
||||
|
||||
assert "Current Date: 01/01/2025" in task.description
|
||||
assert task.description != original_description
|
||||
|
||||
|
||||
def test_agent_inject_date_invalid_format():
|
||||
"""Test error handling with invalid date format.
|
||||
|
||||
Tests that when an invalid date_format is provided, the task description remains unchanged.
|
||||
"""
|
||||
agent = Agent(
|
||||
role="test_agent",
|
||||
goal="test_goal",
|
||||
backstory="test_backstory",
|
||||
inject_date=True,
|
||||
date_format="invalid",
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Test task",
|
||||
expected_output="Test output",
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
original_description = task.description
|
||||
|
||||
agent._inject_date_to_task(task)
|
||||
|
||||
assert task.description == original_description
|
||||
Reference in New Issue
Block a user