mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 05:37:20 +08:00
send messages separately, adjust summarize prompt
This commit is contained in:
@@ -53,7 +53,7 @@ def action_to_str(action: Action) -> str:
|
||||
elif isinstance(action, MessageAction):
|
||||
return action.content
|
||||
elif isinstance(action, AgentSummarizeAction):
|
||||
return action.summary
|
||||
return action.summarized_actions
|
||||
return ''
|
||||
|
||||
|
||||
@@ -97,6 +97,8 @@ def get_observation_message(obs) -> dict[str, str] | None:
|
||||
elif isinstance(obs, AgentDelegateObservation):
|
||||
content = 'OBSERVATION:\n' + truncate_content(str(obs.outputs))
|
||||
return {'role': 'user', 'content': content}
|
||||
elif isinstance(obs, AgentSummarizeAction):
|
||||
return {'role': 'user', 'content': obs.summarized_observations}
|
||||
return None
|
||||
|
||||
|
||||
@@ -262,14 +264,29 @@ class CodeActAgent(Agent):
|
||||
]
|
||||
|
||||
for event in state.history.get_events():
|
||||
# split summarize message into action and observation
|
||||
if isinstance(event, AgentSummarizeAction):
|
||||
action_message = get_action_message(event)
|
||||
if action_message:
|
||||
messages.append(action_message)
|
||||
observation_message = get_observation_message(event)
|
||||
if observation_message:
|
||||
messages.append(observation_message)
|
||||
continue
|
||||
|
||||
# find regular message
|
||||
message = (
|
||||
get_action_message(event)
|
||||
if isinstance(event, Action)
|
||||
else get_observation_message(event)
|
||||
)
|
||||
|
||||
# add regular message
|
||||
if message:
|
||||
messages.append(message)
|
||||
|
||||
# the latest user message is important:
|
||||
# we want to remind the agent of the environment constraints
|
||||
latest_user_message = next(
|
||||
(m for m in reversed(messages) if m['role'] == 'user'), None
|
||||
)
|
||||
@@ -277,11 +294,11 @@ class CodeActAgent(Agent):
|
||||
if latest_user_message:
|
||||
if state.almost_stuck == 1:
|
||||
latest_user_message['content'] += (
|
||||
'\n\nENVIRONMENT REMINDER: You are almost stuck repeating the same action. You have only 1 iteration left and you must change your approach. Now.'
|
||||
'\n\nENVIRONMENT REMINDER: You are almost stuck, repeating the same action. You have only 1 chance left before you fail. You MUST change your approach. Re-think the problem. Do NOT repeat the same action again, you will fail.'
|
||||
)
|
||||
elif state.almost_stuck == 2:
|
||||
latest_user_message['content'] += (
|
||||
'\n\nENVIRONMENT REMINDER: You are almost stuck repeating the same action. You have only 2 iterations left and you must change your approach.'
|
||||
'\n\nENVIRONMENT REMINDER: You are almost stuck, repeating the same action. You have only 2 iterations left before you fail. Do NOT repeat the same action again, you will fail the same as before. Re-think the problem.'
|
||||
)
|
||||
else:
|
||||
latest_user_message['content'] += (
|
||||
|
||||
@@ -85,7 +85,7 @@ async def main(
|
||||
AgentCls: Type[Agent] = Agent.get_cls(args.agent_cls)
|
||||
agent = AgentCls(llm=llm)
|
||||
|
||||
event_stream = EventStream('main' + (f'_{sid if sid else ""}'))
|
||||
event_stream = EventStream('main' + ('_' + sid if sid else ''))
|
||||
|
||||
# restore main session if enabled
|
||||
initial_state = None
|
||||
|
||||
@@ -37,12 +37,12 @@ class AgentSummarizeAction(Action):
|
||||
Action to summarize a list of events.
|
||||
|
||||
Attributes:
|
||||
- actions: A comma-separated list of all the action names from the summarized actions.
|
||||
- summary: A single sentence summarizing all the observations.
|
||||
- summarized_actions: A sentence summarizing all the actions.
|
||||
- summarized_observations: A few sentences summarizing all the observations.
|
||||
"""
|
||||
|
||||
summarized_actions: str = ''
|
||||
summary: str = ''
|
||||
summarized_observations: str = ''
|
||||
action: str = ActionType.SUMMARIZE
|
||||
_chunk_start: int = -1
|
||||
_chunk_end: int = -1
|
||||
@@ -50,11 +50,12 @@ class AgentSummarizeAction(Action):
|
||||
|
||||
@property
|
||||
def message(self) -> str:
|
||||
return self.summary
|
||||
return self.summarized_observations
|
||||
|
||||
def __str__(self) -> str:
|
||||
ret = '**AgentSummarizeAction**\n'
|
||||
ret += f'SUMMARY: {self.summary}'
|
||||
ret += f'SUMMARIZED ACTIONS: {self.summarized_actions}\n'
|
||||
ret += f'SUMMARIZED OBSERVATIONS: {self.summarized_observations}\n'
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
@@ -6,14 +6,25 @@ from opendevin.core.exceptions import (
|
||||
from opendevin.core.logger import opendevin_logger as logger
|
||||
from opendevin.core.utils import json
|
||||
from opendevin.events.action.agent import AgentSummarizeAction
|
||||
from opendevin.events.event import EventSource
|
||||
from opendevin.events.serialization.action import action_from_dict
|
||||
|
||||
SUMMARY_PROMPT = """
|
||||
Given the following actions and observations, create a JSON response with:
|
||||
- "action": "summarize"
|
||||
- args:
|
||||
- "summarized_actions": A comma-separated list of unique action names from the provided actions
|
||||
- "summary": A single sentence summarizing all the provided observations
|
||||
- "summarized_actions": A sentence summarizing all the provided actions, at first person
|
||||
- "summarized observations": A few sentences summarizing all the provided observations, at third person
|
||||
|
||||
Example:
|
||||
{
|
||||
"action": "summarize",
|
||||
"args": {
|
||||
"summarized_actions": "I opened the uml file.",
|
||||
"summarized observations": "The agent ran a python script to open the uml.pdf file."
|
||||
}
|
||||
}
|
||||
Make sure to include in observations any relevant information that the agent should remember.
|
||||
%(events)s
|
||||
"""
|
||||
|
||||
@@ -46,6 +57,7 @@ def parse_summary_response(response: str) -> AgentSummarizeAction:
|
||||
error_message = f'Expected a summarize action, but the response got {str(type(action)) if action else None}'
|
||||
logger.error(error_message)
|
||||
raise InvalidSummaryResponseError(error_message)
|
||||
action._source = EventSource.AGENT # type: ignore
|
||||
except (LLMResponseError, LLMMalformedActionError) as e:
|
||||
logger.error(f'Failed to parse summary response: {e}')
|
||||
raise InvalidSummaryResponseError(
|
||||
|
||||
Reference in New Issue
Block a user