mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-08-12 17:29:11 +00:00
refactor: update date injection functionality in agents (#6850)
* refactor: update date injection functionality in agents - Changed the description of the parameter to clarify that it injects the current date into the agent's prompt instead of tasks. - Removed the method as it was no longer needed. - Implemented a new method in the class to handle date injection directly into the prompt. - Updated tests to ensure the date is correctly injected into the system prompt and user messages based on the flag. * translations * nit
This commit is contained in:
@@ -60,7 +60,7 @@ mode: "wide"
|
||||
| **احترام نافذة السياق** _(اختياري)_ | `respect_context_window` | `bool` | إبقاء الرسائل تحت حجم نافذة السياق عبر التلخيص. الافتراضي True. |
|
||||
| **وضع تنفيذ الكود** _(اختياري)_ | `code_execution_mode` | `Literal["safe", "unsafe"]` | وضع تنفيذ الكود: 'safe' (باستخدام Docker) أو 'unsafe' (مباشر). الافتراضي 'safe'. |
|
||||
| **متعدد الوسائط** _(اختياري)_ | `multimodal` | `bool` | ما إذا كان الوكيل يدعم القدرات متعددة الوسائط. الافتراضي False. |
|
||||
| **حقن التاريخ** _(اختياري)_ | `inject_date` | `bool` | ما إذا كان يتم حقن التاريخ الحالي تلقائيًا في المهام. الافتراضي False. |
|
||||
| **حقن التاريخ** _(اختياري)_ | `inject_date` | `bool` | ما إذا كان يتم حقن التاريخ الحالي تلقائيًا في أمر الوكيل. الافتراضي False. |
|
||||
| **تنسيق التاريخ** _(اختياري)_ | `date_format` | `str` | سلسلة تنسيق التاريخ عند تفعيل inject_date. الافتراضي "%Y-%m-%d" (تنسيق ISO). |
|
||||
| **الاستدلال** _(اختياري)_ | `reasoning` | `bool` | ما إذا كان يجب على الوكيل التأمل وإنشاء خطة قبل تنفيذ المهمة. الافتراضي False. |
|
||||
| **الحد الأقصى لمحاولات الاستدلال** _(اختياري)_ | `max_reasoning_attempts` | `Optional[int]` | الحد الأقصى لمحاولات الاستدلال قبل تنفيذ المهمة. إذا None، سيحاول حتى الاستعداد. |
|
||||
@@ -287,7 +287,7 @@ analysis_agent = Agent(
|
||||
|
||||
- `multimodal`: تفعيل القدرات متعددة الوسائط لمعالجة النص والمحتوى المرئي
|
||||
- `reasoning`: تمكين الوكيل من التأمل وإنشاء خطط قبل تنفيذ المهام
|
||||
- `inject_date`: حقن التاريخ الحالي تلقائيًا في أوصاف المهام
|
||||
- `inject_date`: حقن التاريخ الحالي تلقائيًا في أمر الوكيل
|
||||
|
||||
#### القوالب
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ The Visual Agent Builder enables:
|
||||
| **Respect Context Window** _(optional)_ | `respect_context_window` | `bool` | Keep messages under context window size by summarizing. Default is True. |
|
||||
| **Code Execution Mode** _(optional)_ | `code_execution_mode` | `Literal["safe", "unsafe"]` | Mode for code execution: 'safe' (using Docker) or 'unsafe' (direct). Default is 'safe'. |
|
||||
| **Multimodal** _(optional)_ | `multimodal` | `bool` | Whether the agent supports multimodal capabilities. Default is False. |
|
||||
| **Inject Date** _(optional)_ | `inject_date` | `bool` | Whether to automatically inject the current date into tasks. Default is False. |
|
||||
| **Inject Date** _(optional)_ | `inject_date` | `bool` | Whether to automatically inject the current date into the agent's prompt. Default is False. |
|
||||
| **Date Format** _(optional)_ | `date_format` | `str` | Format string for date when inject_date is enabled. Default is "%Y-%m-%d" (ISO format). |
|
||||
| **Reasoning** _(optional)_ | `reasoning` | `bool` | Whether the agent should reflect and create a plan before executing a task. Default is False. |
|
||||
| **Max Reasoning Attempts** _(optional)_ | `max_reasoning_attempts` | `Optional[int]` | Maximum number of reasoning attempts before executing the task. If None, will try until ready. |
|
||||
@@ -236,7 +236,7 @@ strategic_agent = Agent(
|
||||
role="Market Analyst",
|
||||
goal="Track market movements with precise date references and strategic planning",
|
||||
backstory="Expert in time-sensitive financial analysis and strategic reporting",
|
||||
inject_date=True, # Automatically inject current date into tasks
|
||||
inject_date=True, # Automatically inject current date into the prompt
|
||||
date_format="%B %d, %Y", # Format as "May 21, 2025"
|
||||
reasoning=True, # Enable strategic planning
|
||||
max_reasoning_attempts=2, # Limit planning iterations
|
||||
@@ -303,7 +303,7 @@ multimodal_agent = Agent(
|
||||
|
||||
- `multimodal`: Enable multimodal capabilities for processing text and visual content
|
||||
- `reasoning`: Enable agent to reflect and create plans before executing tasks
|
||||
- `inject_date`: Automatically inject current date into task descriptions
|
||||
- `inject_date`: Automatically inject current date into the agents prompt
|
||||
|
||||
#### Templates
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ CrewAI AOP에는 코드를 작성하지 않고도 에이전트 생성 및 구성
|
||||
| **컨텍스트 윈도우 준수** _(옵션)_ | `respect_context_window` | `bool` | 메시지를 컨텍스트 윈도우 크기 내로 유지하기 위하여 요약 기능을 사용합니다. 기본값은 True입니다. |
|
||||
| **코드 실행 모드** _(옵션)_ | `code_execution_mode` | `Literal["safe", "unsafe"]` | 코드 실행 모드: 'safe'(Docker 사용) 또는 'unsafe'(직접 실행). 기본값은 'safe'입니다. |
|
||||
| **멀티모달** _(옵션)_ | `multimodal` | `bool` | 에이전트가 멀티모달 기능을 지원하는지 여부입니다. 기본값은 False입니다. |
|
||||
| **날짜 자동 삽입** _(옵션)_ | `inject_date` | `bool` | 작업에 현재 날짜를 자동으로 삽입할지 여부입니다. 기본값은 False입니다. |
|
||||
| **날짜 자동 삽입** _(옵션)_ | `inject_date` | `bool` | 에이전트 프롬프트에 현재 날짜를 자동으로 삽입할지 여부입니다. 기본값은 False입니다. |
|
||||
| **날짜 형식** _(옵션)_ | `date_format` | `str` | inject_date 활성화 시 날짜 표시 형식 문자열입니다. 기본값은 "%Y-%m-%d"(ISO 포맷)입니다. |
|
||||
| **추론** _(옵션)_ | `reasoning` | `bool` | 에이전트가 작업을 실행하기 전에 반영 및 플랜을 생성할지 여부입니다. 기본값은 False입니다. |
|
||||
| **최대 추론 시도 수** _(옵션)_ | `max_reasoning_attempts` | `Optional[int]` | 작업 실행 전 최대 추론 시도 횟수입니다. 설정하지 않으면 준비될 때까지 시도합니다. |
|
||||
@@ -267,7 +267,7 @@ strategic_agent = Agent(
|
||||
role="Market Analyst",
|
||||
goal="Track market movements with precise date references and strategic planning",
|
||||
backstory="Expert in time-sensitive financial analysis and strategic reporting",
|
||||
inject_date=True, # Automatically inject current date into tasks
|
||||
inject_date=True, # Automatically inject current date into the prompt
|
||||
date_format="%B %d, %Y", # Format as "May 21, 2025"
|
||||
reasoning=True, # Enable strategic planning
|
||||
max_reasoning_attempts=2, # Limit planning iterations
|
||||
@@ -328,7 +328,7 @@ multimodal_agent = Agent(
|
||||
#### 고급 기능
|
||||
- `multimodal`: 텍스트와 시각적 콘텐츠 처리를 위한 멀티모달 기능 활성화
|
||||
- `reasoning`: 에이전트가 작업을 수행하기 전에 반영하고 계획을 작성할 수 있도록 활성화
|
||||
- `inject_date`: 현재 날짜를 작업 설명에 자동으로 삽입
|
||||
- `inject_date`: 현재 날짜를 에이전트 프롬프트에 자동으로 삽입
|
||||
|
||||
#### 템플릿
|
||||
- `system_template`: 에이전트의 핵심 동작을 정의합니다
|
||||
|
||||
@@ -61,7 +61,7 @@ O Construtor Visual de Agentes permite:
|
||||
| **Respect Context Window** _(opcional)_ | `respect_context_window` | `bool` | Mantém as mensagens dentro do tamanho da janela de contexto, resumindo quando necessário. Padrão: True. |
|
||||
| **Code Execution Mode** _(opcional)_ | `code_execution_mode` | `Literal["safe", "unsafe"]` | Modo de execução de código: 'safe' (usando Docker) ou 'unsafe' (direto). Padrão: 'safe'. |
|
||||
| **Multimodal** _(opcional)_ | `multimodal` | `bool` | Se o agente suporta capacidades multimodais. Padrão: False. |
|
||||
| **Inject Date** _(opcional)_ | `inject_date` | `bool` | Se deve injetar automaticamente a data atual nas tarefas. Padrão: False. |
|
||||
| **Inject Date** _(opcional)_ | `inject_date` | `bool` | Se deve injetar automaticamente a data atual no prompt do agente. Padrão: False. |
|
||||
| **Date Format** _(opcional)_ | `date_format` | `str` | Formato de data utilizado quando `inject_date` está ativo. Padrão: "%Y-%m-%d" (formato ISO). |
|
||||
| **Reasoning** _(opcional)_ | `reasoning` | `bool` | Se o agente deve refletir e criar um plano antes de executar uma tarefa. Padrão: False. |
|
||||
| **Max Reasoning Attempts** _(opcional)_ | `max_reasoning_attempts` | `Optional[int]` | Número máximo de tentativas de raciocínio antes de executar a tarefa. Se None, tentará até estar pronto. |
|
||||
@@ -274,7 +274,7 @@ strategic_agent = Agent(
|
||||
role="Analista de Mercado",
|
||||
goal="Acompanhar movimentos do mercado com referências de datas precisas e planejamento estratégico",
|
||||
backstory="Especialista em análise financeira sensível ao tempo e relatórios estratégicos",
|
||||
inject_date=True, # Injeta automaticamente a data atual nas tarefas
|
||||
inject_date=True, # Injeta automaticamente a data atual no prompt
|
||||
date_format="%d de %B de %Y", # Exemplo: "21 de maio de 2025"
|
||||
reasoning=True, # Ativa planejamento estratégico
|
||||
max_reasoning_attempts=2, # Limite de iterações de planejamento
|
||||
@@ -341,7 +341,7 @@ multimodal_agent = Agent(
|
||||
|
||||
- `multimodal`: Habilita capacidades multimodais para processar texto e conteúdo visual
|
||||
- `reasoning`: Permite que o agente reflita e crie planos antes de executar tarefas
|
||||
- `inject_date`: Injeta a data atual automaticamente nas descrições das tarefas
|
||||
- `inject_date`: Injeta a data atual automaticamente no prompt do agente
|
||||
|
||||
#### Templates
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import asyncio
|
||||
from collections.abc import Callable, Coroutine, Sequence
|
||||
import concurrent.futures
|
||||
import contextvars
|
||||
from datetime import datetime
|
||||
import inspect
|
||||
import json
|
||||
import os
|
||||
@@ -264,7 +263,7 @@ class Agent(BaseAgent):
|
||||
)
|
||||
inject_date: bool = Field(
|
||||
default=False,
|
||||
description="Whether to automatically inject the current date into tasks.",
|
||||
description="Whether to automatically inject the current date into the agent's prompt.",
|
||||
)
|
||||
date_format: str = Field(
|
||||
default="%Y-%m-%d",
|
||||
@@ -545,7 +544,7 @@ class Agent(BaseAgent):
|
||||
) -> str:
|
||||
"""Prepare common setup for task execution shared by sync and async paths.
|
||||
|
||||
Handles reasoning, date injection, prompt building, and memory retrieval.
|
||||
Handles reasoning, prompt building, and memory retrieval.
|
||||
|
||||
Args:
|
||||
task: Task to execute.
|
||||
@@ -556,8 +555,6 @@ class Agent(BaseAgent):
|
||||
"""
|
||||
get_env_context()
|
||||
|
||||
self._inject_date_to_task(task)
|
||||
|
||||
self.reset_tool_failures()
|
||||
|
||||
if self.tools_handler:
|
||||
@@ -1332,32 +1329,6 @@ class Agent(BaseAgent):
|
||||
]
|
||||
)
|
||||
|
||||
def _inject_date_to_task(self, task: Task) -> None:
|
||||
"""Inject the current date into the task description if inject_date is enabled."""
|
||||
if self.inject_date:
|
||||
try:
|
||||
valid_format_codes = [
|
||||
"%Y",
|
||||
"%m",
|
||||
"%d",
|
||||
"%H",
|
||||
"%M",
|
||||
"%S",
|
||||
"%B",
|
||||
"%b",
|
||||
"%A",
|
||||
"%a",
|
||||
]
|
||||
is_valid = any(code in self.date_format for code in valid_format_codes)
|
||||
|
||||
if not is_valid:
|
||||
raise ValueError(f"Invalid date format: {self.date_format}")
|
||||
|
||||
current_date = datetime.now().strftime(self.date_format)
|
||||
task.description += f"\n\nCurrent Date: {current_date}"
|
||||
except Exception as e:
|
||||
self._logger.log("warning", f"Failed to inject date: {e!s}")
|
||||
|
||||
def _validate_docker_installation(self) -> None:
|
||||
"""Deprecated: No-op. CodeInterpreterTool is no longer available."""
|
||||
warnings.warn(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Literal
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -9,6 +10,20 @@ from pydantic import BaseModel, Field
|
||||
from crewai.utilities.i18n import I18N_DEFAULT
|
||||
|
||||
|
||||
VALID_DATE_FORMAT_CODES = (
|
||||
"%Y",
|
||||
"%m",
|
||||
"%d",
|
||||
"%H",
|
||||
"%M",
|
||||
"%S",
|
||||
"%B",
|
||||
"%b",
|
||||
"%A",
|
||||
"%a",
|
||||
)
|
||||
|
||||
|
||||
class StandardPromptResult(BaseModel):
|
||||
"""Result with only prompt field for standard mode."""
|
||||
|
||||
@@ -87,7 +102,11 @@ class Prompts(BaseModel):
|
||||
slices.append("tools")
|
||||
else:
|
||||
slices.append("no_tools")
|
||||
system: str = self._build_prompt(slices) + self._build_skill_block()
|
||||
system: str = (
|
||||
self._build_prompt(slices)
|
||||
+ self._build_skill_block()
|
||||
+ self._build_date_block()
|
||||
)
|
||||
|
||||
task_slice: COMPONENTS
|
||||
if self.use_native_tool_calling:
|
||||
@@ -106,7 +125,9 @@ class Prompts(BaseModel):
|
||||
return SystemPromptResult(
|
||||
system=system,
|
||||
user=self._build_prompt([task_slice]),
|
||||
prompt=self._build_prompt(slices) + self._build_skill_block(),
|
||||
prompt=self._build_prompt(slices)
|
||||
+ self._build_skill_block()
|
||||
+ self._build_date_block(),
|
||||
)
|
||||
return StandardPromptResult(
|
||||
prompt=self._build_prompt(
|
||||
@@ -116,8 +137,31 @@ class Prompts(BaseModel):
|
||||
self.response_template,
|
||||
)
|
||||
+ self._build_skill_block()
|
||||
+ self._build_date_block()
|
||||
)
|
||||
|
||||
def _build_date_block(self) -> str:
|
||||
"""Render the current date when the agent has ``inject_date`` enabled.
|
||||
|
||||
Kept at the tail of the prompt so the stable prefix ahead of it stays
|
||||
usable as a prompt-cache anchor.
|
||||
"""
|
||||
if not getattr(self.agent, "inject_date", False):
|
||||
return ""
|
||||
|
||||
date_format = getattr(self.agent, "date_format", "%Y-%m-%d")
|
||||
try:
|
||||
if not any(code in date_format for code in VALID_DATE_FORMAT_CODES):
|
||||
raise ValueError(f"Invalid date format: {date_format}")
|
||||
current_date = datetime.now().strftime(date_format)
|
||||
except Exception as e:
|
||||
logger = getattr(self.agent, "_logger", None)
|
||||
if logger is not None:
|
||||
logger.log("warning", f"Failed to inject date: {e!s}")
|
||||
return ""
|
||||
|
||||
return f"\n\nCurrent Date: {current_date}"
|
||||
|
||||
def _build_skill_block(self) -> str:
|
||||
"""Render always-on instructions and the available skill catalog.
|
||||
|
||||
|
||||
@@ -1,116 +1,165 @@
|
||||
"""Tests for the agent ``inject_date`` flag.
|
||||
|
||||
These assert against the messages the LLM actually receives, so they fail if the
|
||||
date stops reaching the wire for either execution entry point: crew/task
|
||||
execution via ``execute_task`` and standalone execution via ``kickoff``.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
from crewai.agent import Agent
|
||||
from crewai.llms.base_llm import BaseLLM
|
||||
from crewai.task import Task
|
||||
|
||||
MOCK_TARGET = "crewai.agent.core.datetime"
|
||||
MOCK_TARGET = "crewai.utilities.prompts.datetime"
|
||||
FROZEN_NOW = datetime(2025, 1, 1)
|
||||
|
||||
|
||||
def test_agent_inject_date():
|
||||
"""Test that the inject_date flag injects the current date into the task.
|
||||
class _RecordingLLM(BaseLLM):
|
||||
"""Deterministic LLM that captures every message list it is handed."""
|
||||
|
||||
Tests that when inject_date=True, the current date is added to the task description.
|
||||
"""
|
||||
with patch(MOCK_TARGET) as mock_datetime:
|
||||
mock_datetime.now.return_value = datetime(2025, 1, 1)
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
super().__init__(**kwargs)
|
||||
self.calls: list[Any] = []
|
||||
|
||||
agent = Agent(
|
||||
role="test_agent",
|
||||
goal="test_goal",
|
||||
backstory="test_backstory",
|
||||
inject_date=True,
|
||||
def call(self, messages: Any, **kwargs: Any) -> str:
|
||||
self.calls.append(messages)
|
||||
return "Thought: Done.\nFinal Answer: done"
|
||||
|
||||
def supports_function_calling(self) -> bool:
|
||||
return False
|
||||
|
||||
def supports_stop_words(self) -> bool:
|
||||
return False
|
||||
|
||||
def get_context_window_size(self) -> int:
|
||||
return 8_192
|
||||
|
||||
def contents_for(self, role: str) -> list[str]:
|
||||
"""Every message body sent under ``role`` across all calls."""
|
||||
return [
|
||||
str(message.get("content", ""))
|
||||
for messages in self.calls
|
||||
if not isinstance(messages, str)
|
||||
for message in messages
|
||||
if message.get("role") == role
|
||||
]
|
||||
|
||||
@property
|
||||
def everything_sent(self) -> str:
|
||||
return "\n".join(
|
||||
str(message.get("content", ""))
|
||||
for messages in self.calls
|
||||
if not isinstance(messages, str)
|
||||
for message in messages
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Test task",
|
||||
expected_output="Test output",
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
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(
|
||||
def _agent(llm: BaseLLM, **kwargs: Any) -> Agent:
|
||||
return Agent(
|
||||
role="test_agent",
|
||||
goal="test_goal",
|
||||
backstory="test_backstory",
|
||||
llm=llm,
|
||||
max_iter=2,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Test task",
|
||||
expected_output="Test output",
|
||||
|
||||
def _task(agent: Agent) -> Task:
|
||||
return Task(
|
||||
description="What is the date today?",
|
||||
expected_output="The date.",
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
original_description = task.description
|
||||
|
||||
agent._inject_date_to_task(task)
|
||||
def test_inject_date_reaches_system_prompt_on_kickoff() -> None:
|
||||
"""Standalone ``kickoff`` must put the date in the system message."""
|
||||
llm = _RecordingLLM(model="date-test")
|
||||
agent = _agent(llm, inject_date=True)
|
||||
|
||||
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(MOCK_TARGET) as mock_datetime:
|
||||
mock_datetime.now.return_value = datetime(2025, 1, 1)
|
||||
mock_datetime.now.return_value = FROZEN_NOW
|
||||
agent.kickoff("What is the date today?")
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
original_description = task.description
|
||||
|
||||
agent._inject_date_to_task(task)
|
||||
|
||||
assert "Current Date: 01/01/2025" in task.description
|
||||
assert task.description != original_description
|
||||
system_prompts = llm.contents_for("system")
|
||||
assert system_prompts
|
||||
assert all("Current Date: 2025-01-01" in prompt for prompt in system_prompts)
|
||||
|
||||
|
||||
def test_agent_inject_date_invalid_format():
|
||||
"""Test error handling with invalid date format.
|
||||
def test_inject_date_reaches_system_prompt_on_task_execution() -> None:
|
||||
"""Crew/task execution must keep putting the date in front of the model."""
|
||||
llm = _RecordingLLM(model="date-test")
|
||||
agent = _agent(llm, inject_date=True)
|
||||
|
||||
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",
|
||||
with patch(MOCK_TARGET) as mock_datetime:
|
||||
mock_datetime.now.return_value = FROZEN_NOW
|
||||
agent.execute_task(_task(agent))
|
||||
|
||||
system_prompts = llm.contents_for("system")
|
||||
assert system_prompts
|
||||
assert all("Current Date: 2025-01-01" in prompt for prompt in system_prompts)
|
||||
|
||||
|
||||
def test_inject_date_reaches_prompt_without_system_prompt() -> None:
|
||||
"""With ``use_system_prompt=False`` the whole prompt is one user message."""
|
||||
llm = _RecordingLLM(model="date-test")
|
||||
agent = _agent(llm, inject_date=True, use_system_prompt=False)
|
||||
|
||||
with patch(MOCK_TARGET) as mock_datetime:
|
||||
mock_datetime.now.return_value = FROZEN_NOW
|
||||
agent.kickoff("What is the date today?")
|
||||
|
||||
assert not llm.contents_for("system")
|
||||
assert "Current Date: 2025-01-01" in llm.contents_for("user")[0]
|
||||
|
||||
|
||||
def test_inject_date_custom_format() -> None:
|
||||
llm = _RecordingLLM(model="date-test")
|
||||
agent = _agent(llm, inject_date=True, date_format="%d/%m/%Y")
|
||||
|
||||
with patch(MOCK_TARGET) as mock_datetime:
|
||||
mock_datetime.now.return_value = FROZEN_NOW
|
||||
agent.kickoff("What is the date today?")
|
||||
|
||||
assert "Current Date: 01/01/2025" in llm.contents_for("system")[0]
|
||||
|
||||
|
||||
def test_without_inject_date_no_date_is_sent() -> None:
|
||||
llm = _RecordingLLM(model="date-test")
|
||||
agent = _agent(llm)
|
||||
|
||||
agent.kickoff("What is the date today?")
|
||||
|
||||
assert llm.calls
|
||||
assert "Current Date:" not in llm.everything_sent
|
||||
|
||||
|
||||
def test_inject_date_invalid_format_is_skipped() -> None:
|
||||
"""An unusable format should drop the date, not break execution."""
|
||||
llm = _RecordingLLM(model="date-test")
|
||||
agent = _agent(llm, inject_date=True, date_format="invalid")
|
||||
|
||||
output = agent.kickoff("What is the date today?")
|
||||
|
||||
assert output.raw == "done"
|
||||
assert "Current Date:" not in llm.everything_sent
|
||||
|
||||
|
||||
def test_inject_date_does_not_accumulate_across_runs() -> None:
|
||||
"""Re-running the same task must not stack up repeated date lines."""
|
||||
llm = _RecordingLLM(model="date-test")
|
||||
agent = _agent(llm, inject_date=True)
|
||||
task = _task(agent)
|
||||
|
||||
with patch(MOCK_TARGET) as mock_datetime:
|
||||
mock_datetime.now.return_value = FROZEN_NOW
|
||||
agent.execute_task(task)
|
||||
agent.execute_task(task)
|
||||
|
||||
assert all(
|
||||
prompt.count("Current Date:") == 1 for prompt in llm.contents_for("system")
|
||||
)
|
||||
|
||||
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