From 0df87bfacc0b673e0cb44c0a775fd90c2d506b5e Mon Sep 17 00:00:00 2001 From: Rohit Malhotra Date: Thu, 27 Mar 2025 01:23:12 -0400 Subject: [PATCH] [Feat]: Tell the agent the current date (#7509) --- .../agenthub/codeact_agent/prompts/additional_info.j2 | 3 +++ openhands/events/observation/agent.py | 2 ++ openhands/memory/conversation_memory.py | 5 ++++- openhands/memory/memory.py | 8 +++++++- openhands/utils/prompt.py | 1 + tests/unit/test_observation_serialization.py | 2 ++ tests/unit/test_prompt_manager.py | 2 ++ 7 files changed, 21 insertions(+), 2 deletions(-) diff --git a/openhands/agenthub/codeact_agent/prompts/additional_info.j2 b/openhands/agenthub/codeact_agent/prompts/additional_info.j2 index 5c30c79be3..64d466b6c5 100644 --- a/openhands/agenthub/codeact_agent/prompts/additional_info.j2 +++ b/openhands/agenthub/codeact_agent/prompts/additional_info.j2 @@ -24,5 +24,8 @@ For example, if you are using vite.config.js, you should set server.host and ser {% if runtime_info.additional_agent_instructions %} {{ runtime_info.additional_agent_instructions }} {% endif %} +{% if runtime_info.date %} +Today's date is {{ runtime_info.date }} (UTC). +{% endif %} {% endif %} diff --git a/openhands/events/observation/agent.py b/openhands/events/observation/agent.py index 2e2831283d..16686d3b13 100644 --- a/openhands/events/observation/agent.py +++ b/openhands/events/observation/agent.py @@ -72,6 +72,7 @@ class RecallObservation(Observation): repo_instructions: str = '' runtime_hosts: dict[str, int] = field(default_factory=dict) additional_agent_instructions: str = '' + date: str = '' # knowledge microagent_knowledge: list[MicroagentKnowledge] = field(default_factory=list) @@ -112,6 +113,7 @@ class RecallObservation(Observation): f'repo_instructions={self.repo_instructions[:20]}...', f'runtime_hosts={self.runtime_hosts}', f'additional_agent_instructions={self.additional_agent_instructions[:20]}...', + f'date={self.date}' ] ) else: diff --git a/openhands/memory/conversation_memory.py b/openhands/memory/conversation_memory.py index 596a76e14e..8440fd6eda 100644 --- a/openhands/memory/conversation_memory.py +++ b/openhands/memory/conversation_memory.py @@ -399,13 +399,16 @@ class ConversationMemory: else: repo_info = None + date = obs.date + if obs.runtime_hosts or obs.additional_agent_instructions: runtime_info = RuntimeInfo( available_hosts=obs.runtime_hosts, additional_agent_instructions=obs.additional_agent_instructions, + date=date, ) else: - runtime_info = None + runtime_info = RuntimeInfo(date=date) repo_instructions = ( obs.repo_instructions if obs.repo_instructions else '' diff --git a/openhands/memory/memory.py b/openhands/memory/memory.py index a6eab63d06..aacfe1bca7 100644 --- a/openhands/memory/memory.py +++ b/openhands/memory/memory.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from datetime import datetime, timezone from typing import Callable import openhands @@ -170,6 +171,7 @@ class Memory: else '', microagent_knowledge=microagent_knowledge, content='Added workspace context', + date=self.runtime_info.date if self.runtime_info is not None else '', ) return obs return None @@ -263,13 +265,17 @@ class Memory: def set_runtime_info(self, runtime: Runtime) -> None: """Store runtime info (web hosts, ports, etc.).""" # e.g. { '127.0.0.1': 8080 } + utc_now = datetime.now(timezone.utc) + date = str(utc_now.date()) + if runtime.web_hosts or runtime.additional_agent_instructions: self.runtime_info = RuntimeInfo( available_hosts=runtime.web_hosts, additional_agent_instructions=runtime.additional_agent_instructions, + date=date, ) else: - self.runtime_info = None + self.runtime_info = RuntimeInfo(date=date) def send_error_message(self, message_id: str, message: str): """Sends an error message if the callback function was provided.""" diff --git a/openhands/utils/prompt.py b/openhands/utils/prompt.py index 4762b0e442..65859cacff 100644 --- a/openhands/utils/prompt.py +++ b/openhands/utils/prompt.py @@ -11,6 +11,7 @@ from openhands.events.observation.agent import MicroagentKnowledge @dataclass class RuntimeInfo: + date: str available_hosts: dict[str, int] = field(default_factory=dict) additional_agent_instructions: str = '' diff --git a/tests/unit/test_observation_serialization.py b/tests/unit/test_observation_serialization.py index 6345d6c34f..1b84cd75b2 100644 --- a/tests/unit/test_observation_serialization.py +++ b/tests/unit/test_observation_serialization.py @@ -245,6 +245,7 @@ def test_microagent_observation_serialization(): 'runtime_hosts': {'host1': 8080, 'host2': 8081}, 'repo_instructions': 'complex_repo_instructions', 'additional_agent_instructions': 'You know it all about this runtime', + 'date': '04/12/1023', 'microagent_knowledge': [], }, } @@ -263,6 +264,7 @@ def test_microagent_observation_microagent_knowledge_serialization(): 'repo_instructions': '', 'runtime_hosts': {}, 'additional_agent_instructions': '', + 'date': '', 'microagent_knowledge': [ { 'name': 'microagent1', diff --git a/tests/unit/test_prompt_manager.py b/tests/unit/test_prompt_manager.py index 1c01eb80c4..7ca79bfe8c 100644 --- a/tests/unit/test_prompt_manager.py +++ b/tests/unit/test_prompt_manager.py @@ -239,6 +239,7 @@ each of which has a corresponding port: # Create repository and runtime information repo_info = RepositoryInfo(repo_name='owner/repo', repo_directory='/workspace/repo') runtime_info = RuntimeInfo( + date='02/12/1232', available_hosts={'example.com': 8080}, additional_agent_instructions='You know everything about this runtime.', ) @@ -260,6 +261,7 @@ each of which has a corresponding port: assert '' in result assert 'example.com (port 8080)' in result assert 'You know everything about this runtime.' in result + assert "Today's date is 02/12/1232 (UTC)." # Clean up os.remove(os.path.join(prompt_dir, 'additional_info.j2'))