Spaces:
Build error
Build error
from typing import TypedDict | |
from openhands.controller.agent import Agent | |
from openhands.controller.state.state import State | |
from openhands.core.config import AgentConfig | |
from openhands.core.schema import AgentState | |
from openhands.events.action import ( | |
Action, | |
AgentFinishAction, | |
AgentRejectAction, | |
BrowseInteractiveAction, | |
BrowseURLAction, | |
CmdRunAction, | |
FileReadAction, | |
FileWriteAction, | |
MessageAction, | |
) | |
from openhands.events.observation import ( | |
AgentStateChangedObservation, | |
BrowserOutputObservation, | |
CmdOutputMetadata, | |
CmdOutputObservation, | |
FileReadObservation, | |
FileWriteObservation, | |
Observation, | |
) | |
from openhands.events.serialization.event import event_to_dict | |
from openhands.llm.llm import LLM | |
""" | |
FIXME: There are a few problems this surfaced | |
* FileWrites seem to add an unintended newline at the end of the file | |
* Browser not working | |
""" | |
ActionObs = TypedDict( | |
'ActionObs', {'action': Action, 'observations': list[Observation]} | |
) | |
class DummyAgent(Agent): | |
VERSION = '1.0' | |
""" | |
The DummyAgent is used for e2e testing. It just sends the same set of actions deterministically, | |
without making any LLM calls. | |
""" | |
def __init__(self, llm: LLM, config: AgentConfig): | |
super().__init__(llm, config) | |
self.steps: list[ActionObs] = [ | |
{ | |
'action': MessageAction('Time to get started!'), | |
'observations': [], | |
}, | |
{ | |
'action': CmdRunAction(command='echo "foo"'), | |
'observations': [CmdOutputObservation('foo', command='echo "foo"')], | |
}, | |
{ | |
'action': FileWriteAction( | |
content='echo "Hello, World!"', path='hello.sh' | |
), | |
'observations': [ | |
FileWriteObservation( | |
content='echo "Hello, World!"', path='hello.sh' | |
) | |
], | |
}, | |
{ | |
'action': FileReadAction(path='hello.sh'), | |
'observations': [ | |
FileReadObservation('echo "Hello, World!"\n', path='hello.sh') | |
], | |
}, | |
{ | |
'action': CmdRunAction(command='bash hello.sh'), | |
'observations': [ | |
CmdOutputObservation( | |
'bash: hello.sh: No such file or directory', | |
command='bash workspace/hello.sh', | |
metadata=CmdOutputMetadata(exit_code=127), | |
) | |
], | |
}, | |
{ | |
'action': BrowseURLAction(url='https://google.com'), | |
'observations': [ | |
BrowserOutputObservation( | |
'<html><body>Simulated Google page</body></html>', | |
url='https://google.com', | |
screenshot='', | |
trigger_by_action='', | |
), | |
], | |
}, | |
{ | |
'action': BrowseInteractiveAction( | |
browser_actions='goto("https://google.com")' | |
), | |
'observations': [ | |
BrowserOutputObservation( | |
'<html><body>Simulated Google page after interaction</body></html>', | |
url='https://google.com', | |
screenshot='', | |
trigger_by_action='', | |
), | |
], | |
}, | |
{ | |
'action': AgentRejectAction(), | |
'observations': [AgentStateChangedObservation('', AgentState.REJECTED)], | |
}, | |
{ | |
'action': AgentFinishAction( | |
outputs={}, thought='Task completed', action='finish' | |
), | |
'observations': [AgentStateChangedObservation('', AgentState.FINISHED)], | |
}, | |
] | |
def step(self, state: State) -> Action: | |
if state.iteration >= len(self.steps): | |
return AgentFinishAction() | |
current_step = self.steps[state.iteration] | |
action = current_step['action'] | |
if state.iteration > 0: | |
prev_step = self.steps[state.iteration - 1] | |
if 'observations' in prev_step and prev_step['observations']: | |
expected_observations = prev_step['observations'] | |
hist_events = state.view[-len(expected_observations) :] | |
if len(hist_events) < len(expected_observations): | |
print( | |
f'Warning: Expected {len(expected_observations)} observations, but got {len(hist_events)}' | |
) | |
for i in range(min(len(expected_observations), len(hist_events))): | |
hist_obs = event_to_dict(hist_events[i]) | |
expected_obs = event_to_dict(expected_observations[i]) | |
# Remove dynamic fields for comparison | |
for obs in [hist_obs, expected_obs]: | |
obs.pop('id', None) | |
obs.pop('timestamp', None) | |
obs.pop('cause', None) | |
obs.pop('source', None) | |
if hist_obs != expected_obs: | |
print( | |
f'Warning: Observation mismatch. Expected {expected_obs}, got {hist_obs}' | |
) | |
return action | |