feat: terminate BrowserToolkit to allow rerun
Description
A step to remedy camel-ai/owl#449 thus https://github.com/camel-ai/owl/pull/450.
Playwright driver supports Async and Sync mode. Current BrowserToolkit is running in sync mode not async (see #1886). NotImplementedError is being thrown when trying to rerun OWL instance which is an error extensively discussed in microsoft/playwright-python#462, which seem to be caused by asyncio and Playwright sync version conflicts. But I will show you that this issue maynot look as it seems.
In my journey to fix "Building Society issue" related to Stop OWL Feature (see https://github.com/camel-ai/owl/pull/450), I discovered that the NotImplementedError issue traces back to BrowserTookit reinstantiation in construct_society():
*BrowserToolkit(
headless=False, # Set to True for headless mode
web_agent_model=models["browsing"],
planning_agent_model=models["planning"],
).get_tools(),
While debugging, an Attribute Error exception was thrown when self.browser.close() was called before self.browser.init(). Thus the first commit.
Why _terminate() (Commit No.2)?
To demonstrate, Try to paste then run this code in browser_toolkit.py:
def test_sequential_browsers():
from dotenv import load_dotenv
from camel.models import ModelFactory
from camel.types import ModelPlatformType, ModelType
load_dotenv(dotenv_path="C:/Users/ASUS/camel/.env")
"""Test if we can initialize and use two browser instances sequentially."""
print("Starting sequential browser test...")
# First browser instance
print("\n=== BROWSER INSTANCE #1 ===")
models = {
"browsing": ModelFactory.create(
model_platform=ModelPlatformType.GEMINI,
model_type=ModelType.GEMINI_2_5_PRO_EXP,
model_config_dict={"temperature": 0},
),
"planning": ModelFactory.create(
model_platform=ModelPlatformType.GEMINI,
model_type=ModelType.GEMINI_2_5_PRO_EXP,
model_config_dict={"temperature": 0},
),
}
browser1 = BrowserToolkit(
headless=False,
web_agent_model=models["browsing"],
planning_agent_model=models["planning"],
)
print("Initialized first")
browser1.browser.init()
browser1.browser.close()
# browser1._terminate()
browser2 = BrowserToolkit(
headless=False,
web_agent_model=models["browsing"],
planning_agent_model=models["planning"],
)
browser2.browser.init()
# browser2._terminate()
print("Initialized second")
print(
"\nBoth browser instances have been initialized and closed successfully!"
)
if __name__ == "__main__":
test_sequential_browsers()
The above code should throw an error such as below. To fix the error below, uncomment # browser1._terminate() in between the instances. Playwright has a stop() function as in docs, thus it seems that you should stop() playwright before creating a new instance (at least in the sync mode).
playwright._impl._errors.Error: It looks like you are using Playwright Sync API inside the asyncio loop.
Please use the Async API instead.
This is a step to fix the OWL error by drilling down the _terminate() function then calling it on OWL completion, but is still not complete on OWL's Termination edge cases, which I am polishing (see https://github.com/camel-ai/owl/pull/450).
Checklist
Go over all the following points, and put an x in all the boxes that apply.
- [x] I have read the CONTRIBUTION guide (required)
- [x] I have linked this PR to an issue using the Development section on the right sidebar or by adding
Fixes #issue-numberin the PR description (required) - [x] I have checked if any dependencies need to be added or updated in
pyproject.tomlanduv lock - [ ] I have updated the tests accordingly (required for a bug fix or a new feature)
- [ ] I have updated the documentation if needed:
- [ ] I have added examples if this is a new feature
If you are unsure about any of these, don't hesitate to ask. We are here to help!
TLDR;
- Added _terminate() function for proper Playwright Termination -- To see the usefuless, copy and paste the code in browser_toolkit()
- Fix Attribute Error in close() function