From d4e3982a6b9854c9b4f8e65239137b58c55d4a4a Mon Sep 17 00:00:00 2001 From: tofarr Date: Fri, 25 Oct 2024 11:31:20 -0600 Subject: [PATCH 1/7] Small refactor : EventStream as a dataclass (#4557) --- openhands/events/stream.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/openhands/events/stream.py b/openhands/events/stream.py index 8cff229c0518..1e4c3b9d5394 100644 --- a/openhands/events/stream.py +++ b/openhands/events/stream.py @@ -1,5 +1,6 @@ import asyncio import threading +from dataclasses import dataclass, field from datetime import datetime from enum import Enum from typing import Callable, Iterable @@ -29,24 +30,17 @@ def session_exists(sid: str, file_store: FileStore) -> bool: return False +@dataclass class EventStream: sid: str file_store: FileStore # For each subscriber ID, there is a stack of callback functions - useful # when there are agent delegates - _subscribers: dict[str, list[Callable]] - _cur_id: int - _lock: threading.Lock - - def __init__(self, sid: str, file_store: FileStore): - self.sid = sid - self.file_store = file_store - self._subscribers = {} - self._cur_id = 0 - self._lock = threading.Lock() - self._reinitialize_from_file_store() + _subscribers: dict[str, list[Callable]] = field(default_factory=dict) + _cur_id: int = 0 + _lock: threading.Lock = field(default_factory=threading.Lock) - def _reinitialize_from_file_store(self) -> None: + def __post_init__(self) -> None: try: events = self.file_store.list(f'sessions/{self.sid}/events') except FileNotFoundError: @@ -173,4 +167,4 @@ def clear(self): self.file_store.delete(f'sessions/{self.sid}') self._cur_id = 0 # self._subscribers = {} - self._reinitialize_from_file_store() + self.__post_init__() From 8bfd2fcf4f079ed37aca1845fa2a76c507bf6db7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2024 20:07:16 +0200 Subject: [PATCH 2/7] chore(deps): bump the version-all group across 1 directory with 8 updates (#4564) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 224 ++++++++++++++++++++++++++----------------------- pyproject.toml | 6 +- 2 files changed, 124 insertions(+), 106 deletions(-) diff --git a/poetry.lock b/poetry.lock index aede00a6fe46..20316ac24fe7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -585,17 +585,17 @@ files = [ [[package]] name = "boto3" -version = "1.35.46" +version = "1.35.48" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.35.46-py3-none-any.whl", hash = "sha256:a839ce09a844d92e0039f95851e88da9df80c89ebb4c7818b3e78247fd97a8a7"}, - {file = "boto3-1.35.46.tar.gz", hash = "sha256:c9bab807b372d5b076d6aeb1d6513131fa0b74e32d8895128f8568b6521296ea"}, + {file = "boto3-1.35.48-py3-none-any.whl", hash = "sha256:60889bb6e21f0af662ac9404e00125d3b8a5808f190e89462e5ddf73604adfc1"}, + {file = "boto3-1.35.48.tar.gz", hash = "sha256:5007a5cdd09e4db9309adf2ee090455a34ae639bd10a68a1fefca72cd77070fc"}, ] [package.dependencies] -botocore = ">=1.35.46,<1.36.0" +botocore = ">=1.35.48,<1.36.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -604,13 +604,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.35.46" +version = "1.35.48" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.35.46-py3-none-any.whl", hash = "sha256:8bbc9a55cae65a8db7f2e33ff087f4dbfc13fce868e8e3c5273ce9af367a555a"}, - {file = "botocore-1.35.46.tar.gz", hash = "sha256:8c0ff5fdd611a28f5752189d171c69690dbc484fa06d74376890bb0543ec3dc1"}, + {file = "botocore-1.35.48-py3-none-any.whl", hash = "sha256:34fa25fd717208b05745e60f271a39636108fa87a3512fbca18e7e6f787a3239"}, + {file = "botocore-1.35.48.tar.gz", hash = "sha256:3e766cc251053c9ef98542fdf225381ed58531769c3811a6282bd7247f7e2bdf"}, ] [package.dependencies] @@ -623,32 +623,50 @@ crt = ["awscrt (==0.22.0)"] [[package]] name = "browsergym" -version = "0.9.0" +version = "0.10.2" description = "BrowserGym: a gym environment for web task automation in the Chromium browser" optional = false python-versions = ">3.7" files = [ - {file = "browsergym-0.9.0-py3-none-any.whl", hash = "sha256:71bf43e12ae624e9077e0eb7f7d1b07acf1bd28de602ea49a162025e7ac5ea64"}, - {file = "browsergym-0.9.0.tar.gz", hash = "sha256:8faf68dea9d5c70f7e38456622ea570bd979ee0d29eab794a57361a8e986f27b"}, + {file = "browsergym-0.10.2-py3-none-any.whl", hash = "sha256:9581d1d1f1fcd1cf35266cf30c881d60c147a0d374b3491eeaebb07d9690f868"}, + {file = "browsergym-0.10.2.tar.gz", hash = "sha256:3cdd7520cca857421aa7ec0a965968df4bcef721299a424397f86d7cad078ab0"}, ] [package.dependencies] -browsergym-core = "0.9.0" -browsergym-experiments = "0.9.0" -browsergym-miniwob = "0.9.0" -browsergym-visualwebarena = "0.9.0" -browsergym-webarena = "0.9.0" +browsergym-assistantbench = "0.10.2" +browsergym-core = "0.10.2" +browsergym-experiments = "0.10.2" +browsergym-miniwob = "0.10.2" +browsergym-visualwebarena = "0.10.2" +browsergym-webarena = "0.10.2" browsergym-workarena = ">=0.4.1" +[[package]] +name = "browsergym-assistantbench" +version = "0.10.2" +description = "AssistantBench benchmark for BrowserGym" +optional = false +python-versions = ">3.7" +files = [ + {file = "browsergym_assistantbench-0.10.2-py3-none-any.whl", hash = "sha256:af0d3a3e23686066b070feca38f8740262bed6d65ccf9098f393334a005987c0"}, + {file = "browsergym_assistantbench-0.10.2.tar.gz", hash = "sha256:de18eb7c010403d5d467b927b4713b56f6e97a59493bee4c42599d4d7cb54dce"}, +] + +[package.dependencies] +browsergym-core = "0.10.2" +datasets = "*" +numpy = "*" +scipy = "*" + [[package]] name = "browsergym-core" -version = "0.9.0" +version = "0.10.2" description = "BrowserGym: a gym environment for web task automation in the Chromium browser" optional = false python-versions = ">3.9" files = [ - {file = "browsergym_core-0.9.0-py3-none-any.whl", hash = "sha256:4666a44d979816d50c72ed5fd528e5f4e49ef124719db52951bf82aa8826c1f9"}, - {file = "browsergym_core-0.9.0.tar.gz", hash = "sha256:a2bb5f5d27f8d418c6c3935f8020f1da8aa8956dd144b6a0608ebfe5ee764c28"}, + {file = "browsergym_core-0.10.2-py3-none-any.whl", hash = "sha256:0686a8e2ee7244e33c97326193f54df0ad08d99aad9a4ed9ac28baba5ca26d18"}, + {file = "browsergym_core-0.10.2.tar.gz", hash = "sha256:7e93bad5cc3990badee77e9481413d625d2fce2ec8f7f9e195dbc194b6cfb4e9"}, ] [package.dependencies] @@ -662,63 +680,63 @@ pyparsing = ">=3" [[package]] name = "browsergym-experiments" -version = "0.9.0" +version = "0.10.2" description = "Experimentation tools for BrowserGym" optional = false python-versions = ">3.7" files = [ - {file = "browsergym_experiments-0.9.0-py3-none-any.whl", hash = "sha256:91fda3f337ca94680c32c24f75a9700e460a4d760284ec2009dc192f53f9efcb"}, - {file = "browsergym_experiments-0.9.0.tar.gz", hash = "sha256:84a0b50c664764b51c3074d3c9fc74559a333ed1eb8e44020129a03c7fcff4de"}, + {file = "browsergym_experiments-0.10.2-py3-none-any.whl", hash = "sha256:60a626b3159ef63b5ff72a6c8156c8f3cf82a9278dfc5a9d3ece39c2b1913595"}, + {file = "browsergym_experiments-0.10.2.tar.gz", hash = "sha256:b49bc27f315ad12014ff21580c7c7aca6489ca4106e7ab46502f716674efa236"}, ] [package.dependencies] -browsergym-core = "0.9.0" +browsergym-core = "0.10.2" dataclasses-json = "*" tiktoken = ">=0.4" [[package]] name = "browsergym-miniwob" -version = "0.9.0" +version = "0.10.2" description = "MiniWoB++ benchmark for BrowserGym" optional = false python-versions = ">3.7" files = [ - {file = "browsergym_miniwob-0.9.0-py3-none-any.whl", hash = "sha256:7e3af816cb0a382543d64ab0e312dfedb9e4cb6d43a1b5230876358877b2626f"}, - {file = "browsergym_miniwob-0.9.0.tar.gz", hash = "sha256:e1e9fcebef9829b915581e3e845b37084b2036c7e8977173aebaf17b62d7adbb"}, + {file = "browsergym_miniwob-0.10.2-py3-none-any.whl", hash = "sha256:b11b04378868a8f5dee34f721134baed4780fd55ccaebf9db4de6fcac48f3190"}, + {file = "browsergym_miniwob-0.10.2.tar.gz", hash = "sha256:9109b8122a61b27e227d923861055f220c6ddd60f34f877c3a30444c6f8a7b05"}, ] [package.dependencies] -browsergym-core = "0.9.0" +browsergym-core = "0.10.2" [[package]] name = "browsergym-visualwebarena" -version = "0.9.0" +version = "0.10.2" description = "VisualWebArena benchmark for BrowserGym" optional = false python-versions = ">3.7" files = [ - {file = "browsergym_visualwebarena-0.9.0-py3-none-any.whl", hash = "sha256:e90f5092e0d0afdd124c068f2ee6e900b10fa44bc7074c00bcba6b38bdd3c710"}, - {file = "browsergym_visualwebarena-0.9.0.tar.gz", hash = "sha256:fc07a44d23d7d2eefb85c48553595226a7b98cbfb25b6bb2abf39e04f2bfcc38"}, + {file = "browsergym_visualwebarena-0.10.2-py3-none-any.whl", hash = "sha256:87c913ccd4d12a79c625b5c4d9ead7e0bc50b298d19e413204bb586a67736d83"}, + {file = "browsergym_visualwebarena-0.10.2.tar.gz", hash = "sha256:5f84a4f33a21106c9b650cecb0362b78af2546d9927255828c273fe800d776a1"}, ] [package.dependencies] -browsergym-core = "0.9.0" +browsergym-core = "0.10.2" libvisualwebarena = "0.0.14" requests = "*" [[package]] name = "browsergym-webarena" -version = "0.9.0" +version = "0.10.2" description = "WebArena benchmark for BrowserGym" optional = false python-versions = ">3.7" files = [ - {file = "browsergym_webarena-0.9.0-py3-none-any.whl", hash = "sha256:b959d2b64ec0bbfe815852d50391b7d177b8da0e9eef3b5951f33ace14f8260c"}, - {file = "browsergym_webarena-0.9.0.tar.gz", hash = "sha256:fd4c3152c1237186fbb1f3c634a72c2e455a7c11d23f7e35b033ef51ddd7d92f"}, + {file = "browsergym_webarena-0.10.2-py3-none-any.whl", hash = "sha256:e9ca6d0ad263412ebb229fe1b66e1ab7f5841a3f838abedf3bf01b800a7c6597"}, + {file = "browsergym_webarena-0.10.2.tar.gz", hash = "sha256:b4b9a38f144b6aaa56bbbbce9dd2c5565a39a1b55e3647d61e02458ca3f5fd24"}, ] [package.dependencies] -browsergym-core = "0.9.0" +browsergym-core = "0.10.2" libwebarena = "0.0.3" [[package]] @@ -3880,13 +3898,13 @@ types-tqdm = "*" [[package]] name = "litellm" -version = "1.50.2" +version = "1.50.4" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.50.2-py3-none-any.whl", hash = "sha256:99cac60c78037946ab809b7cfbbadad53507bb2db8ae39391b4be215a0869fdd"}, - {file = "litellm-1.50.2.tar.gz", hash = "sha256:b244c9a0e069cc626b85fb9f5cc252114aaff1225500da30ce0940f841aef8ea"}, + {file = "litellm-1.50.4-py3-none-any.whl", hash = "sha256:cc6992275e24a0bbb4a3b377e6842d45a8510fc85d7f255930a64bb872980a36"}, + {file = "litellm-1.50.4.tar.gz", hash = "sha256:a7e68ef614f631b58969c2c7a5154a565ba5974558d437c8cd6c8623654880ea"}, ] [package.dependencies] @@ -4656,13 +4674,13 @@ files = [ [[package]] name = "minio" -version = "7.2.9" +version = "7.2.10" description = "MinIO Python SDK for Amazon S3 Compatible Cloud Storage" optional = false python-versions = ">3.8" files = [ - {file = "minio-7.2.9-py3-none-any.whl", hash = "sha256:fe5523d9c4a4d6cfc07e96905852841bccdb22b22770e1efca4bf5ae8b65774b"}, - {file = "minio-7.2.9.tar.gz", hash = "sha256:a83c2fcd981944602a8dc11e8e07543ed9cda0a9462264e3f46a13171c56bccb"}, + {file = "minio-7.2.10-py3-none-any.whl", hash = "sha256:5961c58192b1d70d3a2a362064b8e027b8232688998a6d1251dadbb02ab57a7d"}, + {file = "minio-7.2.10.tar.gz", hash = "sha256:418c31ac79346a580df04a0e14db1becbc548a6e7cca61f9bc4ef3bcd336c449"}, ] [package.dependencies] @@ -4798,12 +4816,12 @@ type = ["mypy (==1.11.2)"] [[package]] name = "modal" -version = "0.64.216" +version = "0.64.230" description = "Python client library for Modal" optional = false python-versions = ">=3.8" files = [ - {file = "modal-0.64.216-py3-none-any.whl", hash = "sha256:ca47322e8f01a1dedf88485b928afd74df60924cee27d20c4f9672a6bd9f47cf"}, + {file = "modal-0.64.230-py3-none-any.whl", hash = "sha256:d432fdc425cac4bd27853c55e7dae850f18bfeba765ab7c7b45309936ee5996f"}, ] [package.dependencies] @@ -5561,13 +5579,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.52.1" +version = "1.52.2" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.52.1-py3-none-any.whl", hash = "sha256:f23e83df5ba04ee0e82c8562571e8cb596cd88f9a84ab783e6c6259e5ffbfb4a"}, - {file = "openai-1.52.1.tar.gz", hash = "sha256:383b96c7e937cbec23cad5bf5718085381e4313ca33c5c5896b54f8e1b19d144"}, + {file = "openai-1.52.2-py3-none-any.whl", hash = "sha256:57e9e37bc407f39bb6ec3a27d7e8fb9728b2779936daa1fcf95df17d3edfaccc"}, + {file = "openai-1.52.2.tar.gz", hash = "sha256:87b7d0f69d85f5641678d414b7ee3082363647a5c66a462ed7f3ccb59582da0d"}, ] [package.dependencies] @@ -7706,29 +7724,29 @@ pyasn1 = ">=0.1.3" [[package]] name = "ruff" -version = "0.7.0" +version = "0.7.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.0-py3-none-linux_armv6l.whl", hash = "sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628"}, - {file = "ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737"}, - {file = "ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11"}, - {file = "ruff-0.7.0-py3-none-win32.whl", hash = "sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec"}, - {file = "ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2"}, - {file = "ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e"}, - {file = "ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b"}, + {file = "ruff-0.7.1-py3-none-linux_armv6l.whl", hash = "sha256:cb1bc5ed9403daa7da05475d615739cc0212e861b7306f314379d958592aaa89"}, + {file = "ruff-0.7.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27c1c52a8d199a257ff1e5582d078eab7145129aa02721815ca8fa4f9612dc35"}, + {file = "ruff-0.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:588a34e1ef2ea55b4ddfec26bbe76bc866e92523d8c6cdec5e8aceefeff02d99"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94fc32f9cdf72dc75c451e5f072758b118ab8100727168a3df58502b43a599ca"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:985818742b833bffa543a84d1cc11b5e6871de1b4e0ac3060a59a2bae3969250"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32f1e8a192e261366c702c5fb2ece9f68d26625f198a25c408861c16dc2dea9c"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:699085bf05819588551b11751eff33e9ca58b1b86a6843e1b082a7de40da1565"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344cc2b0814047dc8c3a8ff2cd1f3d808bb23c6658db830d25147339d9bf9ea7"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4316bbf69d5a859cc937890c7ac7a6551252b6a01b1d2c97e8fc96e45a7c8b4a"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5c121b46abde94a505175524e51891f829414e093cd8326d6e741ecfc0a9112"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8422104078324ea250886954e48f1373a8fe7de59283d747c3a7eca050b4e378"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:56aad830af8a9db644e80098fe4984a948e2b6fc2e73891538f43bbe478461b8"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:658304f02f68d3a83c998ad8bf91f9b4f53e93e5412b8f2388359d55869727fd"}, + {file = "ruff-0.7.1-py3-none-win32.whl", hash = "sha256:b517a2011333eb7ce2d402652ecaa0ac1a30c114fbbd55c6b8ee466a7f600ee9"}, + {file = "ruff-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307"}, + {file = "ruff-0.7.1-py3-none-win_arm64.whl", hash = "sha256:19aa200ec824c0f36d0c9114c8ec0087082021732979a359d6f3c390a6ff2a37"}, + {file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"}, ] [[package]] @@ -10022,48 +10040,48 @@ test = ["zope.testrunner"] [[package]] name = "zope-interface" -version = "7.1.0" +version = "7.1.1" description = "Interfaces for Python" optional = false python-versions = ">=3.8" files = [ - {file = "zope.interface-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2bd9e9f366a5df08ebbdc159f8224904c1c5ce63893984abb76954e6fbe4381a"}, - {file = "zope.interface-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:661d5df403cd3c5b8699ac480fa7f58047a3253b029db690efa0c3cf209993ef"}, - {file = "zope.interface-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91b6c30689cfd87c8f264acb2fc16ad6b3c72caba2aec1bf189314cf1a84ca33"}, - {file = "zope.interface-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b6a4924f5bad9fe21d99f66a07da60d75696a136162427951ec3cb223a5570d"}, - {file = "zope.interface-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80a3c00b35f6170be5454b45abe2719ea65919a2f09e8a6e7b1362312a872cd3"}, - {file = "zope.interface-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:b936d61dbe29572fd2cfe13e30b925e5383bed1aba867692670f5a2a2eb7b4e9"}, - {file = "zope.interface-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0ac20581fc6cd7c754f6dff0ae06fedb060fa0e9ea6309d8be8b2701d9ea51c4"}, - {file = "zope.interface-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:848b6fa92d7c8143646e64124ed46818a0049a24ecc517958c520081fd147685"}, - {file = "zope.interface-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1ef1fdb6f014d5886b97e52b16d0f852364f447d2ab0f0c6027765777b6667"}, - {file = "zope.interface-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bcff5c09d0215f42ba64b49205a278e44413d9bf9fa688fd9e42bfe472b5f4f"}, - {file = "zope.interface-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07add15de0cc7e69917f7d286b64d54125c950aeb43efed7a5ea7172f000fbc1"}, - {file = "zope.interface-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:9940d5bc441f887c5f375ec62bcf7e7e495a2d5b1da97de1184a88fb567f06af"}, - {file = "zope.interface-7.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f245d039f72e6f802902375755846f5de1ee1e14c3e8736c078565599bcab621"}, - {file = "zope.interface-7.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6159e767d224d8f18deff634a1d3722e68d27488c357f62ebeb5f3e2f5288b1f"}, - {file = "zope.interface-7.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e956b1fd7f3448dd5e00f273072e73e50dfafcb35e4227e6d5af208075593c9"}, - {file = "zope.interface-7.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff115ef91c0eeac69cd92daeba36a9d8e14daee445b504eeea2b1c0b55821984"}, - {file = "zope.interface-7.1.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bec001798ab62c3fc5447162bf48496ae9fba02edc295a9e10a0b0c639a6452e"}, - {file = "zope.interface-7.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:124149e2d42067b9c6597f4dafdc7a0983d0163868f897b7bb5dc850b14f9a87"}, - {file = "zope.interface-7.1.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:9733a9a0f94ef53d7aa64661811b20875b5bc6039034c6e42fb9732170130573"}, - {file = "zope.interface-7.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5fcf379b875c610b5a41bc8a891841533f98de0520287d7f85e25386cd10d3e9"}, - {file = "zope.interface-7.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0a45b5af9f72c805ee668d1479480ca85169312211bed6ed18c343e39307d5f"}, - {file = "zope.interface-7.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af4a12b459a273b0b34679a5c3dc5e34c1847c3dd14a628aa0668e19e638ea2"}, - {file = "zope.interface-7.1.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a735f82d2e3ed47ca01a20dfc4c779b966b16352650a8036ab3955aad151ed8a"}, - {file = "zope.interface-7.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:5501e772aff595e3c54266bc1bfc5858e8f38974ce413a8f1044aae0f32a83a3"}, - {file = "zope.interface-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec59fe53db7d32abb96c6d4efeed84aab4a7c38c62d7a901a9b20c09dd936e7a"}, - {file = "zope.interface-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e53c291debef523b09e1fe3dffe5f35dde164f1c603d77f770b88a1da34b7ed6"}, - {file = "zope.interface-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:711eebc77f2092c6a8b304bad0b81a6ce3cf5490b25574e7309fbc07d881e3af"}, - {file = "zope.interface-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a00ead2e24c76436e1b457a5132d87f83858330f6c923640b7ef82d668525d1"}, - {file = "zope.interface-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e28ea0bc4b084fc93a483877653a033062435317082cdc6388dec3438309faf"}, - {file = "zope.interface-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:27cfb5205d68b12682b6e55ab8424662d96e8ead19550aad0796b08dd2c9a45e"}, - {file = "zope.interface-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e3e48f3dea21c147e1b10c132016cb79af1159facca9736d231694ef5a740a8"}, - {file = "zope.interface-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a99240b1d02dc469f6afbe7da1bf617645e60290c272968f4e53feec18d7dce8"}, - {file = "zope.interface-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc8a318162123eddbdf22fcc7b751288ce52e4ad096d3766ff1799244352449d"}, - {file = "zope.interface-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7b25db127db3e6b597c5f74af60309c4ad65acd826f89609662f0dc33a54728"}, - {file = "zope.interface-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a29ac607e970b5576547f0e3589ec156e04de17af42839eedcf478450687317"}, - {file = "zope.interface-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:a14c9decf0eb61e0892631271d500c1e306c7b6901c998c7035e194d9150fdd1"}, - {file = "zope_interface-7.1.0.tar.gz", hash = "sha256:3f005869a1a05e368965adb2075f97f8ee9a26c61898a9e52a9764d93774f237"}, + {file = "zope.interface-7.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6650bd56ef350d37c8baccfd3ee8a0483ed6f8666e641e4b9ae1a1827b79f9e5"}, + {file = "zope.interface-7.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84e87eba6b77a3af187bae82d8de1a7c208c2a04ec9f6bd444fd091b811ad92e"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c4e1b4c06d9abd1037c088dae1566c85f344a3e6ae4350744c3f7f7259d9c67"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cd5e3d910ac87652a09f6e5db8e41bc3b49cf08ddd2d73d30afc644801492cd"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca95594d936ee349620900be5b46c0122a1ff6ce42d7d5cb2cf09dc84071ef16"}, + {file = "zope.interface-7.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:ad339509dcfbbc99bf8e147db6686249c4032f26586699ec4c82f6e5909c9fe2"}, + {file = "zope.interface-7.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e59f175e868f856a77c0a77ba001385c377df2104fdbda6b9f99456a01e102a"}, + {file = "zope.interface-7.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0de23bcb93401994ea00bc5c677ef06d420340ac0a4e9c10d80e047b9ce5af3f"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdb7e7e5524b76d3ec037c1d81a9e2c7457b240fd4cb0a2476b65c3a5a6c81f"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3603ef82a9920bd0bfb505423cb7e937498ad971ad5a6141841e8f76d2fd5446"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1d52d052355e0c5c89e0630dd2ff7c0b823fd5f56286a663e92444761b35e25"}, + {file = "zope.interface-7.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:179ad46ece518c9084cb272e4a69d266b659f7f8f48e51706746c2d8a426433e"}, + {file = "zope.interface-7.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e6503534b52bb1720ace9366ee30838a58a3413d3e197512f3338c8f34b5d89d"}, + {file = "zope.interface-7.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f85b290e5b8b11814efb0d004d8ce6c9a483c35c462e8d9bf84abb93e79fa770"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d029fac6a80edae80f79c37e5e3abfa92968fe921886139b3ee470a1b177321a"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5836b8fb044c6e75ba34dfaabc602493019eadfa0faf6ff25f4c4c356a71a853"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7395f13533318f150ee72adb55b29284b16e73b6d5f02ab21f173b3e83f242b8"}, + {file = "zope.interface-7.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:1d0e23c6b746eb8ce04573cc47bcac60961ac138885d207bd6f57e27a1431ae8"}, + {file = "zope.interface-7.1.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:9fad9bd5502221ab179f13ea251cb30eef7cf65023156967f86673aff54b53a0"}, + {file = "zope.interface-7.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:55c373becbd36a44d0c9be1d5271422fdaa8562d158fb44b4192297b3c67096c"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed1df8cc01dd1e3970666a7370b8bfc7457371c58ba88c57bd5bca17ab198053"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99c14f0727c978639139e6cad7a60e82b7720922678d75aacb90cf4ef74a068c"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b1eed7670d564f1025d7cda89f99f216c30210e42e95de466135be0b4a499d9"}, + {file = "zope.interface-7.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:3defc925c4b22ac1272d544a49c6ba04c3eefcce3200319ee1be03d9270306dd"}, + {file = "zope.interface-7.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8d0fe45be57b5219aa4b96e846631c04615d5ef068146de5a02ccd15c185321f"}, + {file = "zope.interface-7.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bcbeb44fc16e0078b3b68a95e43f821ae34dcbf976dde6985141838a5f23dd3d"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8e7b05dc6315a193cceaec071cc3cf1c180cea28808ccded0b1283f1c38ba73"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d553e02b68c0ea5a226855f02edbc9eefd99f6a8886fa9f9bdf999d77f46585"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81744a7e61b598ebcf4722ac56a7a4f50502432b5b4dc7eb29075a89cf82d029"}, + {file = "zope.interface-7.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:7720322763aceb5e0a7cadcc38c67b839efe599f0887cbf6c003c55b1458c501"}, + {file = "zope.interface-7.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ed0852c25950cf430067f058f8d98df6288502ac313861d9803fe7691a9b3"}, + {file = "zope.interface-7.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9595e478047ce752b35cfa221d7601a5283ccdaab40422e0dc1d4a334c70f580"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2317e1d4dba68203a5227ea3057f9078ec9376275f9700086b8f0ffc0b358e1b"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6821ef9870f32154da873fcde439274f99814ea452dd16b99fa0b66345c4b6b"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:190eeec67e023d5aac54d183fa145db0b898664234234ac54643a441da434616"}, + {file = "zope.interface-7.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:d17e7fc814eaab93409b80819fd6d30342844345c27f3bc3c4b43c2425a8d267"}, + {file = "zope.interface-7.1.1.tar.gz", hash = "sha256:4284d664ef0ff7b709836d4de7b13d80873dc5faeffc073abdb280058bfac5e3"}, ] [package.dependencies] @@ -10077,4 +10095,4 @@ testing = ["coverage[toml]", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "a49f87851aeffcff101ee23015674a9879472c8099dfcc258f46f599861f49b4" +content-hash = "aeb09e429a789c3f8ced605e7e1a5932fd6cce7f7f4ce30a960da77fba18b9a3" diff --git a/pyproject.toml b/pyproject.toml index 5561be6a354c..393bab9594dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ uvicorn = "*" types-toml = "*" numpy = "*" json-repair = "*" -browsergym = "0.9.0" # integrate browsergym as the browsing interface +browsergym = "0.10.2" # integrate browsergym as the browsing interface html2text = "*" e2b = "^0.17.1" pexpect = "*" @@ -36,7 +36,7 @@ minio = "^7.2.8" gevent = "^24.2.1" pyarrow = "17.0.0" # transitive dependency, pinned here to avoid conflicts tenacity = "^8.5.0" -zope-interface = "7.1.0" +zope-interface = "7.1.1" pathspec = "^0.12.1" google-cloud-aiplatform = "*" anthropic = {extras = ["vertex"], version = "*"} @@ -69,7 +69,7 @@ llama-index-embeddings-azure-openai = "*" llama-index-embeddings-ollama = "*" [tool.poetry.group.dev.dependencies] -ruff = "0.7.0" +ruff = "0.7.1" mypy = "1.13.0" pre-commit = "4.0.1" build = "*" From be3cbb045e98265847fc0b5241566c675ae6a07a Mon Sep 17 00:00:00 2001 From: Xingyao Wang Date: Sat, 26 Oct 2024 13:28:27 -0500 Subject: [PATCH 3/7] fix(controllor): make agent controller stops when encounter fatal observation (#4573) --- openhands/controller/agent_controller.py | 6 +-- tests/unit/test_agent_controller.py | 58 +++++++++++++++++++++++- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/openhands/controller/agent_controller.py b/openhands/controller/agent_controller.py index 946f6a7d327f..d40cf1bf37d7 100644 --- a/openhands/controller/agent_controller.py +++ b/openhands/controller/agent_controller.py @@ -254,11 +254,11 @@ async def _handle_observation(self, observation: Observation): if self.state.agent_state == AgentState.ERROR: self.state.metrics.merge(self.state.local_metrics) elif isinstance(observation, FatalErrorObservation): - await self.report_error( - 'There was a fatal error during agent execution: ' + str(observation) + self.state.last_error = ( + f'There was a fatal error during agent execution: {str(observation)}' ) - await self.set_agent_state_to(AgentState.ERROR) self.state.metrics.merge(self.state.local_metrics) + await self.set_agent_state_to(AgentState.ERROR) async def _handle_message_action(self, action: MessageAction): """Handles message actions from the event stream. diff --git a/tests/unit/test_agent_controller.py b/tests/unit/test_agent_controller.py index fbaa225c9071..2a4e6d86acbf 100644 --- a/tests/unit/test_agent_controller.py +++ b/tests/unit/test_agent_controller.py @@ -6,10 +6,17 @@ from openhands.controller.agent import Agent from openhands.controller.agent_controller import AgentController from openhands.controller.state.state import TrafficControlState +from openhands.core.config import AppConfig from openhands.core.exceptions import LLMMalformedActionError +from openhands.core.main import run_controller from openhands.core.schema import AgentState -from openhands.events import EventStream -from openhands.events.action import ChangeAgentStateAction, MessageAction +from openhands.events import Event, EventSource, EventStream, EventStreamSubscriber +from openhands.events.action import ChangeAgentStateAction, CmdRunAction, MessageAction +from openhands.events.observation import FatalErrorObservation +from openhands.llm import LLM +from openhands.llm.metrics import Metrics +from openhands.runtime.base import Runtime +from openhands.storage import get_file_store @pytest.fixture @@ -123,6 +130,53 @@ async def test_step_with_exception(mock_agent, mock_event_stream): await controller.close() +@pytest.mark.asyncio +async def test_run_controller_with_fatal_error(mock_agent, mock_event_stream): + config = AppConfig() + file_store = get_file_store(config.file_store, config.file_store_path) + event_stream = EventStream(sid='test', file_store=file_store) + + agent = MagicMock(spec=Agent) + # a random message to send to the runtime + event = CmdRunAction(command='ls') + agent.step.return_value = event + agent.llm = MagicMock(spec=LLM) + agent.llm.metrics = Metrics() + agent.llm.config = config.get_llm_config() + + fatal_error_obs = FatalErrorObservation('Fatal error detected') + fatal_error_obs._cause = event.id + + runtime = MagicMock(spec=Runtime) + + async def on_event(event: Event): + if isinstance(event, CmdRunAction): + await event_stream.async_add_event(fatal_error_obs, EventSource.USER) + + event_stream.subscribe(EventStreamSubscriber.RUNTIME, on_event) + runtime.event_stream = event_stream + + state = await run_controller( + config=config, + initial_user_action=MessageAction(content='Test message'), + runtime=runtime, + sid='test', + agent=agent, + fake_user_response_fn=lambda _: 'repeat', + ) + print(f'state: {state}') + print(f'event_stream: {list(event_stream.get_events())}') + assert state.iteration == 1 + # it will first become AgentState.ERROR, then become AgentState.STOPPED + # in side run_controller (since the while loop + sleep no longer loop) + assert state.agent_state == AgentState.STOPPED + assert ( + state.last_error + == 'There was a fatal error during agent execution: **FatalErrorObservation**\nFatal error detected' + ) + assert len(list(event_stream.get_events())) == 5 + + @pytest.mark.asyncio @pytest.mark.parametrize( 'delegate_state', From 98d4884ced8ce0a47f2804ef9b204e514202f309 Mon Sep 17 00:00:00 2001 From: Xingyao Wang Date: Sat, 26 Oct 2024 19:40:58 -0500 Subject: [PATCH 4/7] fix(controller): stop when run into loop (#4579) --- openhands/controller/agent_controller.py | 16 +++-- tests/unit/test_agent_controller.py | 78 +++++++++++++++++++++++- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/openhands/controller/agent_controller.py b/openhands/controller/agent_controller.py index d40cf1bf37d7..0171959c5a21 100644 --- a/openhands/controller/agent_controller.py +++ b/openhands/controller/agent_controller.py @@ -403,9 +403,20 @@ async def _step(self) -> None: return if self._pending_action: + logger.debug( + f'{self.agent.name} LEVEL {self.state.delegate_level} LOCAL STEP {self.state.local_iteration} GLOBAL STEP {self.state.iteration} awaiting pending action to get executed: {self._pending_action}' + ) await asyncio.sleep(1) return + # check if agent got stuck before taking any action + if self._is_stuck(): + # This need to go BEFORE report_error to sync metrics + self.event_stream.add_event( + FatalErrorObservation('Agent got stuck in a loop'), EventSource.USER + ) + return + if self.delegate is not None: assert self.delegate != self if self.delegate.get_agent_state() == AgentState.PAUSED: @@ -467,11 +478,6 @@ async def _step(self) -> None: await self.update_state_after_step() logger.info(action, extra={'msg_type': 'ACTION'}) - if self._is_stuck(): - # This need to go BEFORE report_error to sync metrics - await self.set_agent_state_to(AgentState.ERROR) - await self.report_error('Agent got stuck in a loop') - async def _delegate_step(self): """Executes a single step of the delegate agent.""" logger.debug(f'[Agent Controller {self.id}] Delegate not none, awaiting...') diff --git a/tests/unit/test_agent_controller.py b/tests/unit/test_agent_controller.py index 2a4e6d86acbf..9b0522302f9f 100644 --- a/tests/unit/test_agent_controller.py +++ b/tests/unit/test_agent_controller.py @@ -12,7 +12,11 @@ from openhands.core.schema import AgentState from openhands.events import Event, EventSource, EventStream, EventStreamSubscriber from openhands.events.action import ChangeAgentStateAction, CmdRunAction, MessageAction -from openhands.events.observation import FatalErrorObservation +from openhands.events.observation import ( + ErrorObservation, + FatalErrorObservation, +) +from openhands.events.serialization import event_to_dict from openhands.llm import LLM from openhands.llm.metrics import Metrics from openhands.runtime.base import Runtime @@ -177,6 +181,78 @@ async def on_event(event: Event): assert len(list(event_stream.get_events())) == 5 +@pytest.mark.asyncio +async def test_run_controller_stop_with_stuck(mock_agent, mock_event_stream): + config = AppConfig() + file_store = get_file_store(config.file_store, config.file_store_path) + event_stream = EventStream(sid='test', file_store=file_store) + + agent = MagicMock(spec=Agent) + # a random message to send to the runtime + event = CmdRunAction(command='ls') + + def agent_step_fn(state): + print(f'agent_step_fn received state: {state}') + return event + + agent.step = agent_step_fn + agent.llm = MagicMock(spec=LLM) + agent.llm.metrics = Metrics() + agent.llm.config = config.get_llm_config() + runtime = MagicMock(spec=Runtime) + + async def on_event(event: Event): + if isinstance(event, CmdRunAction): + non_fatal_error_obs = ErrorObservation( + 'Non fatal error here to trigger loop' + ) + non_fatal_error_obs._cause = event.id + await event_stream.async_add_event(non_fatal_error_obs, EventSource.USER) + + event_stream.subscribe(EventStreamSubscriber.RUNTIME, on_event) + runtime.event_stream = event_stream + + state = await run_controller( + config=config, + initial_user_action=MessageAction(content='Test message'), + runtime=runtime, + sid='test', + agent=agent, + fake_user_response_fn=lambda _: 'repeat', + ) + events = list(event_stream.get_events()) + print(f'state: {state}') + for i, event in enumerate(events): + print(f'event {i}: {event_to_dict(event)}') + + assert state.iteration == 4 + assert len(events) == 12 + # check the eventstream have 4 pairs of repeated actions and observations + repeating_actions_and_observations = events[2:10] + for action, observation in zip( + repeating_actions_and_observations[0::2], + repeating_actions_and_observations[1::2], + ): + action_dict = event_to_dict(action) + observation_dict = event_to_dict(observation) + assert action_dict['action'] == 'run' and action_dict['args']['command'] == 'ls' + assert ( + observation_dict['observation'] == 'error' + and observation_dict['content'] == 'Non fatal error here to trigger loop' + ) + last_event = event_to_dict(events[-1]) + assert last_event['extras']['agent_state'] == 'error' + assert last_event['observation'] == 'agent_state_changed' + + # it will first become AgentState.ERROR, then become AgentState.STOPPED + # in side run_controller (since the while loop + sleep no longer loop) + assert state.agent_state == AgentState.STOPPED + assert ( + state.last_error + == 'There was a fatal error during agent execution: **FatalErrorObservation**\nAgent got stuck in a loop' + ) + + @pytest.mark.asyncio @pytest.mark.parametrize( 'delegate_state', From 5ba7bc6be1884e4fc6529f54349cbae8ef712dfa Mon Sep 17 00:00:00 2001 From: "Ryan H. Tran" Date: Sun, 27 Oct 2024 08:17:43 +0700 Subject: [PATCH 5/7] Mention `build-essential` dependency for ubuntu in dev doc (#4511) --- Development.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Development.md b/Development.md index 8538c2a0612e..ef3ca78e861c 100644 --- a/Development.md +++ b/Development.md @@ -5,12 +5,14 @@ Otherwise, you can clone the OpenHands project directly. ## Start the server for development ### 1. Requirements -* Linux, Mac OS, or [WSL on Windows](https://learn.microsoft.com/en-us/windows/wsl/install) [ Ubuntu <= 22.04] +* Linux, Mac OS, or [WSL on Windows](https://learn.microsoft.com/en-us/windows/wsl/install) [Ubuntu <= 22.04] * [Docker](https://docs.docker.com/engine/install/) (For those on MacOS, make sure to allow the default Docker socket to be used from advanced settings!) * [Python](https://www.python.org/downloads/) = 3.12 * [NodeJS](https://nodejs.org/en/download/package-manager) >= 18.17.1 * [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer) >= 1.8 -* netcat => sudo apt-get install netcat +* OS-specific dependencies: + - Ubuntu: build-essential => `sudo apt-get install build-essential` + - WSL: netcat => `sudo apt-get install netcat` Make sure you have all these dependencies installed before moving on to `make build`. From 2a6740f4ba904801090def5508d30ec1e432ced7 Mon Sep 17 00:00:00 2001 From: Mahmoud Sehsah <46302138+msehsah1@users.noreply.github.com> Date: Sat, 26 Oct 2024 21:54:52 -0400 Subject: [PATCH 6/7] fix(builder): Build the runtime with docker version that contains (-) in the version name (#4580) --- openhands/runtime/builder/docker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openhands/runtime/builder/docker.py b/openhands/runtime/builder/docker.py index 09f94f103dff..5a22302d61d5 100644 --- a/openhands/runtime/builder/docker.py +++ b/openhands/runtime/builder/docker.py @@ -16,7 +16,7 @@ def __init__(self, docker_client: docker.DockerClient): self.docker_client = docker_client version_info = self.docker_client.version() - server_version = version_info.get('Version', '') + server_version = version_info.get('Version', '').replace('-', '.') if tuple(map(int, server_version.split('.'))) < (18, 9): raise RuntimeError('Docker server version must be >= 18.09 to use BuildKit') @@ -53,7 +53,7 @@ def build( """ self.docker_client = docker.from_env() version_info = self.docker_client.version() - server_version = version_info.get('Version', '') + server_version = version_info.get('Version', '').replace('-', '.') if tuple(map(int, server_version.split('.'))) < (18, 9): raise RuntimeError('Docker server version must be >= 18.09 to use BuildKit') From a20da54e3afd498027fc4eaa1c5cae6fb37ba9dd Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Sun, 27 Oct 2024 11:50:23 -0400 Subject: [PATCH 7/7] Remove verbose log from agent controller (#4585) --- openhands/controller/agent_controller.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openhands/controller/agent_controller.py b/openhands/controller/agent_controller.py index 0171959c5a21..0660cd030909 100644 --- a/openhands/controller/agent_controller.py +++ b/openhands/controller/agent_controller.py @@ -403,9 +403,6 @@ async def _step(self) -> None: return if self._pending_action: - logger.debug( - f'{self.agent.name} LEVEL {self.state.delegate_level} LOCAL STEP {self.state.local_iteration} GLOBAL STEP {self.state.iteration} awaiting pending action to get executed: {self._pending_action}' - ) await asyncio.sleep(1) return