feat(browser): add optional rust-native backend via fantoccini
* feat(browser): add optional rust-native automation backend * style: align channels module with stable rustfmt * fix(browser): switch rust-native backend to fantoccini Replace headless_chrome with fantoccini to satisfy license checks and keep browser-native optional. Adds native_webdriver_url wiring, migrates native backend session/actions to WebDriver, updates docs/config defaults, and keeps backend auto-resolution behavior intact. * test(config): serialize env override tests with lock Prevent flaky CI failures caused by concurrent environment variable mutation across config env-override tests. * style: apply rustfmt 1.92 for CI parity * chore(ci): sync lockfile and rustfmt with current main Resolve feature table drift after rebasing onto latest main, refresh Cargo.lock for browser-native fantoccini, and apply rustfmt 1.92 formatting required by CI.
This commit is contained in:
parent
9d29f30a31
commit
85fc12bcf7
7 changed files with 1412 additions and 64 deletions
414
Cargo.lock
generated
414
Cargo.lock
generated
|
|
@ -159,7 +159,7 @@ dependencies = [
|
||||||
"axum-core",
|
"axum-core",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
|
@ -191,7 +191,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"mime",
|
"mime",
|
||||||
|
|
@ -390,12 +390,52 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie"
|
||||||
|
version = "0.16.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
|
||||||
|
dependencies = [
|
||||||
|
"time",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
"time",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation-sys"
|
||||||
version = "0.8.7"
|
version = "0.8.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core_maths"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30"
|
||||||
|
dependencies = [
|
||||||
|
"libm",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
|
@ -433,6 +473,15 @@ version = "2.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
|
checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dialoguer"
|
name = "dialoguer"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
|
@ -593,6 +642,29 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fantoccini"
|
||||||
|
version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d0086bcd59795408c87a04f94b5a8bd62cba2856cfe656c7e6439061d95b760"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"cookie 0.18.1",
|
||||||
|
"futures-util",
|
||||||
|
"http 1.4.0",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper",
|
||||||
|
"hyper-rustls",
|
||||||
|
"hyper-util",
|
||||||
|
"mime",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"time",
|
||||||
|
"tokio",
|
||||||
|
"url",
|
||||||
|
"webdriver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "2.3.0"
|
version = "2.3.0"
|
||||||
|
|
@ -846,6 +918,17 @@ dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "0.2.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
|
@ -863,7 +946,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -874,7 +957,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
@ -901,7 +984,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
"httpdate",
|
"httpdate",
|
||||||
|
|
@ -919,10 +1002,12 @@ version = "0.27.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
|
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
|
"log",
|
||||||
"rustls",
|
"rustls",
|
||||||
|
"rustls-native-certs",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
|
|
@ -940,7 +1025,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
|
|
@ -977,6 +1062,18 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_collections"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"yoke 0.7.5",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec 0.10.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "icu_collections"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
|
|
@ -985,9 +1082,9 @@ checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"potential_utf",
|
"potential_utf",
|
||||||
"yoke",
|
"yoke 0.8.1",
|
||||||
"zerofrom",
|
"zerofrom",
|
||||||
"zerovec",
|
"zerovec 0.11.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -997,10 +1094,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
|
checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"litemap",
|
"litemap 0.8.1",
|
||||||
"tinystr",
|
"tinystr 0.8.2",
|
||||||
"writeable",
|
"writeable 0.6.2",
|
||||||
"zerovec",
|
"zerovec 0.11.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_locid"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"litemap 0.7.5",
|
||||||
|
"tinystr 0.7.6",
|
||||||
|
"writeable 0.5.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1009,12 +1118,12 @@ version = "2.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
|
checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"icu_collections",
|
"icu_collections 2.1.1",
|
||||||
"icu_normalizer_data",
|
"icu_normalizer_data",
|
||||||
"icu_properties",
|
"icu_properties",
|
||||||
"icu_provider",
|
"icu_provider 2.1.1",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"zerovec",
|
"zerovec 0.11.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1029,12 +1138,12 @@ version = "2.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
|
checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"icu_collections",
|
"icu_collections 2.1.1",
|
||||||
"icu_locale_core",
|
"icu_locale_core",
|
||||||
"icu_properties_data",
|
"icu_properties_data",
|
||||||
"icu_provider",
|
"icu_provider 2.1.1",
|
||||||
"zerotrie",
|
"zerotrie",
|
||||||
"zerovec",
|
"zerovec 0.11.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1043,6 +1152,23 @@ version = "2.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"
|
checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_provider"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_provider_macros",
|
||||||
|
"stable_deref_trait",
|
||||||
|
"tinystr 0.7.6",
|
||||||
|
"writeable 0.5.5",
|
||||||
|
"yoke 0.7.5",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec 0.10.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_provider"
|
name = "icu_provider"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
|
|
@ -1051,13 +1177,46 @@ checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"icu_locale_core",
|
"icu_locale_core",
|
||||||
"writeable",
|
"writeable 0.6.2",
|
||||||
"yoke",
|
"yoke 0.8.1",
|
||||||
"zerofrom",
|
"zerofrom",
|
||||||
"zerotrie",
|
"zerotrie",
|
||||||
"zerovec",
|
"zerovec 0.11.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_provider_macros"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_segmenter"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a717725612346ffc2d7b42c94b820db6908048f39434504cb130e8b46256b0de"
|
||||||
|
dependencies = [
|
||||||
|
"core_maths",
|
||||||
|
"displaydoc",
|
||||||
|
"icu_collections 1.5.0",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_provider 1.5.0",
|
||||||
|
"icu_segmenter_data",
|
||||||
|
"utf8_iter",
|
||||||
|
"zerovec 0.10.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_segmenter_data"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1e52775179941363cc594e49ce99284d13d6948928d8e72c755f55e98caa1eb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "id-arena"
|
name = "id-arena"
|
||||||
version = "2.3.0"
|
version = "2.3.0"
|
||||||
|
|
@ -1216,6 +1375,12 @@ version = "0.2.182"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libm"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
|
@ -1243,6 +1408,12 @@ version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "litemap"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litemap"
|
name = "litemap"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|
@ -1352,6 +1523,12 @@ dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
|
|
@ -1388,6 +1565,12 @@ version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-probe"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry"
|
name = "opentelemetry"
|
||||||
version = "0.31.0"
|
version = "0.31.0"
|
||||||
|
|
@ -1409,7 +1592,7 @@ checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"opentelemetry",
|
"opentelemetry",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
]
|
]
|
||||||
|
|
@ -1420,7 +1603,7 @@ version = "0.31.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf"
|
checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"opentelemetry",
|
"opentelemetry",
|
||||||
"opentelemetry-http",
|
"opentelemetry-http",
|
||||||
"opentelemetry-proto",
|
"opentelemetry-proto",
|
||||||
|
|
@ -1548,9 +1731,15 @@ version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
|
checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerovec",
|
"zerovec 0.11.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
|
|
@ -1803,7 +1992,7 @@ dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
|
@ -1898,6 +2087,18 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-native-certs"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
|
||||||
|
dependencies = [
|
||||||
|
"openssl-probe",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"schannel",
|
||||||
|
"security-framework",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pki-types"
|
name = "rustls-pki-types"
|
||||||
version = "1.14.0"
|
version = "1.14.0"
|
||||||
|
|
@ -1932,12 +2133,44 @@ version = "1.0.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "schannel"
|
||||||
|
version = "0.1.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "security-framework"
|
||||||
|
version = "3.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"core-foundation",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
"security-framework-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "security-framework-sys"
|
||||||
|
version = "2.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.27"
|
version = "1.0.27"
|
||||||
|
|
@ -2227,6 +2460,46 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"itoa",
|
||||||
|
"num-conv",
|
||||||
|
"powerfmt",
|
||||||
|
"serde_core",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinystr"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinystr"
|
name = "tinystr"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
|
@ -2234,7 +2507,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
|
checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"zerovec",
|
"zerovec 0.11.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2390,7 +2663,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
|
@ -2437,7 +2710,7 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"iri-string",
|
"iri-string",
|
||||||
|
|
@ -2518,7 +2791,7 @@ dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"http",
|
"http 1.4.0",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
|
@ -2787,6 +3060,26 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webdriver"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91d53921e1bef27512fa358179c9a22428d55778d2c2ae3c5c37a52b82ce6e92"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"bytes",
|
||||||
|
"cookie 0.16.2",
|
||||||
|
"http 0.2.12",
|
||||||
|
"icu_segmenter",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
"time",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.26.11"
|
version = "0.26.11"
|
||||||
|
|
@ -3192,12 +3485,30 @@ dependencies = [
|
||||||
"wasmparser",
|
"wasmparser",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "writeable"
|
||||||
|
version = "0.5.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "writeable"
|
name = "writeable"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
|
checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"stable_deref_trait",
|
||||||
|
"yoke-derive 0.7.5",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|
@ -3205,10 +3516,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
|
checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
"yoke-derive",
|
"yoke-derive 0.8.1",
|
||||||
"zerofrom",
|
"zerofrom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke-derive"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke-derive"
|
name = "yoke-derive"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|
@ -3236,6 +3559,7 @@ dependencies = [
|
||||||
"cron",
|
"cron",
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"directories",
|
"directories",
|
||||||
|
"fantoccini",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"glob",
|
"glob",
|
||||||
"hex",
|
"hex",
|
||||||
|
|
@ -3326,19 +3650,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
|
checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"yoke",
|
"yoke 0.8.1",
|
||||||
"zerofrom",
|
"zerofrom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
|
||||||
|
dependencies = [
|
||||||
|
"yoke 0.7.5",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec-derive 0.10.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerovec"
|
name = "zerovec"
|
||||||
version = "0.11.5"
|
version = "0.11.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
|
checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"yoke",
|
"yoke 0.8.1",
|
||||||
"zerofrom",
|
"zerofrom",
|
||||||
"zerovec-derive",
|
"zerovec-derive 0.11.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec-derive"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@ prometheus = { version = "0.13", default-features = false }
|
||||||
# Base64 encoding (screenshots, image data)
|
# Base64 encoding (screenshots, image data)
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
|
|
||||||
|
# Optional Rust-native browser automation backend
|
||||||
|
fantoccini = { version = "0.22.0", optional = true, default-features = false, features = ["rustls-tls"] }
|
||||||
|
|
||||||
# Error handling
|
# Error handling
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
thiserror = "2.0"
|
thiserror = "2.0"
|
||||||
|
|
@ -96,6 +99,7 @@ opentelemetry-otlp = { version = "0.31", default-features = false, features = ["
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
browser-native = ["dep:fantoccini"]
|
||||||
|
|
||||||
# Sandbox backends (platform-specific, opt-in)
|
# Sandbox backends (platform-specific, opt-in)
|
||||||
sandbox-landlock = ["landlock"] # Linux kernel LSM
|
sandbox-landlock = ["landlock"] # Linux kernel LSM
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -128,7 +128,7 @@ Every subsystem is a **trait** — swap implementations with a config change, ze
|
||||||
| **AI Models** | `Provider` | 22+ providers (OpenRouter, Anthropic, OpenAI, Ollama, Venice, Groq, Mistral, xAI, DeepSeek, Together, Fireworks, Perplexity, Cohere, Bedrock, etc.) | `custom:https://your-api.com` — any OpenAI-compatible API |
|
| **AI Models** | `Provider` | 22+ providers (OpenRouter, Anthropic, OpenAI, Ollama, Venice, Groq, Mistral, xAI, DeepSeek, Together, Fireworks, Perplexity, Cohere, Bedrock, etc.) | `custom:https://your-api.com` — any OpenAI-compatible API |
|
||||||
| **Channels** | `Channel` | CLI, Telegram, Discord, Slack, iMessage, Matrix, WhatsApp, Webhook | Any messaging API |
|
| **Channels** | `Channel` | CLI, Telegram, Discord, Slack, iMessage, Matrix, WhatsApp, Webhook | Any messaging API |
|
||||||
| **Memory** | `Memory` | SQLite with hybrid search (FTS5 + vector cosine similarity), Markdown | Any persistence backend |
|
| **Memory** | `Memory` | SQLite with hybrid search (FTS5 + vector cosine similarity), Markdown | Any persistence backend |
|
||||||
| **Tools** | `Tool` | shell, file_read, file_write, memory_store, memory_recall, memory_forget, browser_open (Brave + allowlist), composio (optional) | Any capability |
|
| **Tools** | `Tool` | shell, file_read, file_write, memory_store, memory_recall, memory_forget, browser_open (Brave + allowlist), browser (agent-browser / rust-native), composio (optional) | Any capability |
|
||||||
| **Observability** | `Observer` | Noop, Log, Multi | Prometheus, OTel |
|
| **Observability** | `Observer` | Noop, Log, Multi | Prometheus, OTel |
|
||||||
| **Runtime** | `RuntimeAdapter` | Native, Docker (sandboxed) | WASM (planned; unsupported kinds fail fast) |
|
| **Runtime** | `RuntimeAdapter` | Native, Docker (sandboxed) | WASM (planned; unsupported kinds fail fast) |
|
||||||
| **Security** | `SecurityPolicy` | Gateway pairing, sandbox, allowlists, rate limits, filesystem scoping, encrypted secrets | — |
|
| **Security** | `SecurityPolicy` | Gateway pairing, sandbox, allowlists, rate limits, filesystem scoping, encrypted secrets | — |
|
||||||
|
|
@ -302,8 +302,16 @@ provider = "none" # "none", "cloudflare", "tailscale", "ngrok", "c
|
||||||
encrypt = true # API keys encrypted with local key file
|
encrypt = true # API keys encrypted with local key file
|
||||||
|
|
||||||
[browser]
|
[browser]
|
||||||
enabled = false # opt-in browser_open tool
|
enabled = false # opt-in browser_open + browser tools
|
||||||
allowed_domains = ["docs.rs"] # required when browser is enabled
|
allowed_domains = ["docs.rs"] # required when browser is enabled
|
||||||
|
backend = "agent_browser" # "agent_browser" (default), "rust_native", "auto"
|
||||||
|
native_headless = true # applies when backend uses rust-native
|
||||||
|
native_webdriver_url = "http://127.0.0.1:9515" # WebDriver endpoint (chromedriver/selenium)
|
||||||
|
# native_chrome_path = "/usr/bin/chromium" # optional explicit browser binary for driver
|
||||||
|
|
||||||
|
# Rust-native backend build flag:
|
||||||
|
# cargo build --release --features browser-native
|
||||||
|
# Ensure a WebDriver server is running, e.g. chromedriver --port=9515
|
||||||
|
|
||||||
[composio]
|
[composio]
|
||||||
enabled = false # opt-in: 1000+ OAuth apps via composio.dev
|
enabled = false # opt-in: 1000+ OAuth apps via composio.dev
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
pub use schema::{
|
pub use schema::{
|
||||||
AuditConfig, AutonomyConfig, BrowserConfig, ChannelsConfig, ComposioConfig, Config,
|
AuditConfig, AutonomyConfig, BrowserConfig, ChannelsConfig, ComposioConfig, Config,
|
||||||
DelegateAgentConfig, DiscordConfig, DockerRuntimeConfig, GatewayConfig, HeartbeatConfig,
|
DelegateAgentConfig, DiscordConfig, DockerRuntimeConfig, GatewayConfig, HeartbeatConfig,
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@ impl Default for SecretsConfig {
|
||||||
|
|
||||||
// ── Browser (friendly-service browsing only) ───────────────────
|
// ── Browser (friendly-service browsing only) ───────────────────
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct BrowserConfig {
|
pub struct BrowserConfig {
|
||||||
/// Enable `browser_open` tool (opens URLs in Brave without scraping)
|
/// Enable `browser_open` tool (opens URLs in Brave without scraping)
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
@ -283,6 +283,40 @@ pub struct BrowserConfig {
|
||||||
/// Browser session name (for agent-browser automation)
|
/// Browser session name (for agent-browser automation)
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub session_name: Option<String>,
|
pub session_name: Option<String>,
|
||||||
|
/// Browser automation backend: "agent_browser" | "rust_native" | "auto"
|
||||||
|
#[serde(default = "default_browser_backend")]
|
||||||
|
pub backend: String,
|
||||||
|
/// Headless mode for rust-native backend
|
||||||
|
#[serde(default = "default_true")]
|
||||||
|
pub native_headless: bool,
|
||||||
|
/// WebDriver endpoint URL for rust-native backend (e.g. http://127.0.0.1:9515)
|
||||||
|
#[serde(default = "default_browser_webdriver_url")]
|
||||||
|
pub native_webdriver_url: String,
|
||||||
|
/// Optional Chrome/Chromium executable path for rust-native backend
|
||||||
|
#[serde(default)]
|
||||||
|
pub native_chrome_path: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_browser_backend() -> String {
|
||||||
|
"agent_browser".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_browser_webdriver_url() -> String {
|
||||||
|
"http://127.0.0.1:9515".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BrowserConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: false,
|
||||||
|
allowed_domains: Vec::new(),
|
||||||
|
session_name: None,
|
||||||
|
backend: default_browser_backend(),
|
||||||
|
native_headless: default_true(),
|
||||||
|
native_webdriver_url: default_browser_webdriver_url(),
|
||||||
|
native_chrome_path: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── HTTP request tool ───────────────────────────────────────────
|
// ── HTTP request tool ───────────────────────────────────────────
|
||||||
|
|
@ -1337,6 +1371,7 @@ fn sync_directory(_path: &Path) -> Result<()> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::{Mutex, OnceLock};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
// ── Defaults ─────────────────────────────────────────────
|
// ── Defaults ─────────────────────────────────────────────
|
||||||
|
|
@ -2095,6 +2130,10 @@ default_temperature = 0.7
|
||||||
let b = BrowserConfig::default();
|
let b = BrowserConfig::default();
|
||||||
assert!(!b.enabled);
|
assert!(!b.enabled);
|
||||||
assert!(b.allowed_domains.is_empty());
|
assert!(b.allowed_domains.is_empty());
|
||||||
|
assert_eq!(b.backend, "agent_browser");
|
||||||
|
assert!(b.native_headless);
|
||||||
|
assert_eq!(b.native_webdriver_url, "http://127.0.0.1:9515");
|
||||||
|
assert!(b.native_chrome_path.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -2103,12 +2142,23 @@ default_temperature = 0.7
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowed_domains: vec!["example.com".into(), "docs.example.com".into()],
|
allowed_domains: vec!["example.com".into(), "docs.example.com".into()],
|
||||||
session_name: None,
|
session_name: None,
|
||||||
|
backend: "auto".into(),
|
||||||
|
native_headless: false,
|
||||||
|
native_webdriver_url: "http://localhost:4444".into(),
|
||||||
|
native_chrome_path: Some("/usr/bin/chromium".into()),
|
||||||
};
|
};
|
||||||
let toml_str = toml::to_string(&b).unwrap();
|
let toml_str = toml::to_string(&b).unwrap();
|
||||||
let parsed: BrowserConfig = toml::from_str(&toml_str).unwrap();
|
let parsed: BrowserConfig = toml::from_str(&toml_str).unwrap();
|
||||||
assert!(parsed.enabled);
|
assert!(parsed.enabled);
|
||||||
assert_eq!(parsed.allowed_domains.len(), 2);
|
assert_eq!(parsed.allowed_domains.len(), 2);
|
||||||
assert_eq!(parsed.allowed_domains[0], "example.com");
|
assert_eq!(parsed.allowed_domains[0], "example.com");
|
||||||
|
assert_eq!(parsed.backend, "auto");
|
||||||
|
assert!(!parsed.native_headless);
|
||||||
|
assert_eq!(parsed.native_webdriver_url, "http://localhost:4444");
|
||||||
|
assert_eq!(
|
||||||
|
parsed.native_chrome_path.as_deref(),
|
||||||
|
Some("/usr/bin/chromium")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -2123,10 +2173,19 @@ default_temperature = 0.7
|
||||||
assert!(parsed.browser.allowed_domains.is_empty());
|
assert!(parsed.browser.allowed_domains.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn env_override_lock() -> std::sync::MutexGuard<'static, ()> {
|
||||||
|
static ENV_LOCK: OnceLock<Mutex<()>> = OnceLock::new();
|
||||||
|
ENV_LOCK
|
||||||
|
.get_or_init(|| Mutex::new(()))
|
||||||
|
.lock()
|
||||||
|
.expect("env override test lock poisoned")
|
||||||
|
}
|
||||||
|
|
||||||
// ── Environment variable overrides (Docker support) ─────────
|
// ── Environment variable overrides (Docker support) ─────────
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_api_key() {
|
fn env_override_api_key() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
assert!(config.api_key.is_none());
|
assert!(config.api_key.is_none());
|
||||||
|
|
||||||
|
|
@ -2139,6 +2198,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_api_key_fallback() {
|
fn env_override_api_key_fallback() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
std::env::remove_var("ZEROCLAW_API_KEY");
|
std::env::remove_var("ZEROCLAW_API_KEY");
|
||||||
|
|
@ -2151,6 +2211,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_provider() {
|
fn env_override_provider() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
std::env::set_var("ZEROCLAW_PROVIDER", "anthropic");
|
std::env::set_var("ZEROCLAW_PROVIDER", "anthropic");
|
||||||
|
|
@ -2162,6 +2223,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_provider_fallback() {
|
fn env_override_provider_fallback() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
std::env::remove_var("ZEROCLAW_PROVIDER");
|
std::env::remove_var("ZEROCLAW_PROVIDER");
|
||||||
|
|
@ -2174,6 +2236,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_model() {
|
fn env_override_model() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
std::env::set_var("ZEROCLAW_MODEL", "gpt-4o");
|
std::env::set_var("ZEROCLAW_MODEL", "gpt-4o");
|
||||||
|
|
@ -2185,6 +2248,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_workspace() {
|
fn env_override_workspace() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
std::env::set_var("ZEROCLAW_WORKSPACE", "/custom/workspace");
|
std::env::set_var("ZEROCLAW_WORKSPACE", "/custom/workspace");
|
||||||
|
|
@ -2196,6 +2260,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_empty_values_ignored() {
|
fn env_override_empty_values_ignored() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
let original_provider = config.default_provider.clone();
|
let original_provider = config.default_provider.clone();
|
||||||
|
|
||||||
|
|
@ -2208,6 +2273,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_gateway_port() {
|
fn env_override_gateway_port() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
assert_eq!(config.gateway.port, 3000);
|
assert_eq!(config.gateway.port, 3000);
|
||||||
|
|
||||||
|
|
@ -2220,6 +2286,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_port_fallback() {
|
fn env_override_port_fallback() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
std::env::remove_var("ZEROCLAW_GATEWAY_PORT");
|
std::env::remove_var("ZEROCLAW_GATEWAY_PORT");
|
||||||
|
|
@ -2232,6 +2299,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_gateway_host() {
|
fn env_override_gateway_host() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
assert_eq!(config.gateway.host, "127.0.0.1");
|
assert_eq!(config.gateway.host, "127.0.0.1");
|
||||||
|
|
||||||
|
|
@ -2244,6 +2312,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_host_fallback() {
|
fn env_override_host_fallback() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
std::env::remove_var("ZEROCLAW_GATEWAY_HOST");
|
std::env::remove_var("ZEROCLAW_GATEWAY_HOST");
|
||||||
|
|
@ -2256,6 +2325,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_temperature() {
|
fn env_override_temperature() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
|
||||||
std::env::set_var("ZEROCLAW_TEMPERATURE", "0.5");
|
std::env::set_var("ZEROCLAW_TEMPERATURE", "0.5");
|
||||||
|
|
@ -2267,6 +2337,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_temperature_out_of_range_ignored() {
|
fn env_override_temperature_out_of_range_ignored() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
// Clean up any leftover env vars from other tests
|
// Clean up any leftover env vars from other tests
|
||||||
std::env::remove_var("ZEROCLAW_TEMPERATURE");
|
std::env::remove_var("ZEROCLAW_TEMPERATURE");
|
||||||
|
|
||||||
|
|
@ -2286,6 +2357,7 @@ default_temperature = 0.7
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_override_invalid_port_ignored() {
|
fn env_override_invalid_port_ignored() {
|
||||||
|
let _guard = env_override_lock();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
let original_port = config.gateway.port;
|
let original_port = config.gateway.port;
|
||||||
|
|
||||||
|
|
@ -2467,7 +2539,7 @@ temperature = 0.3
|
||||||
max_depth: 3,
|
max_depth: 3,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let mut config = Config {
|
let config = Config {
|
||||||
config_path: config_path.clone(),
|
config_path: config_path.clone(),
|
||||||
workspace_dir: zeroclaw_dir.join("workspace"),
|
workspace_dir: zeroclaw_dir.join("workspace"),
|
||||||
secrets: SecretsConfig { encrypt: true },
|
secrets: SecretsConfig { encrypt: true },
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -55,6 +55,7 @@ pub fn default_tools_with_runtime(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create full tool registry including memory tools and optional Composio
|
/// Create full tool registry including memory tools and optional Composio
|
||||||
|
#[allow(clippy::implicit_hasher)]
|
||||||
pub fn all_tools(
|
pub fn all_tools(
|
||||||
security: &Arc<SecurityPolicy>,
|
security: &Arc<SecurityPolicy>,
|
||||||
memory: Arc<dyn Memory>,
|
memory: Arc<dyn Memory>,
|
||||||
|
|
@ -77,6 +78,7 @@ pub fn all_tools(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create full tool registry including memory tools and optional Composio.
|
/// Create full tool registry including memory tools and optional Composio.
|
||||||
|
#[allow(clippy::implicit_hasher)]
|
||||||
pub fn all_tools_with_runtime(
|
pub fn all_tools_with_runtime(
|
||||||
security: &Arc<SecurityPolicy>,
|
security: &Arc<SecurityPolicy>,
|
||||||
runtime: Arc<dyn RuntimeAdapter>,
|
runtime: Arc<dyn RuntimeAdapter>,
|
||||||
|
|
@ -102,11 +104,15 @@ pub fn all_tools_with_runtime(
|
||||||
security.clone(),
|
security.clone(),
|
||||||
browser_config.allowed_domains.clone(),
|
browser_config.allowed_domains.clone(),
|
||||||
)));
|
)));
|
||||||
// Add full browser automation tool (agent-browser)
|
// Add full browser automation tool (pluggable backend)
|
||||||
tools.push(Box::new(BrowserTool::new(
|
tools.push(Box::new(BrowserTool::new_with_backend(
|
||||||
security.clone(),
|
security.clone(),
|
||||||
browser_config.allowed_domains.clone(),
|
browser_config.allowed_domains.clone(),
|
||||||
browser_config.session_name.clone(),
|
browser_config.session_name.clone(),
|
||||||
|
browser_config.backend.clone(),
|
||||||
|
browser_config.native_headless,
|
||||||
|
browser_config.native_webdriver_url.clone(),
|
||||||
|
browser_config.native_chrome_path.clone(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,6 +174,7 @@ mod tests {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowed_domains: vec!["example.com".into()],
|
allowed_domains: vec!["example.com".into()],
|
||||||
session_name: None,
|
session_name: None,
|
||||||
|
..BrowserConfig::default()
|
||||||
};
|
};
|
||||||
let http = crate::config::HttpRequestConfig::default();
|
let http = crate::config::HttpRequestConfig::default();
|
||||||
|
|
||||||
|
|
@ -191,6 +198,7 @@ mod tests {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowed_domains: vec!["example.com".into()],
|
allowed_domains: vec!["example.com".into()],
|
||||||
session_name: None,
|
session_name: None,
|
||||||
|
..BrowserConfig::default()
|
||||||
};
|
};
|
||||||
let http = crate::config::HttpRequestConfig::default();
|
let http = crate::config::HttpRequestConfig::default();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue