ai-dev-browser 0.9.2__tar.gz → 0.9.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/PKG-INFO +1 -1
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/pool/job.py +49 -1
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/pool/pool.py +30 -9
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser.egg-info/PKG-INFO +1 -1
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/.github/workflows/ci.yml +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/.github/workflows/publish.yml +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/.gitignore +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/.gitmodules +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/.pre-commit-config.yaml +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/.secrets.baseline +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/LICENSE +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/README.md +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/__init__.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/_cli.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/_version.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/__init__.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/accessibility.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/animation.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/audits.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/autofill.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/background_service.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/bluetooth_emulation.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/browser.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/cache_storage.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/cast.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/console.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/crash_report_context.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/css.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/debugger.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/device_access.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/device_orientation.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/dom.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/dom_debugger.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/dom_snapshot.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/dom_storage.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/emulation.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/event_breakpoints.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/extensions.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/fed_cm.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/fetch.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/file_system.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/headless_experimental.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/heap_profiler.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/indexed_db.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/input_.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/inspector.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/io.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/layer_tree.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/log.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/media.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/memory.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/network.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/overlay.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/page.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/performance.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/performance_timeline.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/preload.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/profiler.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/pwa.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/py.typed +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/runtime.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/schema.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/security.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/service_worker.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/smart_card_emulation.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/storage.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/system_info.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/target.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/tethering.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/tracing.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/util.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/web_audio.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/web_authn.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/cdp/web_mcp.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/__init__.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/_case.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/_element.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/_tab.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/_transport.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/ax.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/browser.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/cdp.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/chrome.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/cleanup.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/config.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/connection.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/cookies.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/dialog.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/download.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/elements.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/human.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/login.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/mouse.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/navigation.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/overlays.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/page.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/port.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/process.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/snapshot.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/storage.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/tabs.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/text_match.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/core/window.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/pool/__init__.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/pool/persistence.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/pool/worker.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/profile.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/py.typed +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/__init__.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/_generate.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/browser_list.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/browser_start.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/browser_stop.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/cdp_send.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/click_by_html_id.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/click_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/click_by_text.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/click_by_xpath.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/cookies_list.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/cookies_load.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/cookies_save.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/dialog_respond.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/download.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/drag_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/find_by_html_id.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/find_by_text.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/find_by_xpath.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/focus_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/highlight_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/hover_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/html_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/js_evaluate.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/login_interactive.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/mouse_click.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/mouse_drag.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/mouse_move.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_discover.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_emulate_focus.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_goto.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_html.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_info.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_reload.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_screenshot.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_scroll.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_wait_element.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_wait_ready.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/page_wait_url.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/screenshot_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/select_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/storage_get.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/storage_set.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/tab_close.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/tab_list.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/tab_new.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/tab_switch.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/type_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/type_by_text.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/upload_by_ref.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser/tools/window_set.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser.egg-info/SOURCES.txt +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser.egg-info/dependency_links.txt +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser.egg-info/requires.txt +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/ai_dev_browser.egg-info/top_level.txt +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/pyproject.toml +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/scripts/sync_cdp.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/setup.cfg +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/__init__.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/conftest.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/__init__.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/scenarios_workspace.json +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_dialog_respond.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_find_and_interact_workflows.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_locator_workflows.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_multi_profile_pool.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_page_reload.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_startup_timeout.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_timeout_and_retry.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_workspace_workflows.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/unit/test_case.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/unit/test_cli_param_type.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/unit/test_no_acronym_rot.py +0 -0
- {ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/uv.lock +0 -0
|
@@ -96,7 +96,15 @@ class JobResult:
|
|
|
96
96
|
job_id: ID of the job this result belongs to
|
|
97
97
|
success: True if job completed without error
|
|
98
98
|
data: Return value from the client method (JSON-serializable)
|
|
99
|
-
error: Error message if job failed
|
|
99
|
+
error: Error message if job failed (from `str(exception)`)
|
|
100
|
+
error_type: Exception class name if job failed (e.g.
|
|
101
|
+
`"GrokRateLimitError"`). Lets callers branch on exception
|
|
102
|
+
type without string-matching `error`. None on success.
|
|
103
|
+
error_bases: List of exception base-class names from the mro,
|
|
104
|
+
excluding `object` (e.g.
|
|
105
|
+
`["RateLimitError", "RuntimeError", "Exception"]`). Lets
|
|
106
|
+
callers match superclasses when the concrete type is
|
|
107
|
+
domain-specific but the base is standard. Empty on success.
|
|
100
108
|
completed_at: Timestamp when job completed
|
|
101
109
|
worker_id: ID of the worker that executed the job
|
|
102
110
|
|
|
@@ -107,15 +115,51 @@ class JobResult:
|
|
|
107
115
|
data={"url": "https://example.com", "title": "Example"},
|
|
108
116
|
worker_id=0,
|
|
109
117
|
)
|
|
118
|
+
|
|
119
|
+
# Failure branching without text matching:
|
|
120
|
+
if not result.success:
|
|
121
|
+
if result.error_type == "GrokRateLimitError":
|
|
122
|
+
schedule_retry()
|
|
123
|
+
elif "TimeoutError" in result.error_bases:
|
|
124
|
+
...
|
|
110
125
|
"""
|
|
111
126
|
|
|
112
127
|
job_id: str
|
|
113
128
|
success: bool
|
|
114
129
|
data: Any = None
|
|
115
130
|
error: str | None = None
|
|
131
|
+
error_type: str | None = None
|
|
132
|
+
error_bases: list[str] = field(default_factory=list)
|
|
116
133
|
completed_at: datetime = field(default_factory=datetime.now)
|
|
117
134
|
worker_id: int | None = None
|
|
118
135
|
|
|
136
|
+
@classmethod
|
|
137
|
+
def from_exception(
|
|
138
|
+
cls,
|
|
139
|
+
job_id: str,
|
|
140
|
+
exc: BaseException,
|
|
141
|
+
worker_id: int | None = None,
|
|
142
|
+
) -> "JobResult":
|
|
143
|
+
"""Build a failure result capturing the exception's type + mro.
|
|
144
|
+
|
|
145
|
+
Use inside worker exception handlers so callers downstream can
|
|
146
|
+
branch on `error_type` / `error_bases` without parsing
|
|
147
|
+
`error` text.
|
|
148
|
+
"""
|
|
149
|
+
cls_chain = type(exc).__mro__
|
|
150
|
+
# mro ends with `object`; drop it. First element is the type
|
|
151
|
+
# itself, which we surface as `error_type`; the rest is bases.
|
|
152
|
+
error_type = cls_chain[0].__name__
|
|
153
|
+
error_bases = [c.__name__ for c in cls_chain[1:] if c is not object]
|
|
154
|
+
return cls(
|
|
155
|
+
job_id=job_id,
|
|
156
|
+
success=False,
|
|
157
|
+
error=str(exc),
|
|
158
|
+
error_type=error_type,
|
|
159
|
+
error_bases=error_bases,
|
|
160
|
+
worker_id=worker_id,
|
|
161
|
+
)
|
|
162
|
+
|
|
119
163
|
def to_dict(self) -> dict:
|
|
120
164
|
"""Serialize result for persistence."""
|
|
121
165
|
return {
|
|
@@ -123,6 +167,8 @@ class JobResult:
|
|
|
123
167
|
"success": self.success,
|
|
124
168
|
"data": self.data,
|
|
125
169
|
"error": self.error,
|
|
170
|
+
"error_type": self.error_type,
|
|
171
|
+
"error_bases": self.error_bases,
|
|
126
172
|
"completed_at": self.completed_at.isoformat(),
|
|
127
173
|
"worker_id": self.worker_id,
|
|
128
174
|
}
|
|
@@ -135,6 +181,8 @@ class JobResult:
|
|
|
135
181
|
success=data["success"],
|
|
136
182
|
data=data.get("data"),
|
|
137
183
|
error=data.get("error"),
|
|
184
|
+
error_type=data.get("error_type"),
|
|
185
|
+
error_bases=data.get("error_bases") or [],
|
|
138
186
|
completed_at=datetime.fromisoformat(data["completed_at"]),
|
|
139
187
|
worker_id=data.get("worker_id"),
|
|
140
188
|
)
|
|
@@ -697,7 +697,7 @@ class BrowserPool(Generic[ClientT]):
|
|
|
697
697
|
)
|
|
698
698
|
|
|
699
699
|
except Exception as e:
|
|
700
|
-
await self._handle_job_failure(worker, job, str(e))
|
|
700
|
+
await self._handle_job_failure(worker, job, str(e), exc=e)
|
|
701
701
|
|
|
702
702
|
finally:
|
|
703
703
|
worker.mark_idle()
|
|
@@ -709,8 +709,22 @@ class BrowserPool(Generic[ClientT]):
|
|
|
709
709
|
logger.error(f"Worker {worker.worker_id} loop error: {e}")
|
|
710
710
|
await asyncio.sleep(1)
|
|
711
711
|
|
|
712
|
-
async def _handle_job_failure(
|
|
713
|
-
|
|
712
|
+
async def _handle_job_failure(
|
|
713
|
+
self,
|
|
714
|
+
worker: Worker,
|
|
715
|
+
job: Job,
|
|
716
|
+
error: str,
|
|
717
|
+
*,
|
|
718
|
+
exc: BaseException | None = None,
|
|
719
|
+
) -> None:
|
|
720
|
+
"""Handle job failure - retry or mark as failed.
|
|
721
|
+
|
|
722
|
+
If `exc` is provided (exception caught in the worker loop), the
|
|
723
|
+
terminal `JobResult` captures `error_type` + `error_bases` so
|
|
724
|
+
callers can branch on exception type without parsing `error`.
|
|
725
|
+
Non-exception failures (e.g. `fail_condition` triggered) pass
|
|
726
|
+
only `error` and the type fields stay None / [].
|
|
727
|
+
"""
|
|
714
728
|
job.retries += 1
|
|
715
729
|
worker.stats.fail += 1
|
|
716
730
|
|
|
@@ -725,12 +739,19 @@ class BrowserPool(Generic[ClientT]):
|
|
|
725
739
|
f"({job.job_id[:8]}...), retry {job.retries}: {error}"
|
|
726
740
|
)
|
|
727
741
|
else:
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
742
|
+
if exc is not None:
|
|
743
|
+
result = JobResult.from_exception(
|
|
744
|
+
job_id=job.job_id,
|
|
745
|
+
exc=exc,
|
|
746
|
+
worker_id=worker.worker_id,
|
|
747
|
+
)
|
|
748
|
+
else:
|
|
749
|
+
result = JobResult(
|
|
750
|
+
job_id=job.job_id,
|
|
751
|
+
success=False,
|
|
752
|
+
error=error,
|
|
753
|
+
worker_id=worker.worker_id,
|
|
754
|
+
)
|
|
734
755
|
self._results[job.job_id] = result
|
|
735
756
|
self._pending_jobs.pop(job.job_id, None)
|
|
736
757
|
job.status = JobStatus.FAILED
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ai_dev_browser-0.9.2 → ai_dev_browser-0.9.3}/tests/integration/test_find_and_interact_workflows.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|