Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove while True in AgentController #5868

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open

Remove while True in AgentController #5868

wants to merge 23 commits into from

Conversation

rbren
Copy link
Collaborator

@rbren rbren commented Dec 27, 2024

End-user friendly description of the problem this fixes or functionality that this introduces

  • Include this change in the Release Notes. If checked, you must provide an end-user friendly description for your change below
    no changelog

Give a summary of what the PR does, explaining any non-trivial design decisions

The while True here is causing a lot of problems. It's easy for it to get stuck permanently.

Removing that loop is a surprisingly simple change--we just _step the agent whenever a new event comes in that it might react to. Haven't fully tested this yet but at first blush it's working well.

However, doing that surfaced a bunch of subtle issues with EventStream callbacks blocking each other, as well as main parts of the app. So now:

  • All events are added to a queue, which is processed in order
  • The queue is processed on its own thread
  • Every subscriber gets its own thread, with an asyncio loop set up for it

Link of any specific issues this addresses


To run this PR locally, use the following command:

docker run -it --rm   -p 3000:3000   -v /var/run/docker.sock:/var/run/docker.sock   --add-host host.docker.internal:host-gateway   -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:86e5632-nikolaik   --name openhands-app-86e5632   docker.all-hands.dev/all-hands-ai/openhands:86e5632

# no need to check too often
await asyncio.sleep(1)
else:
if self.delegate.get_agent_state() != AgentState.PAUSED:
await self._delegate_step()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please feel free to ignore, since this is a draft, just FYI when you get to test delegates: this whole bit with delegates became pointless. Because currently, the parent is unsubbed when the delegate starts, and the delegate subbed, and at the end of the delegate, the parent subscribes again. 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ugh this needs some love 😄

Are we still using delegation for the browser?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we have some code, but it's not in use. That tool is not defined. The two actions that CodeAct has, for browsing (interactive and text-only), are good. The second is crazy good. 😅

FWIW, using CodeAct as delegate (of another "planner" CodeAct) is a thing that has been tried, more than once, and in that example it has worked decently. IMO that PR was practically mergeable at some point. If it will be tried again, I think it would be nice to be able to support it. Hey I'm just adding a data point, in case you contemplate killing it! 😇

The old agents still work, including delegator. (Pretty amazing, considering they, erm, aren't really tested for a while afaik.🙊)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I had high hopes for delegation when we put it here! I still think it could be great, but I don't love the handshake we currently have

@rbren rbren marked this pull request as ready for review December 27, 2024 23:37
elif isinstance(event, Observation):
await self._handle_observation(event)
self.step()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this include obs like AgentChangeState or something which isn't supposed to interest the agent? It seems like it does

# No event loop running...
asyncio.run(self._async_add_event(event, source))

async def _async_add_event(self, event: Event, source: EventSource):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, we're back to a sync add_event? I do like it! I'm not sure why it had switched again 😅

except Exception as e:
traceback.print_exc()
self.log('error', f'Error while running the agent: {e}')
await self._react_to_exception(e)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a thought about what I don't see at a cursory look (on github interface):

  • do we still send status message to the UI on exception?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants