superbrowser-sdk 2.8.0__tar.gz → 2.9.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.8.0 → superbrowser_sdk-2.9.0}/CHANGELOG.md +32 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/PKG-INFO +1 -1
- superbrowser_sdk-2.9.0/docs/design/mcp_tool_metadata.md +199 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/mcp.md +12 -2
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/pyproject.toml +1 -1
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/__init__.py +1 -1
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/facade.py +40 -1
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/mcp_server.py +14 -3
- superbrowser_sdk-2.9.0/tests/test_mcp_observe_targets.py +329 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.env.example +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/adversarial-v3.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/adversarial.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/benchmark.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/dco.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/e2e.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/publish.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/smoke.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/stress.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.github/workflows/test.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.gitignore +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/.pre-commit-config.yaml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/CONTRIBUTING.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/Dockerfile +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/LICENSE +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/README.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/Super-Browser.png +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/benchmarks/fixtures/behavioral.html +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/benchmarks/fixtures/dom-heavy.html +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/benchmarks/fixtures/form.html +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/benchmarks/fixtures/simple.html +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/benchmarks/v1.11.0-baseline-patchright.json +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/benchmarks/v1.11.0-baseline-patchright.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/conftest.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docker-compose.yml +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/agent-reliability.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/aiv/AIV_FRAMEWORK_v5.3.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/anti-detection-ejecta.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/api-ergonomics-audit.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/api-reference.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/api-stability.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/architecture.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/behavioral-synthesis.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/browser-networking.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/cloak-integration.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/consistency-engine.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/design/inspect_redaction.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/discovery/DISCOVERY-REPORT.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/error-catalog.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/fingerprint-scoring.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/fingerprint-validation.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/gap-analysis.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/human-behavior.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/memory.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/migration/v1-to-v2.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/migration/v1.8-to-v1.9.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/operating-doctrine.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/platform-abstraction.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/plugins.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/quickstart.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/recording.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/rfcs/README.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-decomposition.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-a-api-simplification.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-b-network-stealth.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-c-behavioral-realism.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-d-challenge-infrastructure.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/rfcs/v2-track-e-e2e-harness.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/stealth-coverage.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/docs/stealth-evidence.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/backend_selection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/basic_usage.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/budget_tracking.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/cloak_stealth.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/error_handling.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/fingerprint_scan.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/human_behavior.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/multi_tab_workflow.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/session_persistence.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/examples/stealth_mode.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/adversarial_run.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/agent_efficiency_benchmark.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/browser_benchmark.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/e2e_trend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/run_stealth_gauntlet.sh +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/smoke_published.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/stress_real_world.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/validate_e2e_report.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/scripts/verify_release_artifact.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/__main__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/debug.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/delegator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/diagnostics.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/anthropic_client.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/browser_transport.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/budget_aware.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/factory.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/openai_client.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/llm/protocol.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/loop.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/loop_detector.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/plugins.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/registry.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/router.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/structured_logging.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/agent/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/bezier.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/dwell.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/fitts.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/gauss.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/keyboard.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/mouse.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/navigation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/orchestrator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/prng.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/qwerty.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/scroll.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/session_seed.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/behavioral/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/cdp_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/patchright_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/playwright_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/backends/selenium_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/cdp.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/cloak_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/cloud.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/discovery.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/engine.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/fetch.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/injectors/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/injectors/bidi_injector.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/injectors/cdp_injector.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/injectors/page_injector.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/page.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/session.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/shutdown.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/browser/tabs.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/cascade.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/client.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/compressor.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/cost_estimator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/credential_pool.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/governor.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/budget/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/cli/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/cli/commands.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/cli/interactive.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/cli/script.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/events/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/events/bus.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/events/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/cache.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/controller.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/decorator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/presets.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/recovery.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/snapshot.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/interaction/vision.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/memory/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/memory/integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/memory/store.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/memory/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/plugins/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/plugins/decorators.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/plugins/hooks.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/py.typed +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/persistence.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/recorder.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/replayer.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/report.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recording/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/checkpoint.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/classifier.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/coordinator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/event_bus.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/format_validator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/reflection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/retry_tracker.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/session_recovery.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/recovery/watchdogs.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/output.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/typed.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/results/validation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/action_redaction.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/approval.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/credential_vault.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/domain_filter.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/gate.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/injection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/manager.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/policy.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/redactor.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/security/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/session/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/session/proxy.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/activation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/markdown.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/registry.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/skills/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/action_policy.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/captcha.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/challenges/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/challenges/cache.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/challenges/pow.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/challenges/turnstile.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/dag.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/derive.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/errors.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/inject.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/inject_delivery.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/matrix.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/prng.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rule.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/audio.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/behavior.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/fonts.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/gpu.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/locale.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/navigator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/screen.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/consistency/rules/user_agent.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/diagnostics.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/audio.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/browser_apis.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/canvas.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/registry.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/timing.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ejecta/webrtc.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/fingerprint_scanner.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/fingerprint_score.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/headers.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/human.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/human_config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/ip_reputation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/manager.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/data/linux-chrome-stable.json +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/data/macos-chrome-stable.json +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/data/macos-m4-chrome-stable.json +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/data/windows-chrome-stable.json +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/host_detect.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/profiles/schema.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/proxy.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/proxy_pool.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/report.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/scoring.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/tls_baselines.json +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/user_agent_pool.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/checks.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/harness.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/report.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/stealth/validation/suite.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/testing.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/cost_analytics.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/flow_logger.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/middleware.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/session_db.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/sinks.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/tracing/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/ax_diff.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/hasher.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/verification/verifier.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/cache.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/controller.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/coords.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/factory.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/ocr.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/providers.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/src/super_browser/vision/types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/stress/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/stress/server.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/conftest.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/controlled_server.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/report.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/scoring.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/targets.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_controlled_server.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_targets_unit.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_tier1_scanners.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_tier2_vendors.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial/test_tier3_controlled.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/README.md +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/backends.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/behavioral_telemetry.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/core.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/engines/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/engines/scoring.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/harness.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/reporters/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/reporters/history.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/reporters/json_reporter.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/reporters/markdown_reporter.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/server.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/automation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/behavioral.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/controlled.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/ejector.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/external.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/fingerprint.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/adversarial3/vectors/network.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/pytest.ini +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/run.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/conftest.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_backends.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_behavioral_telemetry.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_behavioral_telemetry_smoke.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_behavioral_vectors.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_core.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_external.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_harness_smoke.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_header_ordering.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_reporters.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_scoring.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_server.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_superbrowser_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/adversarial_v3/tests/test_vectors.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/conftest.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/conftest.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_01_example_nav.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_02_google_search.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_03_github_login.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_04_amazon_search.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_05_google_forms.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_06_google_flights.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_07_wikipedia_extract.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_08_reddit_spa.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_09_form_complex.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/discovery/test_task_10_signup_flow.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/conftest.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_behavioral_realism.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_challenge_detection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_interaction.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_live_navigation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_multi_tab.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_navigation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_session_persistence.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e/test_stealth_overhead.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/e2e_v1_3_journey.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/conftest.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_config_composition.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_engine_backends.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_error_paths.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_facade_smoke.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_full_lifecycle.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_multi_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_performance_smoke.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_playwright_integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_public_api.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_session_persistence.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_stealth_abstraction.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v1100_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v150_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v160_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v170_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v180_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v190_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v191_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v192_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v193_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v194_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v195_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v1_3_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/integration/test_v1_4_features.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/pattern_validation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/conftest.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_chrome_runtime.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_cli_switches.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_headless_indicators.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_live_sites.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_runtime_enable.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/stealth_detection/test_webdriver.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_action_timeout.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_browser_transport.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_controller_rebinding.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_debug_mode.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_default_tooling.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_delegator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_error_screenshots.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security_control.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security_file_tab.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security_network.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_facade_security_session.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_fail_fast.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_llm.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_llm_budget.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_llm_production.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_llm_streaming.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_loop.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_loop_detector.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_prompt_isolation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_registry.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_retry_budget.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_streaming.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_structured_logging.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_tab_cap.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_task_02.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_agent/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_behavioral.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_dwell.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_hardening.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_human_config_dwell.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_navigation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_orchestrator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_behavioral/test_session_seed.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_benchmark/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_benchmark/test_efficiency.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_benchmarks/test_browser_benchmark.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_benchmarks/test_stress_real_world.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cdp.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cdp_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cloak_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cloak_docs.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_cloak_integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_discovery.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_engine_protocol.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_fetch.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_injectors.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_page.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_patchright_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_playwright_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_selenium_backend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_session.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_browser/test_shutdown.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_cascade.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_cascade_governor.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_circuit_breaker.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_client.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_compressor.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_cost_estimator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_credential_pool.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_governor.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_budget/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_interactive.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_script.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_stealth_check.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_stealth_validate.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_cli/test_unified_cli.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_diagnostics.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_e2e/test_report_schema.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_e2e/test_trend.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_audio.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_batch37_integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_batch38_integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_browser_apis.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_canvas.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_timing.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_ejecta/test_webrtc.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_events/test_event_bus.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_events/test_lifecycle_hooks.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_governance_docs.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_cache.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_controller.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_decorator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_injection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_page_change.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_presets.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_recovery.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_snapshot.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_interaction/test_vision.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_diagnostics.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_entrypoint.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_interaction.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_navigation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_permissions.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_redaction.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_server.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_server_smoke.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_write_tools.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_mcp_write_tools_wave2.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_memory/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_memory/test_cli_config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_memory/test_integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_memory/test_store.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recording/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recording/test_persistence.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recording/test_recorder.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recording/test_replayer.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_checkpoint.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_classifier.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_coordinator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_event_bus.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_format_validator.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_reflection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_retry_tracker.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_session_recovery.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_recovery/test_watchdogs.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_release/test_naming_consistency.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_release/test_smoke_published.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_release/test_verify_artifact.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_results/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_batch40_integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_categories.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_output.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_typed.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_results/test_validation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_runtime_correctness/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_runtime_correctness/test_runtime_fixes.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_approval.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_credential_vault.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_domain_filter.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_injection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_manager.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_policy.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_redaction_pipeline.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_redactor.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_security/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_session/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_session/test_locale.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_session/test_proxy.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_skills/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_activation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_integration.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_markdown.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_registry.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_skills/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_action_policy.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_captcha.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_captcha_resolution.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_challenge_cache.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_challenge_config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_consistency/test_consistency.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_consistency_inject.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_diagnostics.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_e2e_lifecycle.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_e2e_reporting.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_fingerprint_scanner.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_fingerprint_score.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_headers.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_human.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_human_behavior_v2.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_ip_reputation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_kasada_detection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_manager.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_network_stealth_config.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_profiles.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_proxy.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_proxy_pool.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_stealth_bridge.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_tls_fingerprint.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_turnstile_detection.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_user_agent_pool.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_stealth/test_validation.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_cost_analytics.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_flow_logger.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_middleware.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_session_db.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_sinks.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_tracing/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_verification/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_verification/test_ax_diff.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_verification/test_hasher.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_verification/test_types.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_verification/test_verifier.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_vision/__init__.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_cache.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_controller.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_coords.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_factory.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_ocr.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_providers.py +0 -0
- {superbrowser_sdk-2.8.0 → superbrowser_sdk-2.9.0}/tests/test_vision/test_types.py +0 -0
|
@@ -5,6 +5,38 @@ 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.9.0] — 2026-06-27
|
|
9
|
+
|
|
10
|
+
### Added — MCP observe actionable targets
|
|
11
|
+
|
|
12
|
+
`observe` now returns a `targets` array of actionable element references
|
|
13
|
+
extracted from the accessibility snapshot. Each target includes:
|
|
14
|
+
|
|
15
|
+
- `target` — a ref string (e.g. `@e0`) usable as the `target` argument for
|
|
16
|
+
coordinate-tier action tools: `click`, `fill`, `type_text`, `hover`,
|
|
17
|
+
`select_option`. Checkbox/radio targets map to `click` (toggle-like) because
|
|
18
|
+
`check`/`uncheck` are selector-tier only and cannot resolve `@refs`.
|
|
19
|
+
- `role` — the AX role (button, textbox, checkbox, combobox, link, etc.)
|
|
20
|
+
- `name` — the accessible name (subject to inspect-output redaction)
|
|
21
|
+
- `action_hint` — recommended action for the role (`click`, `fill`,
|
|
22
|
+
select_option)
|
|
23
|
+
|
|
24
|
+
Targets are capped at 50 interactive, non-disabled elements.
|
|
25
|
+
`targets_truncated` indicates when more exist. This closes the gap where
|
|
26
|
+
agents had to guess CSS selectors — they can now go `observe → action`
|
|
27
|
+
deterministically using the refs returned by `observe`.
|
|
28
|
+
|
|
29
|
+
### Documentation — MCP tool metadata design note (P4)
|
|
30
|
+
|
|
31
|
+
Added `docs/design/mcp_tool_metadata.md` — a design note analyzing whether
|
|
32
|
+
MCP tool schemas, tiers, validation, and docs should be unified onto the
|
|
33
|
+
existing `ToolDefinition` registry. **Decision: defer full unification.** The
|
|
34
|
+
current `ToolDefinition` cannot express MCP-specific metadata (tiers, enums,
|
|
35
|
+
ranges, validation hooks, bool-as-int rejection) without lossy flattening. Keep
|
|
36
|
+
`mcp_server.py` as the MCP source of truth until tool count or a production
|
|
37
|
+
mismatch justifies change. Trigger conditions and three future options
|
|
38
|
+
documented.
|
|
39
|
+
|
|
8
40
|
## [2.8.0] — 2026-06-26
|
|
9
41
|
|
|
10
42
|
### Added — MCP interaction tools (P3.1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superbrowser-sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.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
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Design Note: MCP Tool Metadata Unification
|
|
2
|
+
|
|
3
|
+
> **Status:** Design note. No implementation.
|
|
4
|
+
> **Decision:** Defer full unification. Document the metadata contract; keep
|
|
5
|
+
> `mcp_server.py` as the MCP source of truth until pressure justifies change.
|
|
6
|
+
> **Date:** 2026-06-26
|
|
7
|
+
|
|
8
|
+
## Core question
|
|
9
|
+
|
|
10
|
+
Should Super-Browser extend `ToolDefinition` to become the single source of
|
|
11
|
+
truth for MCP schemas, tiers, validation, and docs — or should MCP remain
|
|
12
|
+
hand-curated until there is stronger pressure?
|
|
13
|
+
|
|
14
|
+
## Current state (v2.8.0)
|
|
15
|
+
|
|
16
|
+
The MCP server advertises **29 tools** in action mode (17 default). Tool
|
|
17
|
+
metadata is maintained in three parallel places:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
1. ToolRegistry / ToolDefinition / ToolParameter (agent-loop path)
|
|
21
|
+
- src/super_browser/agent/registry.py
|
|
22
|
+
- Typed specs, handlers, JSON schemas, toolsets, security_level
|
|
23
|
+
- Used by AgentLoop for the embedded act() path
|
|
24
|
+
|
|
25
|
+
2. MCP types.Tool definitions + _tool_* handlers (MCP path)
|
|
26
|
+
- src/super_browser/mcp_server.py
|
|
27
|
+
- Hand-maintained lists: PHASE1_TOOLS, NAVIGATION_AUX_TOOLS,
|
|
28
|
+
DIAGNOSTICS_TOOLS, INTERACTION_TOOLS, PHASE2B_TOOLS, PHASE2B_WAVE2_TOOLS
|
|
29
|
+
- Handlers wired by name-string convention: getattr(self, f"_tool_{name}")
|
|
30
|
+
|
|
31
|
+
3. MCP tier names + validation + authorization path (MCP path)
|
|
32
|
+
- INSPECT_TOOL_NAMES, NAVIGATION_TOOL_NAMES, ACTION_TOOL_NAMES frozensets
|
|
33
|
+
- Tool-tier list membership determines advertised/default/action behavior
|
|
34
|
+
- _validate_navigation_args / _validate_action_args (hand-written Python)
|
|
35
|
+
- MCPAuthorizer / SecurityManager path for action authorization
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
These three sources are synchronized manually. Tests assert advertised counts
|
|
39
|
+
and tier membership, but there is no compile-time guarantee they agree.
|
|
40
|
+
|
|
41
|
+
## Problem
|
|
42
|
+
|
|
43
|
+
Duplication is growing. Each new MCP tool requires:
|
|
44
|
+
|
|
45
|
+
- A `types.Tool` definition (schema, description)
|
|
46
|
+
- A `_tool_*` handler method
|
|
47
|
+
- An entry in the right `*_TOOLS` list (which determines tier membership)
|
|
48
|
+
- An entry in `_validate_action_args` or `_validate_navigation_args` (hand-written validation)
|
|
49
|
+
- An entry in the `ACTION_TOOL_NAMES` / `NAVIGATION_TOOL_NAMES` frozenset
|
|
50
|
+
- Updates to count assertions across 4+ test files
|
|
51
|
+
- Updates to `docs/mcp.md` (tool table + counts)
|
|
52
|
+
- Updates to `CHANGELOG.md`
|
|
53
|
+
|
|
54
|
+
That is 8 touch points per tool. With 29 tools now and P5/P6 work still ahead,
|
|
55
|
+
the maintenance surface is real.
|
|
56
|
+
|
|
57
|
+
## Why current ToolDefinition cannot serve as MCP source of truth
|
|
58
|
+
|
|
59
|
+
Fact-checked against `src/super_browser/agent/registry.py` (lines 17-63):
|
|
60
|
+
|
|
61
|
+
### 1. Schema expressiveness is too flat
|
|
62
|
+
|
|
63
|
+
`ToolDefinition.to_json_schema()` produces a flat type system:
|
|
64
|
+
`str→string, int→integer, float→number, bool→boolean`. It cannot express:
|
|
65
|
+
|
|
66
|
+
- **Enums** — used heavily: `scroll.direction`, `wait_for.load_state`,
|
|
67
|
+
`select_option.by`, `reload.wait_until`
|
|
68
|
+
- **Defaults** — MCP uses `"default": false`, `"default": 10000`;
|
|
69
|
+
`ToolParameter` stores a default but `to_json_schema()` never emits it
|
|
70
|
+
- **Numeric ranges** — `wait_for.timeout_ms` (100–60000),
|
|
71
|
+
`type_text.delay_ms` (0–1000)
|
|
72
|
+
- **Bool-as-int rejection** — MCP validation explicitly rejects `bool` where
|
|
73
|
+
`int` is expected; `ToolParameter` has no concept of this
|
|
74
|
+
- **Nested objects / arrays** — MCP `inputSchema.properties` can nest
|
|
75
|
+
|
|
76
|
+
### 2. Tier metadata is a different axis
|
|
77
|
+
|
|
78
|
+
`ToolDefinition.security_level` takes values `safe`/`sensitive`/`dangerous`
|
|
79
|
+
(a risk scale). MCP tiers are `inspect`/`navigation`/`action` (permission
|
|
80
|
+
buckets, assigned by list membership). There is no automatic mapping:
|
|
81
|
+
|
|
82
|
+
- `navigate` is `sensitive` but navigation-tier (default-allowed)
|
|
83
|
+
- `scroll` is `safe` but action-tier (gated)
|
|
84
|
+
- `screenshot` is `sensitive` but inspect-tier (no security check)
|
|
85
|
+
|
|
86
|
+
`ToolDefinition` has no `tier` field. Its `toolsets` field is a grouping
|
|
87
|
+
concept unrelated to MCP permission tiers.
|
|
88
|
+
|
|
89
|
+
### 3. Validation hooks are hand-written Python
|
|
90
|
+
|
|
91
|
+
MCP argument validation (`_validate_navigation_args`,
|
|
92
|
+
`_validate_action_args`) contains logic that no schema can express:
|
|
93
|
+
non-empty string checks, bool-as-int rejection, range bounds, exactly-one-
|
|
94
|
+
condition constraints (`wait_for`). This logic cannot be generated from any
|
|
95
|
+
data structure — it requires executable validation hooks.
|
|
96
|
+
|
|
97
|
+
### 4. Handler dispatch is name-string convention
|
|
98
|
+
|
|
99
|
+
MCP dispatches via `getattr(self, f"_tool_{name}")`. This is a runtime
|
|
100
|
+
convention with no type safety. `ToolDefinition.handler` is a callable
|
|
101
|
+
reference, but the MCP path doesn't use it — it uses its own dispatch table.
|
|
102
|
+
|
|
103
|
+
## What MCP metadata would need (the full contract)
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
Per-tool metadata required:
|
|
107
|
+
- tool name (str)
|
|
108
|
+
- tier: inspect | navigation | action | high_risk
|
|
109
|
+
- advertised_by_default: bool (derived from tier)
|
|
110
|
+
- security_level: safe | sensitive | dangerous
|
|
111
|
+
- action_budget: consumes | does_not_consume
|
|
112
|
+
- input schema:
|
|
113
|
+
- parameter name
|
|
114
|
+
- type (str, int, bool, str-enum, ...)
|
|
115
|
+
- required: bool
|
|
116
|
+
- default value
|
|
117
|
+
- enum values (where applicable)
|
|
118
|
+
- numeric range (min, max)
|
|
119
|
+
- reject_bool_as_int: bool
|
|
120
|
+
- validation hook: callable(args) -> error | None
|
|
121
|
+
- handler binding: callable or name convention
|
|
122
|
+
- description (for MCP tool listing)
|
|
123
|
+
- redaction policy: which output fields to redact, text vs URL
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This is substantially richer than what `ToolDefinition` carries today.
|
|
127
|
+
|
|
128
|
+
## Decision: defer full unification
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
Do not implement automatic MCP schema generation now.
|
|
132
|
+
|
|
133
|
+
Reasons:
|
|
134
|
+
1. Current ToolDefinition cannot express MCP metadata without lossy flattening.
|
|
135
|
+
2. Forcing MCP schemas through it would damage validation, enums, ranges.
|
|
136
|
+
3. The maintenance pain (8 touch points per tool) is real but manageable
|
|
137
|
+
at 29 tools.
|
|
138
|
+
4. A partial generator that can't express tier/validation/security
|
|
139
|
+
faithfully is worse than hand-curated — it would create a false sense
|
|
140
|
+
of single-source-of-truth while silently diverging.
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## What to do instead
|
|
144
|
+
|
|
145
|
+
### Now (no code change)
|
|
146
|
+
|
|
147
|
+
Keep `mcp_server.py` as the MCP source of truth. Document this design note
|
|
148
|
+
as the contract for what a future unification would require.
|
|
149
|
+
|
|
150
|
+
### Trigger conditions for revisiting
|
|
151
|
+
|
|
152
|
+
Re-evaluate when any of these become true:
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
1. MCP tool count exceeds ~40 (currently 29)
|
|
156
|
+
2. A tool is added with the wrong tier and isn't caught until production
|
|
157
|
+
3. Validation logic is duplicated between MCP and SDK paths
|
|
158
|
+
4. A third consumer (e.g. external-agent API) needs the same metadata
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Future options (when triggered)
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
Option A — MCPToolDefinition wrapper:
|
|
165
|
+
A new dataclass that wraps ToolDefinition and adds MCP-specific fields
|
|
166
|
+
(tier, advertised_by_default, validation_hook, redaction_policy).
|
|
167
|
+
Pro: doesn't pollute the SDK registry.
|
|
168
|
+
Con: still two definitions per tool.
|
|
169
|
+
|
|
170
|
+
Option B — Extend ToolDefinition:
|
|
171
|
+
Add tier, enum_constraints, defaults, ranges, validation_hook fields.
|
|
172
|
+
Pro: true single source of truth.
|
|
173
|
+
Con: makes the SDK registry awkward for non-MCP consumers; schema migration.
|
|
174
|
+
|
|
175
|
+
Option C — Generate MCP from a new tool-spec module:
|
|
176
|
+
A dedicated mcp_tools.py that defines tool specs with full metadata,
|
|
177
|
+
generates types.Tool objects, validation functions, and docs entries.
|
|
178
|
+
Pro: MCP owns its own metadata; no SDK pollution.
|
|
179
|
+
Con: doesn't unify with the SDK registry (but that may be acceptable).
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The design note recommends **Option C** if/when triggered — it keeps MCP
|
|
183
|
+
and SDK concerns separate while reducing MCP's internal duplication.
|
|
184
|
+
|
|
185
|
+
## Comparison to existing inspect-redaction design
|
|
186
|
+
|
|
187
|
+
The P2.3 redaction design (`docs/design/inspect_redaction.md`) took a
|
|
188
|
+
similar approach: document the boundary, reuse existing machinery, defer
|
|
189
|
+
per-tool overrides. This note follows the same pattern for tool metadata.
|
|
190
|
+
|
|
191
|
+
## Summary
|
|
192
|
+
|
|
193
|
+
```text
|
|
194
|
+
Problem: 8 touch points per MCP tool; metadata in 3+ places.
|
|
195
|
+
Root cause: ToolDefinition is too flat for MCP's needs.
|
|
196
|
+
Decision: Defer unification. Keep hand-curated MCP.
|
|
197
|
+
Trigger: ~40 tools, or a tier-mismatch production incident.
|
|
198
|
+
Preferred future path: Option C (dedicated MCP tool-spec module).
|
|
199
|
+
```
|
|
@@ -115,7 +115,7 @@ advertised; the third requires action mode; the fourth is not implemented.
|
|
|
115
115
|
|---|---|---|---|
|
|
116
116
|
| `browser_status` | none | Runtime status (running, backend). | No |
|
|
117
117
|
| `current_url` | none | Current URL, or a structured "not started" state. | No |
|
|
118
|
-
| `observe` | none | Page state: URL, title, interactive/total element counts. | Yes |
|
|
118
|
+
| `observe` | none | Page state: URL, title, interactive/total element counts, and a `targets` array of actionable element references (capped at 50). Each target includes `target` (a ref like `@e0`, usable as the `target` argument for coordinate-tier action tools: `click`, `fill`, `type_text`, `hover`, `select_option`), `role`, `name`, and `action_hint`. | Yes |
|
|
119
119
|
| `extract_text` | `query` (required), `selector` (optional) | Text content, optionally scoped to a CSS selector. | Yes |
|
|
120
120
|
| `screenshot` | `full_page` (optional, default `false`) | Base64 PNG of the viewport or full page. | Yes |
|
|
121
121
|
| `list_tabs` | none | Snapshot of open tabs. | Yes |
|
|
@@ -162,7 +162,17 @@ results; compound waits can be added later as an explicit AND mode).
|
|
|
162
162
|
navigate → wait_for → observe / extract_text / screenshot
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
-
This is the default-mode loop an agent uses to read a page.
|
|
165
|
+
This is the default-mode loop an agent uses to read a page. `observe` returns
|
|
166
|
+
actionable targets (`@e0` refs) that can be passed directly as the `target`
|
|
167
|
+
argument to coordinate-tier action tools (`click`, `fill`, `type_text`,
|
|
168
|
+
`hover`, `select_option`):
|
|
169
|
+
|
|
170
|
+
```text
|
|
171
|
+
navigate → wait_for → observe → click(target="@e0")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The `targets` array is capped at 50; `targets_truncated` indicates whether more
|
|
175
|
+
interactive elements exist. Target names are subject to inspect-output redaction.
|
|
166
176
|
|
|
167
177
|
#### Debugging workflow
|
|
168
178
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "superbrowser-sdk"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.9.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.9.0"
|
|
10
10
|
|
|
11
11
|
__all__ = [
|
|
12
12
|
"SuperBrowser",
|
|
@@ -482,10 +482,49 @@ class SuperBrowser:
|
|
|
482
482
|
snap = await self._controller.capture_ax_snapshot()
|
|
483
483
|
interactive_count = sum(1 for n in snap.nodes.values() if n.is_interactive)
|
|
484
484
|
|
|
485
|
+
# Build actionable targets from the AX snapshot.
|
|
486
|
+
# The ref (e.g. "@e0") is directly usable as a `target` argument for
|
|
487
|
+
# click/fill/type_text/etc. — the controller's coordinate tier resolves
|
|
488
|
+
# @refs to element coordinates via the snapshot.
|
|
489
|
+
_ROLE_ACTION_MAP = {
|
|
490
|
+
"button": "click", "link": "click", "menuitem": "click",
|
|
491
|
+
"tab": "click", "treeitem": "click", "option": "click",
|
|
492
|
+
"textbox": "fill", "searchbox": "fill", "spinbutton": "fill",
|
|
493
|
+
"combobox": "select_option", "checkbox": "click", "radio": "click",
|
|
494
|
+
"slider": "fill", "switch": "click",
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
# Only include nodes whose center is resolvable (bounds present),
|
|
498
|
+
# because @refs are resolved via the coordinate tier. Nodes without
|
|
499
|
+
# bounds cannot be acted on and would produce a confusing target.
|
|
500
|
+
# Checkbox/radio map to "click" (not "check") because check/uncheck
|
|
501
|
+
# are selector-tier only and cannot resolve @refs.
|
|
502
|
+
all_interactive = [
|
|
503
|
+
n for n in snap.nodes.values()
|
|
504
|
+
if n.is_interactive and not n.disabled and n.center is not None
|
|
505
|
+
]
|
|
506
|
+
_MAX_TARGETS = 50
|
|
507
|
+
capped = all_interactive[:_MAX_TARGETS]
|
|
508
|
+
targets = [
|
|
509
|
+
{
|
|
510
|
+
"target": n.ref if n.ref.startswith("@") else f"@{n.ref}",
|
|
511
|
+
"role": n.role,
|
|
512
|
+
"name": n.name,
|
|
513
|
+
"action_hint": _ROLE_ACTION_MAP.get(n.role, "click"),
|
|
514
|
+
}
|
|
515
|
+
for n in capped
|
|
516
|
+
]
|
|
517
|
+
|
|
485
518
|
return timed_action_result(
|
|
486
519
|
ok=True,
|
|
487
520
|
start_ns=start,
|
|
488
|
-
data={
|
|
521
|
+
data={
|
|
522
|
+
"url": url, "title": title,
|
|
523
|
+
"interactive_elements": interactive_count,
|
|
524
|
+
"total_elements": len(snap.nodes),
|
|
525
|
+
"targets": targets,
|
|
526
|
+
"targets_truncated": len(all_interactive) > _MAX_TARGETS,
|
|
527
|
+
},
|
|
489
528
|
)
|
|
490
529
|
|
|
491
530
|
# -- Tab helper (CHK-07) --
|
|
@@ -1489,9 +1489,17 @@ class ToolDispatcher:
|
|
|
1489
1489
|
_redact_field(payload, field, is_url=True)
|
|
1490
1490
|
|
|
1491
1491
|
# Redact list-of-dicts entries.
|
|
1492
|
+
# Supports dotted paths like "data.targets" for lists nested under a dict.
|
|
1492
1493
|
if list_keys:
|
|
1493
1494
|
for list_key, inner_fields in list_keys.items():
|
|
1494
|
-
|
|
1495
|
+
# Navigate dotted path (e.g. "data.targets" → payload["data"]["targets"])
|
|
1496
|
+
items = payload
|
|
1497
|
+
for part in list_key.split("."):
|
|
1498
|
+
if isinstance(items, dict):
|
|
1499
|
+
items = items.get(part)
|
|
1500
|
+
else:
|
|
1501
|
+
items = None
|
|
1502
|
+
break
|
|
1495
1503
|
if not isinstance(items, list):
|
|
1496
1504
|
continue
|
|
1497
1505
|
for item in items:
|
|
@@ -1579,10 +1587,13 @@ class ToolDispatcher:
|
|
|
1579
1587
|
sb = await self.runtime.get_browser()
|
|
1580
1588
|
ar = await sb.observe()
|
|
1581
1589
|
payload = _serialize_action_result(ar)
|
|
1582
|
-
# observe nests URL/title under data dict
|
|
1583
|
-
|
|
1590
|
+
# observe nests URL/title/targets under data dict.
|
|
1591
|
+
# Redact url/title (nested fields) and target names (nested list-of-dicts).
|
|
1592
|
+
data = payload.get("data")
|
|
1593
|
+
nested = {"data": ("url", "title")} if isinstance(data, dict) else None
|
|
1584
1594
|
return _text_content(self._redact_inspect_output(
|
|
1585
1595
|
payload, nested_keys=nested,
|
|
1596
|
+
list_keys={"data.targets": ("name",)} if isinstance(data, dict) and isinstance(data.get("targets"), list) else None,
|
|
1586
1597
|
))
|
|
1587
1598
|
|
|
1588
1599
|
async def _tool_extract_text(self, arguments: dict[str, Any]) -> list[types.TextContent]:
|