superbrowser-sdk 2.7.0__tar.gz → 2.8.0__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.
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/CHANGELOG.md +24 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/PKG-INFO +1 -1
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/mcp.md +11 -3
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/pyproject.toml +1 -1
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/__init__.py +1 -1
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/facade.py +2 -1
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/controller.py +114 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/mcp_server.py +188 -3
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_controller_rebinding.py +3 -2
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_diagnostics.py +2 -2
- superbrowser_sdk-2.8.0/tests/test_mcp_interaction.py +246 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_navigation.py +8 -8
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_server.py +5 -4
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.env.example +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/adversarial-v3.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/adversarial.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/benchmark.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/dco.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/e2e.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/publish.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/smoke.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/stress.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.github/workflows/test.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.gitignore +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/.pre-commit-config.yaml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/CONTRIBUTING.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/Dockerfile +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/LICENSE +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/README.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/Super-Browser.png +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/benchmarks/fixtures/behavioral.html +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/benchmarks/fixtures/dom-heavy.html +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/benchmarks/fixtures/form.html +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/benchmarks/fixtures/simple.html +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/benchmarks/v1.11.0-baseline-patchright.json +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/benchmarks/v1.11.0-baseline-patchright.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/conftest.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docker-compose.yml +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/agent-reliability.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/aiv/AIV_FRAMEWORK_v5.3.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/anti-detection-ejecta.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/api-ergonomics-audit.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/api-reference.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/api-stability.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/architecture.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/behavioral-synthesis.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/browser-networking.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/cloak-integration.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/consistency-engine.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/design/inspect_redaction.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/discovery/DISCOVERY-REPORT.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/error-catalog.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/fingerprint-scoring.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/fingerprint-validation.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/gap-analysis.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/human-behavior.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/memory.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/migration/v1-to-v2.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/migration/v1.8-to-v1.9.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/operating-doctrine.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/platform-abstraction.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/plugins.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/quickstart.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/recording.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/rfcs/README.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/rfcs/v2-decomposition.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/rfcs/v2-track-a-api-simplification.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/rfcs/v2-track-b-network-stealth.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/rfcs/v2-track-c-behavioral-realism.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/rfcs/v2-track-d-challenge-infrastructure.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/rfcs/v2-track-e-e2e-harness.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/stealth-coverage.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/docs/stealth-evidence.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/backend_selection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/basic_usage.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/budget_tracking.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/cloak_stealth.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/error_handling.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/fingerprint_scan.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/human_behavior.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/multi_tab_workflow.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/session_persistence.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/examples/stealth_mode.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/adversarial_run.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/agent_efficiency_benchmark.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/browser_benchmark.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/e2e_trend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/run_stealth_gauntlet.sh +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/smoke_published.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/stress_real_world.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/validate_e2e_report.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/scripts/verify_release_artifact.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/__main__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/debug.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/delegator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/diagnostics.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/llm/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/llm/anthropic_client.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/llm/browser_transport.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/llm/budget_aware.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/llm/factory.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/llm/openai_client.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/llm/protocol.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/loop.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/loop_detector.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/plugins.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/registry.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/router.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/structured_logging.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/agent/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/bezier.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/dwell.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/fitts.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/gauss.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/keyboard.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/mouse.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/navigation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/orchestrator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/prng.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/qwerty.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/scroll.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/session_seed.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/behavioral/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/backends/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/backends/cdp_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/backends/patchright_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/backends/playwright_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/backends/selenium_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/cdp.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/cloak_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/cloud.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/discovery.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/engine.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/fetch.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/injectors/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/injectors/bidi_injector.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/injectors/cdp_injector.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/injectors/page_injector.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/page.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/session.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/shutdown.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/browser/tabs.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/budget/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/budget/cascade.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/budget/client.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/budget/compressor.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/budget/cost_estimator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/budget/credential_pool.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/budget/governor.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/budget/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/cli/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/cli/commands.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/cli/interactive.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/cli/script.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/events/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/events/bus.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/events/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/cache.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/decorator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/presets.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/recovery.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/snapshot.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/vision.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/memory/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/memory/integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/memory/store.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/memory/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/plugins/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/plugins/decorators.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/plugins/hooks.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/py.typed +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recording/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recording/persistence.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recording/recorder.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recording/replayer.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recording/report.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recording/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/checkpoint.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/classifier.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/coordinator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/event_bus.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/format_validator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/reflection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/retry_tracker.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/session_recovery.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/recovery/watchdogs.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/results/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/results/output.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/results/typed.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/results/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/results/validation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/action_redaction.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/approval.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/credential_vault.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/domain_filter.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/gate.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/injection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/manager.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/policy.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/redactor.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/security/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/session/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/session/proxy.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/skills/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/skills/activation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/skills/markdown.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/skills/registry.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/skills/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/action_policy.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/captcha.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/challenges/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/challenges/cache.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/challenges/pow.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/challenges/turnstile.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/dag.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/derive.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/errors.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/inject.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/inject_delivery.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/matrix.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/prng.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rule.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/audio.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/behavior.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/fonts.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/gpu.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/locale.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/navigator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/screen.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/consistency/rules/user_agent.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/diagnostics.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/audio.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/browser_apis.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/canvas.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/registry.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/timing.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ejecta/webrtc.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/fingerprint_scanner.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/fingerprint_score.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/headers.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/human.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/human_config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/ip_reputation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/manager.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/profiles/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/profiles/data/linux-chrome-stable.json +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/profiles/data/macos-chrome-stable.json +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/profiles/data/macos-m4-chrome-stable.json +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/profiles/data/windows-chrome-stable.json +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/profiles/host_detect.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/profiles/schema.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/proxy.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/proxy_pool.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/report.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/scoring.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/tls_baselines.json +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/user_agent_pool.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/validation/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/validation/checks.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/validation/harness.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/validation/report.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/stealth/validation/suite.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/testing.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/tracing/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/tracing/cost_analytics.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/tracing/flow_logger.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/tracing/middleware.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/tracing/session_db.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/tracing/sinks.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/tracing/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/verification/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/verification/ax_diff.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/verification/hasher.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/verification/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/verification/verifier.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/vision/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/vision/cache.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/vision/controller.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/vision/coords.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/vision/factory.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/vision/ocr.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/vision/providers.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/vision/types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/stress/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/stress/server.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/conftest.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/controlled_server.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/report.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/scoring.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/targets.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/test_controlled_server.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/test_targets_unit.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/test_tier1_scanners.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/test_tier2_vendors.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial/test_tier3_controlled.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/README.md +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/backends.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/behavioral_telemetry.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/core.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/engines/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/engines/scoring.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/harness.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/reporters/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/reporters/history.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/reporters/json_reporter.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/reporters/markdown_reporter.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/server.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/vectors/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/vectors/automation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/vectors/behavioral.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/vectors/controlled.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/vectors/ejector.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/vectors/external.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/vectors/fingerprint.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/adversarial3/vectors/network.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/pytest.ini +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/run.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/conftest.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_backends.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_behavioral_telemetry.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_behavioral_telemetry_smoke.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_behavioral_vectors.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_core.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_external.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_harness_smoke.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_header_ordering.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_reporters.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_scoring.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_server.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_superbrowser_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/adversarial_v3/tests/test_vectors.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/conftest.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/conftest.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_01_example_nav.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_02_google_search.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_03_github_login.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_04_amazon_search.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_05_google_forms.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_06_google_flights.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_07_wikipedia_extract.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_08_reddit_spa.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_09_form_complex.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/discovery/test_task_10_signup_flow.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/conftest.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/test_behavioral_realism.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/test_challenge_detection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/test_interaction.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/test_live_navigation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/test_multi_tab.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/test_navigation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/test_session_persistence.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e/test_stealth_overhead.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/e2e_v1_3_journey.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/conftest.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_config_composition.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_engine_backends.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_error_paths.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_facade_smoke.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_full_lifecycle.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_multi_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_performance_smoke.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_playwright_integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_public_api.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_session_persistence.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_stealth_abstraction.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v1100_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v150_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v160_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v170_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v180_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v190_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v191_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v192_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v193_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v194_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v195_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v1_3_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/integration/test_v1_4_features.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/pattern_validation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/conftest.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/test_chrome_runtime.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/test_cli_switches.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/test_headless_indicators.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/test_live_sites.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/test_runtime_enable.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/test_tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/stealth_detection/test_webdriver.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_action_timeout.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_browser_transport.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_debug_mode.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_default_tooling.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_delegator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_error_screenshots.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_facade.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_facade_security.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_facade_security_control.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_facade_security_file_tab.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_facade_security_network.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_facade_security_session.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_fail_fast.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_llm.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_llm_budget.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_llm_production.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_llm_streaming.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_loop.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_loop_detector.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_prompt_isolation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_registry.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_retry_budget.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_streaming.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_structured_logging.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_tab_cap.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_task_02.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_behavioral/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_behavioral/test_behavioral.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_behavioral/test_dwell.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_behavioral/test_hardening.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_behavioral/test_human_config_dwell.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_behavioral/test_navigation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_behavioral/test_orchestrator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_behavioral/test_session_seed.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_benchmark/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_benchmark/test_efficiency.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_benchmarks/test_browser_benchmark.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_benchmarks/test_stress_real_world.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_cdp.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_cdp_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_cloak_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_cloak_docs.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_cloak_integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_discovery.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_engine_protocol.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_fetch.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_injectors.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_page.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_patchright_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_playwright_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_selenium_backend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_session.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_browser/test_shutdown.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_cascade.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_cascade_governor.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_circuit_breaker.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_client.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_compressor.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_cost_estimator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_credential_pool.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_governor.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_budget/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_cli/test_interactive.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_cli/test_script.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_cli/test_stealth_check.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_cli/test_stealth_validate.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_cli/test_unified_cli.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_diagnostics.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_e2e/test_report_schema.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_e2e/test_trend.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_ejecta/test_audio.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_ejecta/test_batch37_integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_ejecta/test_batch38_integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_ejecta/test_browser_apis.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_ejecta/test_canvas.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_ejecta/test_integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_ejecta/test_timing.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_ejecta/test_webrtc.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_events/test_event_bus.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_events/test_lifecycle_hooks.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_governance_docs.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_cache.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_controller.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_decorator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_injection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_page_change.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_presets.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_recovery.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_snapshot.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_interaction/test_vision.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_entrypoint.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_permissions.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_redaction.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_server_smoke.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_write_tools.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_mcp_write_tools_wave2.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_memory/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_memory/test_cli_config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_memory/test_integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_memory/test_store.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recording/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recording/test_persistence.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recording/test_recorder.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recording/test_replayer.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_checkpoint.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_classifier.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_coordinator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_event_bus.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_format_validator.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_reflection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_retry_tracker.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_session_recovery.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_recovery/test_watchdogs.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_release/test_naming_consistency.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_release/test_smoke_published.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_release/test_verify_artifact.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_results/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_results/test_batch40_integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_results/test_categories.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_results/test_output.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_results/test_typed.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_results/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_results/test_validation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_runtime_correctness/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_runtime_correctness/test_runtime_fixes.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_approval.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_credential_vault.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_domain_filter.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_injection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_manager.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_policy.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_redaction_pipeline.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_redactor.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_security/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_session/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_session/test_locale.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_session/test_proxy.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_skills/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_skills/test_activation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_skills/test_integration.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_skills/test_markdown.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_skills/test_registry.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_skills/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_action_policy.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_captcha.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_captcha_resolution.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_challenge_cache.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_challenge_config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_consistency/test_consistency.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_consistency_inject.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_diagnostics.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_e2e_lifecycle.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_e2e_reporting.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_fingerprint_scanner.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_fingerprint_score.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_headers.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_human.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_human_behavior_v2.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_ip_reputation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_kasada_detection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_manager.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_network_stealth_config.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_profiles.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_proxy.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_proxy_pool.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_stealth_bridge.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_turnstile_detection.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_user_agent_pool.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_stealth/test_validation.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_tracing/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_tracing/test_cost_analytics.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_tracing/test_flow_logger.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_tracing/test_middleware.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_tracing/test_session_db.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_tracing/test_sinks.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_tracing/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_verification/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_verification/test_ax_diff.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_verification/test_hasher.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_verification/test_types.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_verification/test_verifier.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_vision/__init__.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_vision/test_cache.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_vision/test_controller.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_vision/test_coords.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_vision/test_factory.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_vision/test_ocr.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_vision/test_providers.py +0 -0
- {superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_vision/test_types.py +0 -0
|
@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.8.0] — 2026-06-26
|
|
9
|
+
|
|
10
|
+
### Added — MCP interaction tools (P3.1)
|
|
11
|
+
|
|
12
|
+
Six new action-tier MCP tools for form and element interaction:
|
|
13
|
+
|
|
14
|
+
- `hover` — hover over an element (controller-backed, selector/coordinate/vision cascade)
|
|
15
|
+
- `select_option` — select an option in a `<select>` element (maps to controller `select`, supports `by`: text/value/label)
|
|
16
|
+
- `check` — check a checkbox or radio button (new controller method + cascade)
|
|
17
|
+
- `uncheck` — uncheck a checkbox (new controller method + cascade)
|
|
18
|
+
- `focus` — focus an element (new controller method, selector-tier only)
|
|
19
|
+
- `type_text` — type text character-by-character (per-keystroke), triggering JS key listeners. Unlike `fill` which sets the value atomically. Supports `delay_ms` (0–1000). (new controller method)
|
|
20
|
+
|
|
21
|
+
All six are action-tier: require `--allow-actions`, consume the action budget,
|
|
22
|
+
pass through `SecurityManager` + audit, and are absent from the default
|
|
23
|
+
advertised surface.
|
|
24
|
+
|
|
25
|
+
- Default advertised tools: remains 17
|
|
26
|
+
- Action-mode advertised tools: 23 → 29
|
|
27
|
+
|
|
28
|
+
New controller primitives (`check`, `uncheck`, `focus`, `type_text`) added to
|
|
29
|
+
`MultimodalController` with `@agent_action` decorators and `FrameInteractionTarget`
|
|
30
|
+
adapters. Registered in the facade's builtin-tool loop.
|
|
31
|
+
|
|
8
32
|
## [2.7.0] — 2026-06-26
|
|
9
33
|
|
|
10
34
|
### Added — MCP reload and history navigation tools (P3.0B)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superbrowser-sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.8.0
|
|
4
4
|
Summary: Anti-detection agent browser SDK — stealth, budget governance, security guardrails, and structured error recovery behind one async facade
|
|
5
5
|
Project-URL: Homepage, https://github.com/Octo-Lex/Super-Browser
|
|
6
6
|
Project-URL: Documentation, https://github.com/Octo-Lex/Super-Browser#readme
|
|
@@ -7,7 +7,7 @@ scripting Python.
|
|
|
7
7
|
|
|
8
8
|
The stdio server advertises **seventeen tools by default** (six inspect + five
|
|
9
9
|
diagnostics + six navigation) — enough to read a URL end-to-end and explain
|
|
10
|
-
why a read failed. When action mode is enabled, it advertises **
|
|
10
|
+
why a read failed. When action mode is enabled, it advertises **twelve additional
|
|
11
11
|
action tools**; every action call is checked by
|
|
12
12
|
`MCPSessionPolicy` and `SecurityManager` before it can reach the browser.
|
|
13
13
|
|
|
@@ -32,7 +32,7 @@ Either of:
|
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
superbrowser-mcp # default: 17 tools (inspect + diagnostics + navigation)
|
|
35
|
-
superbrowser-mcp --allow-actions #
|
|
35
|
+
superbrowser-mcp --allow-actions # 29 tools (adds the action tier)
|
|
36
36
|
python -m super_browser.mcp_server
|
|
37
37
|
```
|
|
38
38
|
|
|
@@ -192,9 +192,17 @@ entry, no side effects.
|
|
|
192
192
|
| `fill` | `target` (required), `value` (required), `clear_first` (optional), `description` (optional) | SENSITIVE |
|
|
193
193
|
| `open_tab` | `url` (optional) | SENSITIVE — URL passed to `SecurityManager` when provided |
|
|
194
194
|
| `close_tab` | `tab_id` (required) | SENSITIVE |
|
|
195
|
+
| `hover` | `target` (required), `description` (optional) | SENSITIVE |
|
|
196
|
+
| `select_option` | `target` (required), `option` (required), `by` (optional: text/value/label), `description` (optional) | SENSITIVE |
|
|
197
|
+
| `check` | `target` (required), `description` (optional) | SENSITIVE |
|
|
198
|
+
| `uncheck` | `target` (required), `description` (optional) | SENSITIVE |
|
|
199
|
+
| `focus` | `target` (required), `description` (optional) | SENSITIVE |
|
|
200
|
+
| `type_text` | `target` (required), `text` (required), `delay_ms` (optional, 0–1000), `description` (optional) | SENSITIVE |
|
|
195
201
|
|
|
196
202
|
`fill` sends only the literal value supplied by the caller. It does not
|
|
197
|
-
retrieve, infer, store, or auto-fill credentials.
|
|
203
|
+
retrieve, infer, store, or auto-fill credentials. `type_text` types
|
|
204
|
+
character-by-character (per-keystroke), triggering JS key listeners — unlike
|
|
205
|
+
`fill` which sets the value atomically.
|
|
198
206
|
|
|
199
207
|
#### Action workflow
|
|
200
208
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "superbrowser-sdk"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.8.0"
|
|
8
8
|
description = "Anti-detection agent browser SDK — stealth, budget governance, security guardrails, and structured error recovery behind one async facade"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
@@ -6,7 +6,7 @@ from super_browser.agent.types import StreamEvent as StreamEvent # noqa: F401
|
|
|
6
6
|
from super_browser.config import Config as Config # noqa: F401
|
|
7
7
|
from super_browser.results.types import ActionResult as ActionResult # noqa: F401
|
|
8
8
|
|
|
9
|
-
__version__ = "2.
|
|
9
|
+
__version__ = "2.8.0"
|
|
10
10
|
|
|
11
11
|
__all__ = [
|
|
12
12
|
"SuperBrowser",
|
|
@@ -1003,7 +1003,8 @@ class SuperBrowser:
|
|
|
1003
1003
|
# self._controller, the registered tools still route to the current
|
|
1004
1004
|
# controller. Raw bound methods would capture the old controller
|
|
1005
1005
|
# instance and act on a stale page after tab switches.
|
|
1006
|
-
for name in ("click", "fill", "select", "hover", "drag", "scroll", "keypress"
|
|
1006
|
+
for name in ("click", "fill", "select", "hover", "drag", "scroll", "keypress",
|
|
1007
|
+
"check", "uncheck", "focus", "type_text"):
|
|
1007
1008
|
method = getattr(self._controller, name, None)
|
|
1008
1009
|
if method is not None and self._registry.get(name) is None:
|
|
1009
1010
|
self._registry.register(self._make_controller_wrapper(name))
|
{superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/src/super_browser/interaction/controller.py
RENAMED
|
@@ -81,6 +81,18 @@ class FrameInteractionTarget:
|
|
|
81
81
|
async def hover(self, selector: str) -> None:
|
|
82
82
|
await self._frame.locator(selector).hover()
|
|
83
83
|
|
|
84
|
+
async def check(self, selector: str) -> None:
|
|
85
|
+
await self._frame.locator(selector).check()
|
|
86
|
+
|
|
87
|
+
async def uncheck(self, selector: str) -> None:
|
|
88
|
+
await self._frame.locator(selector).uncheck()
|
|
89
|
+
|
|
90
|
+
async def focus(self, selector: str) -> None:
|
|
91
|
+
await self._frame.locator(selector).focus()
|
|
92
|
+
|
|
93
|
+
async def type_text(self, selector: str, text: str, *, delay: int = 0) -> None:
|
|
94
|
+
await self._frame.locator(selector).type(text, delay=delay)
|
|
95
|
+
|
|
84
96
|
async def drag_and_drop(self, source: str, target: str) -> None:
|
|
85
97
|
src = self._frame.locator(source)
|
|
86
98
|
dst = self._frame.locator(target)
|
|
@@ -328,6 +340,108 @@ class MultimodalController:
|
|
|
328
340
|
result, _ = await self._cascade("hover", target, description, t1, t2, t3)
|
|
329
341
|
return result
|
|
330
342
|
|
|
343
|
+
@agent_action(security_level="sensitive")
|
|
344
|
+
async def check(
|
|
345
|
+
self,
|
|
346
|
+
target: str,
|
|
347
|
+
*,
|
|
348
|
+
description: Optional[str] = None,
|
|
349
|
+
) -> ActionResult:
|
|
350
|
+
"""Check a checkbox or radio button.
|
|
351
|
+
|
|
352
|
+
Selector-tier only — coordinate/vision fallbacks would be toggle-like
|
|
353
|
+
(clicks that can uncheck an already-checked box), violating the
|
|
354
|
+
idempotent state-enforcing semantics implied by the tool name.
|
|
355
|
+
"""
|
|
356
|
+
|
|
357
|
+
async def t1():
|
|
358
|
+
await self._interaction_target.check(target)
|
|
359
|
+
return action_result(ok=True, data={"target": target}, method=ActionMethod.SELECTOR)
|
|
360
|
+
|
|
361
|
+
result, _ = await self._cascade("check", target, description, t1)
|
|
362
|
+
return result
|
|
363
|
+
|
|
364
|
+
@agent_action(security_level="sensitive")
|
|
365
|
+
async def uncheck(
|
|
366
|
+
self,
|
|
367
|
+
target: str,
|
|
368
|
+
*,
|
|
369
|
+
description: Optional[str] = None,
|
|
370
|
+
) -> ActionResult:
|
|
371
|
+
"""Uncheck a checkbox.
|
|
372
|
+
|
|
373
|
+
Selector-tier only — same rationale as ``check``: coordinate/vision
|
|
374
|
+
fallbacks would be toggle-like, not state-enforcing.
|
|
375
|
+
"""
|
|
376
|
+
|
|
377
|
+
async def t1():
|
|
378
|
+
await self._interaction_target.uncheck(target)
|
|
379
|
+
return action_result(ok=True, data={"target": target}, method=ActionMethod.SELECTOR)
|
|
380
|
+
|
|
381
|
+
result, _ = await self._cascade("uncheck", target, description, t1)
|
|
382
|
+
return result
|
|
383
|
+
|
|
384
|
+
@agent_action(security_level="sensitive")
|
|
385
|
+
async def focus(
|
|
386
|
+
self,
|
|
387
|
+
target: str,
|
|
388
|
+
*,
|
|
389
|
+
description: Optional[str] = None,
|
|
390
|
+
) -> ActionResult:
|
|
391
|
+
"""Focus an element."""
|
|
392
|
+
|
|
393
|
+
async def t1():
|
|
394
|
+
await self._interaction_target.focus(target)
|
|
395
|
+
return action_result(ok=True, data={"target": target}, method=ActionMethod.SELECTOR)
|
|
396
|
+
|
|
397
|
+
# Focus has no meaningful coordinate/vision fallback — a click would be
|
|
398
|
+
# a different action, not a focus. Only selector-tier.
|
|
399
|
+
result, _ = await self._cascade("focus", target, description, t1)
|
|
400
|
+
return result
|
|
401
|
+
|
|
402
|
+
@agent_action(security_level="sensitive")
|
|
403
|
+
async def type_text(
|
|
404
|
+
self,
|
|
405
|
+
target: str,
|
|
406
|
+
text: str,
|
|
407
|
+
*,
|
|
408
|
+
delay: int = 0,
|
|
409
|
+
description: Optional[str] = None,
|
|
410
|
+
) -> ActionResult:
|
|
411
|
+
"""Type text character-by-character (per-keystroke), unlike fill.
|
|
412
|
+
|
|
413
|
+
Triggers JS keydown/keypress/keyup listeners, suitable for autocomplete,
|
|
414
|
+
masked inputs, and debounce handlers.
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
async def t1():
|
|
418
|
+
await self._interaction_target.type_text(target, text, delay=delay)
|
|
419
|
+
return action_result(ok=True, data={"target": target, "text_length": len(text)}, method=ActionMethod.SELECTOR)
|
|
420
|
+
|
|
421
|
+
async def t2():
|
|
422
|
+
coords = await self._resolve_to_coordinates(target)
|
|
423
|
+
if coords is None:
|
|
424
|
+
return action_result(ok=False, error=ActionError(ErrorCategory.SELECTOR_NOT_FOUND, f"Cannot resolve '{target}'"))
|
|
425
|
+
# Click to focus, then type via CDP.
|
|
426
|
+
await self._cdp.send("Input.dispatchMouseEvent", {
|
|
427
|
+
"type": "mousePressed", "x": coords[0], "y": coords[1],
|
|
428
|
+
"button": "left", "clickCount": 1,
|
|
429
|
+
})
|
|
430
|
+
await self._cdp.send("Input.dispatchMouseEvent", {
|
|
431
|
+
"type": "mouseReleased", "x": coords[0], "y": coords[1],
|
|
432
|
+
"button": "left", "clickCount": 1,
|
|
433
|
+
})
|
|
434
|
+
for char in text:
|
|
435
|
+
await self._cdp.send("Input.dispatchKeyEvent", {
|
|
436
|
+
"type": "char", "text": char,
|
|
437
|
+
})
|
|
438
|
+
if delay:
|
|
439
|
+
await asyncio.sleep(delay / 1000)
|
|
440
|
+
return action_result(ok=True, data={"target": target, "method": "coordinate"}, method=ActionMethod.COORDINATE)
|
|
441
|
+
|
|
442
|
+
result, _ = await self._cascade("type_text", target, description, t1, t2)
|
|
443
|
+
return result
|
|
444
|
+
|
|
331
445
|
@agent_action(security_level="dangerous")
|
|
332
446
|
async def drag(
|
|
333
447
|
self,
|
|
@@ -385,7 +385,88 @@ NAVIGATION_TOOL_NAMES = frozenset(t.name for t in NAVIGATION_TOOLS)
|
|
|
385
385
|
|
|
386
386
|
# Action-tier tools: page interaction (requires allow_actions).
|
|
387
387
|
# navigate is removed from the action set; scroll/press_key remain.
|
|
388
|
-
|
|
388
|
+
# P3.1 adds: hover, select_option, check, uncheck, focus, type_text.
|
|
389
|
+
INTERACTION_TOOLS: list[types.Tool] = [
|
|
390
|
+
types.Tool(
|
|
391
|
+
name="hover",
|
|
392
|
+
description="Hover over an element by selector. Action-tier (requires --allow-actions).",
|
|
393
|
+
inputSchema={
|
|
394
|
+
"type": "object",
|
|
395
|
+
"properties": {
|
|
396
|
+
"target": {"type": "string", "description": "CSS selector for the element to hover."},
|
|
397
|
+
"description": {"type": "string", "description": "Optional natural-language description for vision-based fallback."},
|
|
398
|
+
},
|
|
399
|
+
"required": ["target"],
|
|
400
|
+
},
|
|
401
|
+
),
|
|
402
|
+
types.Tool(
|
|
403
|
+
name="select_option",
|
|
404
|
+
description="Select an option in a <select> element by selector. Action-tier (requires --allow-actions).",
|
|
405
|
+
inputSchema={
|
|
406
|
+
"type": "object",
|
|
407
|
+
"properties": {
|
|
408
|
+
"target": {"type": "string", "description": "CSS selector for the <select> element."},
|
|
409
|
+
"option": {"type": "string", "description": "The option value to select."},
|
|
410
|
+
"by": {"type": "string", "enum": ["text", "value", "label"], "default": "text",
|
|
411
|
+
"description": "How to match the option."},
|
|
412
|
+
"description": {"type": "string", "description": "Optional natural-language description."},
|
|
413
|
+
},
|
|
414
|
+
"required": ["target", "option"],
|
|
415
|
+
},
|
|
416
|
+
),
|
|
417
|
+
types.Tool(
|
|
418
|
+
name="check",
|
|
419
|
+
description="Check a checkbox or radio button by selector. Action-tier (requires --allow-actions).",
|
|
420
|
+
inputSchema={
|
|
421
|
+
"type": "object",
|
|
422
|
+
"properties": {
|
|
423
|
+
"target": {"type": "string", "description": "CSS selector for the checkbox/radio."},
|
|
424
|
+
"description": {"type": "string", "description": "Optional natural-language description."},
|
|
425
|
+
},
|
|
426
|
+
"required": ["target"],
|
|
427
|
+
},
|
|
428
|
+
),
|
|
429
|
+
types.Tool(
|
|
430
|
+
name="uncheck",
|
|
431
|
+
description="Uncheck a checkbox by selector. Action-tier (requires --allow-actions).",
|
|
432
|
+
inputSchema={
|
|
433
|
+
"type": "object",
|
|
434
|
+
"properties": {
|
|
435
|
+
"target": {"type": "string", "description": "CSS selector for the checkbox."},
|
|
436
|
+
"description": {"type": "string", "description": "Optional natural-language description."},
|
|
437
|
+
},
|
|
438
|
+
"required": ["target"],
|
|
439
|
+
},
|
|
440
|
+
),
|
|
441
|
+
types.Tool(
|
|
442
|
+
name="focus",
|
|
443
|
+
description="Focus an element by selector. Action-tier (requires --allow-actions).",
|
|
444
|
+
inputSchema={
|
|
445
|
+
"type": "object",
|
|
446
|
+
"properties": {
|
|
447
|
+
"target": {"type": "string", "description": "CSS selector for the element to focus."},
|
|
448
|
+
"description": {"type": "string", "description": "Optional natural-language description."},
|
|
449
|
+
},
|
|
450
|
+
"required": ["target"],
|
|
451
|
+
},
|
|
452
|
+
),
|
|
453
|
+
types.Tool(
|
|
454
|
+
name="type_text",
|
|
455
|
+
description="Type text character-by-character (per-keystroke) into an element. Unlike fill, this triggers JS key listeners. Action-tier (requires --allow-actions).",
|
|
456
|
+
inputSchema={
|
|
457
|
+
"type": "object",
|
|
458
|
+
"properties": {
|
|
459
|
+
"target": {"type": "string", "description": "CSS selector for the input element."},
|
|
460
|
+
"text": {"type": "string", "description": "The text to type."},
|
|
461
|
+
"delay_ms": {"type": "integer", "default": 0, "description": "Delay between keystrokes in ms (0-1000)."},
|
|
462
|
+
"description": {"type": "string", "description": "Optional natural-language description."},
|
|
463
|
+
},
|
|
464
|
+
"required": ["target", "text"],
|
|
465
|
+
},
|
|
466
|
+
),
|
|
467
|
+
]
|
|
468
|
+
|
|
469
|
+
ACTION_TOOLS: list[types.Tool] = [*PHASE2B_TOOLS[1:], *PHASE2B_WAVE2_TOOLS, *INTERACTION_TOOLS]
|
|
389
470
|
ACTION_TOOL_NAMES = frozenset(t.name for t in ACTION_TOOLS)
|
|
390
471
|
|
|
391
472
|
# Default advertised surface: Inspect + Navigation.
|
|
@@ -890,8 +971,9 @@ class ToolDispatcher:
|
|
|
890
971
|
"""Action-tier dispatch: validate → action gate → authorize → handler.
|
|
891
972
|
|
|
892
973
|
Authorization happens before ANY facade/browser call. If denied, the
|
|
893
|
-
facade is never touched. All
|
|
894
|
-
fill, open_tab, close_tab
|
|
974
|
+
facade is never touched. All 12 action tools (scroll, press_key, click,
|
|
975
|
+
fill, open_tab, close_tab, hover, select_option, check, uncheck, focus,
|
|
976
|
+
type_text) have real handlers that call the facade/controller
|
|
895
977
|
after the authorizer approves.
|
|
896
978
|
"""
|
|
897
979
|
# 1. Validate args before authorization (invalid args must not consume
|
|
@@ -1075,6 +1157,51 @@ class ToolDispatcher:
|
|
|
1075
1157
|
"'tab_id' is required and must be a non-negative integer",
|
|
1076
1158
|
kind="invalid_arguments",
|
|
1077
1159
|
)
|
|
1160
|
+
elif name in ("hover", "check", "uncheck", "focus"):
|
|
1161
|
+
target = arguments.get("target")
|
|
1162
|
+
if not isinstance(target, str) or not target.strip():
|
|
1163
|
+
return _error_content(
|
|
1164
|
+
"'target' is required and must be a non-empty string",
|
|
1165
|
+
kind="invalid_arguments",
|
|
1166
|
+
)
|
|
1167
|
+
elif name == "select_option":
|
|
1168
|
+
target = arguments.get("target")
|
|
1169
|
+
if not isinstance(target, str) or not target.strip():
|
|
1170
|
+
return _error_content(
|
|
1171
|
+
"'target' is required and must be a non-empty string",
|
|
1172
|
+
kind="invalid_arguments",
|
|
1173
|
+
)
|
|
1174
|
+
option = arguments.get("option")
|
|
1175
|
+
if not isinstance(option, str) or not option.strip():
|
|
1176
|
+
return _error_content(
|
|
1177
|
+
"'option' is required and must be a non-empty string",
|
|
1178
|
+
kind="invalid_arguments",
|
|
1179
|
+
)
|
|
1180
|
+
by = arguments.get("by", "text")
|
|
1181
|
+
if by not in ("text", "value", "label"):
|
|
1182
|
+
return _error_content(
|
|
1183
|
+
"'by' must be one of: text, value, label",
|
|
1184
|
+
kind="invalid_arguments",
|
|
1185
|
+
)
|
|
1186
|
+
elif name == "type_text":
|
|
1187
|
+
target = arguments.get("target")
|
|
1188
|
+
if not isinstance(target, str) or not target.strip():
|
|
1189
|
+
return _error_content(
|
|
1190
|
+
"'target' is required and must be a non-empty string",
|
|
1191
|
+
kind="invalid_arguments",
|
|
1192
|
+
)
|
|
1193
|
+
text = arguments.get("text")
|
|
1194
|
+
if not isinstance(text, str):
|
|
1195
|
+
return _error_content(
|
|
1196
|
+
"'text' is required and must be a string",
|
|
1197
|
+
kind="invalid_arguments",
|
|
1198
|
+
)
|
|
1199
|
+
delay_ms = arguments.get("delay_ms", 0)
|
|
1200
|
+
if not isinstance(delay_ms, int) or isinstance(delay_ms, bool) or delay_ms < 0 or delay_ms > 1000:
|
|
1201
|
+
return _error_content(
|
|
1202
|
+
"'delay_ms' must be an integer between 0 and 1000",
|
|
1203
|
+
kind="invalid_arguments",
|
|
1204
|
+
)
|
|
1078
1205
|
return None
|
|
1079
1206
|
|
|
1080
1207
|
@staticmethod
|
|
@@ -1214,6 +1341,64 @@ class ToolDispatcher:
|
|
|
1214
1341
|
ar = await sb.close_tab(arguments["tab_id"])
|
|
1215
1342
|
return _text_content(_serialize_action_result(ar))
|
|
1216
1343
|
|
|
1344
|
+
# --- P3.1 interaction handlers (action-tier; delegate to controller) ---
|
|
1345
|
+
|
|
1346
|
+
async def _tool_hover(self, arguments: dict[str, Any]) -> list[types.TextContent]:
|
|
1347
|
+
sb = await self.runtime.get_browser()
|
|
1348
|
+
controller = getattr(sb, "_controller", None)
|
|
1349
|
+
if controller is None:
|
|
1350
|
+
return _error_content("browser has no active controller", kind="error")
|
|
1351
|
+
ar = await controller.hover(arguments["target"], description=arguments.get("description"))
|
|
1352
|
+
return _text_content(_serialize_action_result(ar))
|
|
1353
|
+
|
|
1354
|
+
async def _tool_select_option(self, arguments: dict[str, Any]) -> list[types.TextContent]:
|
|
1355
|
+
sb = await self.runtime.get_browser()
|
|
1356
|
+
controller = getattr(sb, "_controller", None)
|
|
1357
|
+
if controller is None:
|
|
1358
|
+
return _error_content("browser has no active controller", kind="error")
|
|
1359
|
+
ar = await controller.select(
|
|
1360
|
+
arguments["target"], arguments["option"],
|
|
1361
|
+
by=arguments.get("by", "text"),
|
|
1362
|
+
description=arguments.get("description"),
|
|
1363
|
+
)
|
|
1364
|
+
return _text_content(_serialize_action_result(ar))
|
|
1365
|
+
|
|
1366
|
+
async def _tool_check(self, arguments: dict[str, Any]) -> list[types.TextContent]:
|
|
1367
|
+
sb = await self.runtime.get_browser()
|
|
1368
|
+
controller = getattr(sb, "_controller", None)
|
|
1369
|
+
if controller is None:
|
|
1370
|
+
return _error_content("browser has no active controller", kind="error")
|
|
1371
|
+
ar = await controller.check(arguments["target"], description=arguments.get("description"))
|
|
1372
|
+
return _text_content(_serialize_action_result(ar))
|
|
1373
|
+
|
|
1374
|
+
async def _tool_uncheck(self, arguments: dict[str, Any]) -> list[types.TextContent]:
|
|
1375
|
+
sb = await self.runtime.get_browser()
|
|
1376
|
+
controller = getattr(sb, "_controller", None)
|
|
1377
|
+
if controller is None:
|
|
1378
|
+
return _error_content("browser has no active controller", kind="error")
|
|
1379
|
+
ar = await controller.uncheck(arguments["target"], description=arguments.get("description"))
|
|
1380
|
+
return _text_content(_serialize_action_result(ar))
|
|
1381
|
+
|
|
1382
|
+
async def _tool_focus(self, arguments: dict[str, Any]) -> list[types.TextContent]:
|
|
1383
|
+
sb = await self.runtime.get_browser()
|
|
1384
|
+
controller = getattr(sb, "_controller", None)
|
|
1385
|
+
if controller is None:
|
|
1386
|
+
return _error_content("browser has no active controller", kind="error")
|
|
1387
|
+
ar = await controller.focus(arguments["target"], description=arguments.get("description"))
|
|
1388
|
+
return _text_content(_serialize_action_result(ar))
|
|
1389
|
+
|
|
1390
|
+
async def _tool_type_text(self, arguments: dict[str, Any]) -> list[types.TextContent]:
|
|
1391
|
+
sb = await self.runtime.get_browser()
|
|
1392
|
+
controller = getattr(sb, "_controller", None)
|
|
1393
|
+
if controller is None:
|
|
1394
|
+
return _error_content("browser has no active controller", kind="error")
|
|
1395
|
+
ar = await controller.type_text(
|
|
1396
|
+
arguments["target"], arguments["text"],
|
|
1397
|
+
delay=arguments.get("delay_ms", 0),
|
|
1398
|
+
description=arguments.get("description"),
|
|
1399
|
+
)
|
|
1400
|
+
return _text_content(_serialize_action_result(ar))
|
|
1401
|
+
|
|
1217
1402
|
# --- read-only tools (none of these lazy-start except where noted) ---
|
|
1218
1403
|
|
|
1219
1404
|
async def _tool_browser_status(self, arguments: dict[str, Any]) -> list[types.TextContent]:
|
{superbrowser_sdk-2.7.0 → superbrowser_sdk-2.8.0}/tests/test_agent/test_controller_rebinding.py
RENAMED
|
@@ -156,8 +156,9 @@ class TestRegistryIntegrity:
|
|
|
156
156
|
browser = _make_browser_with_mocks()
|
|
157
157
|
browser._register_builtin_tools()
|
|
158
158
|
|
|
159
|
-
#
|
|
160
|
-
|
|
159
|
+
# 11 controller (7 original + check/uncheck/focus/type_text)
|
|
160
|
+
# + navigate + extract + observe = 14
|
|
161
|
+
assert browser._registry.tool_count == 14
|
|
161
162
|
|
|
162
163
|
|
|
163
164
|
# ---------------------------------------------------------------------------
|
|
@@ -80,11 +80,11 @@ class TestDiagnosticsAdvertisement:
|
|
|
80
80
|
"list_requests", "get_request"):
|
|
81
81
|
assert diag in names
|
|
82
82
|
|
|
83
|
-
def
|
|
83
|
+
def test_action_mode_advertises_29_tools(self):
|
|
84
84
|
from super_browser.mcp_server import MCPSessionPolicy, _tools_for_policy
|
|
85
85
|
|
|
86
86
|
names = {t.name for t in _tools_for_policy(MCPSessionPolicy(allow_actions=True))}
|
|
87
|
-
assert len(names) ==
|
|
87
|
+
assert len(names) == 29
|
|
88
88
|
|
|
89
89
|
def test_diagnostics_are_inspect_tier(self):
|
|
90
90
|
"""Diagnostics tools are in INSPECT_TOOL_NAMES (no action gate)."""
|