diff --git a/Cargo.lock b/Cargo.lock
index afb474a2dc..90b347ea4f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -103,7 +103,7 @@ version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
- "windows-sys 0.60.2",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -114,7 +114,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
- "windows-sys 0.60.2",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -271,7 +271,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -306,7 +306,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -360,6 +360,15 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "atomic"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340"
+dependencies = [
+ "bytemuck",
+]
+
[[package]]
name = "atomic-destructor"
version = "0.3.0"
@@ -505,7 +514,7 @@ checksum = "7aa268c23bfbbd2c4363b9cd302a4f504fb2a9dfe7e3451d66f35dd392e20aca"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -554,15 +563,30 @@ dependencies = [
"unicode-normalization",
]
+[[package]]
+name = "bit-set"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
+dependencies = [
+ "bit-vec 0.6.3",
+]
+
[[package]]
name = "bit-set"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [
- "bit-vec",
+ "bit-vec 0.8.0",
]
+[[package]]
+name = "bit-vec"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
[[package]]
name = "bit-vec"
version = "0.8.0"
@@ -588,9 +612,15 @@ dependencies = [
[[package]]
name = "bitflags"
-version = "2.11.1"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
dependencies = [
"serde_core",
]
@@ -695,7 +725,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1173,6 +1203,12 @@ dependencies = [
"url",
]
+[[package]]
+name = "by_address"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
+
[[package]]
name = "bytemuck"
version = "1.25.0"
@@ -1227,6 +1263,12 @@ dependencies = [
"shlex",
]
+[[package]]
+name = "cesu8"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
+
[[package]]
name = "cfb"
version = "0.7.3"
@@ -1347,7 +1389,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1398,7 +1440,7 @@ version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -1428,6 +1470,20 @@ dependencies = [
"static_assertions",
]
+[[package]]
+name = "compact_str"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab"
+dependencies = [
+ "castaway",
+ "cfg-if 1.0.4",
+ "itoa",
+ "rustversion",
+ "ryu",
+ "static_assertions",
+]
+
[[package]]
name = "compression-codecs"
version = "0.4.38"
@@ -1690,7 +1746,7 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"crossterm_winapi",
"mio",
"parking_lot",
@@ -1700,6 +1756,24 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "crossterm"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
+dependencies = [
+ "bitflags 2.13.0",
+ "crossterm_winapi",
+ "derive_more",
+ "document-features",
+ "mio",
+ "parking_lot",
+ "rustix 1.1.4",
+ "signal-hook",
+ "signal-hook-mio",
+ "winapi",
+]
+
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
@@ -1764,6 +1838,16 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "csscolorparser"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf"
+dependencies = [
+ "lab",
+ "phf",
+]
+
[[package]]
name = "csv"
version = "1.4.0"
@@ -1836,12 +1920,12 @@ dependencies = [
[[package]]
name = "curve25519-dalek"
-version = "5.0.0-pre.6"
+version = "5.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "335f1947f241137a14106b6f5acc5918a5ede29c9d71d3f2cb1678d5075d9fc3"
+checksum = "4f359e08ca85e7bd759e1fd933ff2bccd81864c60a8fba0e259c7f822b0924bf"
dependencies = [
"cfg-if 1.0.4",
- "cpufeatures 0.2.17",
+ "cpufeatures 0.3.0",
"curve25519-dalek-derive",
"digest 0.11.3",
"fiat-crypto 0.3.0",
@@ -1860,7 +1944,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1894,7 +1978,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1907,7 +1991,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1918,7 +2002,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core 0.20.11",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1929,7 +2013,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
dependencies = [
"darling_core 0.23.0",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1969,7 +2053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090"
dependencies = [
"data-encoding",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2032,6 +2116,12 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "deltae"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4"
+
[[package]]
name = "der"
version = "0.8.0"
@@ -2061,7 +2151,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2082,7 +2172,7 @@ dependencies = [
"darling 0.20.11",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2092,7 +2182,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
dependencies = [
"derive_builder_core",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2114,7 +2204,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
- "syn",
+ "syn 2.0.117",
"unicode-xid",
]
@@ -2174,7 +2264,7 @@ dependencies = [
"libc",
"option-ext",
"redox_users",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -2183,7 +2273,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"block2",
"libc",
"objc2",
@@ -2197,7 +2287,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2220,6 +2310,15 @@ dependencies = [
"const-random",
]
+[[package]]
+name = "document-features"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
+dependencies = [
+ "litrs",
+]
+
[[package]]
name = "dotenvy"
version = "0.15.7"
@@ -2266,11 +2365,11 @@ dependencies = [
[[package]]
name = "ed25519-dalek"
-version = "3.0.0-pre.7"
+version = "3.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20449acd54b660981ae5caa2bcb56d1fe7f25f2e37a38ec507400fab034d4bb6"
+checksum = "b011170fe4f04665565b4110afef66774fe9ffff278f3eb5b81cc73d26e27d60"
dependencies = [
- "curve25519-dalek 5.0.0-pre.6",
+ "curve25519-dalek 5.0.0-rc.0",
"ed25519",
"rand_core 0.10.1",
"serde",
@@ -2324,7 +2423,7 @@ checksum = "3ed8956bd5c1f0415200516e78ff07ec9e16415ade83c056c230d7b7ea0d55b7"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2345,7 +2444,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2361,7 +2460,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -2374,6 +2473,15 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "euclid"
+version = "0.22.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06"
+dependencies = [
+ "num-traits",
+]
+
[[package]]
name = "evalexpr"
version = "11.3.1"
@@ -2412,6 +2520,22 @@ dependencies = [
"smallvec",
]
+[[package]]
+name = "fancy-regex"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
+dependencies = [
+ "bit-set 0.5.3",
+ "regex",
+]
+
+[[package]]
+name = "fast-srgb8"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1"
+
[[package]]
name = "fastrand"
version = "2.4.1"
@@ -2439,6 +2563,17 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24"
+[[package]]
+name = "filedescriptor"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d"
+dependencies = [
+ "libc",
+ "thiserror 1.0.69",
+ "winapi",
+]
+
[[package]]
name = "filetime"
version = "0.2.29"
@@ -2455,6 +2590,18 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+[[package]]
+name = "finl_unicode"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9844ddc3a6e533d62bba727eb6c28b5d360921d5175e9ff0f1e621a5c590a4d5"
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+
[[package]]
name = "fixedbitset"
version = "0.5.7"
@@ -2634,7 +2781,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2686,8 +2833,8 @@ dependencies = [
"libc",
"log",
"rustversion",
- "windows-link 0.2.1",
- "windows-result 0.4.1",
+ "windows-link 0.1.3",
+ "windows-result 0.3.4",
]
[[package]]
@@ -2804,7 +2951,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3002,7 +3149,7 @@ dependencies = [
"http",
"idna",
"ipnet",
- "jni",
+ "jni 0.22.4",
"rand 0.10.1",
"rustls",
"thiserror 2.0.18",
@@ -3022,7 +3169,7 @@ dependencies = [
"data-encoding",
"idna",
"ipnet",
- "jni",
+ "jni 0.22.4",
"once_cell",
"prefix-trie",
"rand 0.10.1",
@@ -3045,7 +3192,7 @@ dependencies = [
"hickory-proto",
"ipconfig",
"ipnet",
- "jni",
+ "jni 0.22.4",
"moka",
"ndk-context",
"once_cell",
@@ -3277,7 +3424,7 @@ dependencies = [
"js-sys",
"log",
"wasm-bindgen",
- "windows-core 0.62.2",
+ "windows-core 0.61.2",
]
[[package]]
@@ -3502,6 +3649,15 @@ dependencies = [
"serde_core",
]
+[[package]]
+name = "indoc"
+version = "2.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
+dependencies = [
+ "rustversion",
+]
+
[[package]]
name = "infer"
version = "0.19.0"
@@ -3521,6 +3677,19 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "instability"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971"
+dependencies = [
+ "darling 0.23.0",
+ "indoc",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "instant"
version = "0.1.13"
@@ -3557,9 +3726,9 @@ dependencies = [
[[package]]
name = "iroh"
-version = "1.0.0-rc.0"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b98e206e3d3f2642f5c08c413755fc0ac19b54ae1a656af88be03454ce3ed2e6"
+checksum = "5fca9b4b462c343ff88fc0af4096c186f939b602a0bc08723536ef2c31c93971"
dependencies = [
"backon",
"blake3",
@@ -3594,7 +3763,6 @@ dependencies = [
"rustc-hash",
"rustls",
"rustls-pki-types",
- "rustls-webpki",
"serde",
"smallvec",
"strum",
@@ -3605,36 +3773,32 @@ dependencies = [
"tracing",
"url",
"wasm-bindgen-futures",
- "webpki-roots 1.0.7",
]
[[package]]
name = "iroh-base"
-version = "1.0.0-rc.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af93d67701c00c504982154569192ad384738c0450ba1196930314b955100552"
+checksum = "830a582cd54410dc1aa71d4786a82c3297d7b0165accd8b6dbbb3b240b48140d"
dependencies = [
- "curve25519-dalek 5.0.0-pre.6",
+ "curve25519-dalek 5.0.0-rc.0",
"data-encoding",
"data-encoding-macro",
"derive_more",
- "digest 0.11.3",
"ed25519-dalek",
"getrandom 0.4.2",
"n0-error",
"rand 0.10.1",
"serde",
- "sha2 0.11.0",
"url",
"zeroize",
- "zeroize_derive",
]
[[package]]
name = "iroh-dns"
-version = "1.0.0-rc.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de4112c91eb64094d77df9d3112606dcf7ff216421afccd2dc762fda5a7b2879"
+checksum = "516e4eedc38e33ab69a6bd325520332dc3d67b25454e2d590ebb84a25240dd9a"
dependencies = [
"arc-swap",
"cfg_aliases",
@@ -3644,8 +3808,8 @@ dependencies = [
"n0-error",
"n0-future",
"ndk-context",
+ "portable-atomic",
"rand 0.10.1",
- "reqwest 0.13.3",
"rustls",
"simple-dns",
"strum",
@@ -3656,9 +3820,9 @@ dependencies = [
[[package]]
name = "iroh-metrics"
-version = "1.0.0-rc.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d102597d0ee523f17fdb672c532395e634dbe945429284c811430d63bacc0d8a"
+checksum = "291065721ad7c477b972e581bbc528df031dc8eb5e39fe1ff3300ae5dfb157ef"
dependencies = [
"iroh-metrics-derive",
"itoa",
@@ -3671,21 +3835,21 @@ dependencies = [
[[package]]
name = "iroh-metrics-derive"
-version = "1.0.0-rc.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91c8e0c97f1dc787107f388433c349397c565572fe6406d600ff7bb7b7fe3b30"
+checksum = "1ae5f0c4405d1fbc9fb16ff422ca40620e93dc36c30ecaba0c2aee3992b7bd48"
dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
name = "iroh-relay"
-version = "1.0.0-rc.0"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54f490405e42dd2ecf16be18a3587d2665401e94a498094f12322eaa6d5ebb2b"
+checksum = "8149bb6a57126225a07d6928846d82dcedfd24ea0f863ef7b2eb475e1d726354"
dependencies = [
"blake3",
"bytes",
@@ -3748,6 +3912,22 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+[[package]]
+name = "jni"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
+dependencies = [
+ "cesu8",
+ "cfg-if 1.0.4",
+ "combine",
+ "jni-sys 0.3.1",
+ "log",
+ "thiserror 1.0.69",
+ "walkdir",
+ "windows-sys 0.45.0",
+]
+
[[package]]
name = "jni"
version = "0.22.4"
@@ -3757,7 +3937,7 @@ dependencies = [
"cfg-if 1.0.4",
"combine",
"jni-macros",
- "jni-sys",
+ "jni-sys 0.4.1",
"log",
"simd_cesu8",
"thiserror 2.0.18",
@@ -3775,7 +3955,16 @@ dependencies = [
"quote",
"rustc_version",
"simd_cesu8",
- "syn",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "jni-sys"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
+dependencies = [
+ "jni-sys 0.4.1",
]
[[package]]
@@ -3794,7 +3983,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
dependencies = [
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3829,6 +4018,17 @@ dependencies = [
"ucd-trie",
]
+[[package]]
+name = "kasuari"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bde5057d6143cc94e861d90f591b9303d6716c6b9602309150bd068853c10899"
+dependencies = [
+ "hashbrown 0.16.1",
+ "portable-atomic",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "keyring"
version = "3.6.3"
@@ -3863,6 +4063,12 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e037a2e1d8d5fdbd49b16a4ea09d5d6401c1f29eca5ff29d03d3824dba16256a"
+[[package]]
+name = "lab"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f"
+
[[package]]
name = "lazy_static"
version = "1.5.0"
@@ -3912,6 +4118,12 @@ dependencies = [
"windows-link 0.2.1",
]
+[[package]]
+name = "libm"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
+
[[package]]
name = "libredox"
version = "0.1.17"
@@ -3931,6 +4143,15 @@ dependencies = [
"vcpkg",
]
+[[package]]
+name = "line-clipping"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8"
+dependencies = [
+ "bitflags 2.13.0",
+]
+
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
@@ -3949,6 +4170,12 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
+[[package]]
+name = "litrs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
+
[[package]]
name = "lock_api"
version = "0.4.14"
@@ -4013,6 +4240,16 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3d25b0e0b648a86960ac23b7ad4abb9717601dec6f66c165f5b037f3f03065f"
+[[package]]
+name = "mac_address"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0aeb26bf5e836cc1c341c8106051b573f1766dfa05aa87f0b98be5e51b02303"
+dependencies = [
+ "nix 0.29.0",
+ "winapi",
+]
+
[[package]]
name = "matchers"
version = "0.2.0"
@@ -4036,7 +4273,7 @@ checksum = "746873a384ad60adc5db74471dfaba74bd278afbdcfd81db93fafcdfc8b5ca0c"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4076,6 +4313,12 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+[[package]]
+name = "memmem"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15"
+
[[package]]
name = "memoffset"
version = "0.9.1"
@@ -4087,8 +4330,8 @@ dependencies = [
[[package]]
name = "mesh-llm-api-client"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"hex",
"mesh-llm-client",
@@ -4097,8 +4340,8 @@ dependencies = [
[[package]]
name = "mesh-llm-api-server"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"mesh-llm-api-client",
@@ -4106,10 +4349,15 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "mesh-llm-build-info"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
+
[[package]]
name = "mesh-llm-client"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -4140,8 +4388,8 @@ dependencies = [
[[package]]
name = "mesh-llm-config"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"dirs",
@@ -4151,12 +4399,13 @@ dependencies = [
"skippy-protocol",
"toml 0.9.12+spec-1.1.0",
"toml_edit",
+ "url",
]
[[package]]
name = "mesh-llm-embedded-runtime"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"mesh-llm-host-runtime",
@@ -4165,18 +4414,20 @@ dependencies = [
[[package]]
name = "mesh-llm-events"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"clap",
+ "crossterm 0.28.1",
+ "ratatui",
"serde_json",
]
[[package]]
name = "mesh-llm-gpu-bench"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"cc",
@@ -4188,8 +4439,8 @@ dependencies = [
[[package]]
name = "mesh-llm-guardrails"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"serde",
"serde_json",
@@ -4197,16 +4448,16 @@ dependencies = [
[[package]]
name = "mesh-llm-hardware-profile"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"mesh-llm-native-runtime",
]
[[package]]
name = "mesh-llm-host-runtime"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"argon2",
@@ -4217,7 +4468,7 @@ dependencies = [
"chacha20poly1305",
"chrono",
"clap",
- "crossterm",
+ "crossterm 0.28.1",
"crypto_box",
"dirs",
"ed25519-dalek",
@@ -4228,12 +4479,14 @@ dependencies = [
"http",
"http-body-util",
"httparse",
+ "if-addrs",
"iroh",
"json5",
"keyring",
"libc",
"mdns-sd",
"mesh-llm-api-server",
+ "mesh-llm-build-info",
"mesh-llm-client",
"mesh-llm-config",
"mesh-llm-events",
@@ -4278,6 +4531,7 @@ dependencies = [
"skippy-runtime",
"skippy-server",
"skippy-topology",
+ "socket2",
"tabwriter",
"tar",
"tempfile",
@@ -4295,8 +4549,8 @@ dependencies = [
[[package]]
name = "mesh-llm-identity"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"argon2",
"base64",
@@ -4317,8 +4571,8 @@ dependencies = [
[[package]]
name = "mesh-llm-native-runtime"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"serde",
@@ -4328,8 +4582,8 @@ dependencies = [
[[package]]
name = "mesh-llm-node"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"mesh-llm-types",
@@ -4342,8 +4596,8 @@ dependencies = [
[[package]]
name = "mesh-llm-plugin"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -4359,8 +4613,8 @@ dependencies = [
[[package]]
name = "mesh-llm-plugin-manager"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"dirs",
@@ -4377,8 +4631,8 @@ dependencies = [
[[package]]
name = "mesh-llm-protocol"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"hex",
@@ -4390,22 +4644,23 @@ dependencies = [
[[package]]
name = "mesh-llm-routing"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"iroh",
]
[[package]]
name = "mesh-llm-runtime-install"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"dirs",
"flate2",
"futures-util",
"hex",
+ "mesh-llm-build-info",
"mesh-llm-hardware-profile",
"mesh-llm-native-runtime",
"reqwest 0.12.28",
@@ -4420,8 +4675,8 @@ dependencies = [
[[package]]
name = "mesh-llm-sdk"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"mesh-llm-api-client",
@@ -4435,8 +4690,8 @@ dependencies = [
[[package]]
name = "mesh-llm-skills"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"dirs",
@@ -4446,8 +4701,8 @@ dependencies = [
[[package]]
name = "mesh-llm-system"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"chrono",
@@ -4455,6 +4710,7 @@ dependencies = [
"dirs",
"hex",
"libc",
+ "mesh-llm-build-info",
"mesh-llm-gpu-bench",
"reqwest 0.12.28",
"semver",
@@ -4468,8 +4724,8 @@ dependencies = [
[[package]]
name = "mesh-llm-types"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"hex",
"serde",
@@ -4479,13 +4735,13 @@ dependencies = [
[[package]]
name = "mesh-llm-ui"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
[[package]]
name = "mesh-mixture-of-agents"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"async-trait",
"mesh-llm-guardrails",
@@ -4571,6 +4827,12 @@ dependencies = [
"rxml",
]
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
[[package]]
name = "miniz_oxide"
version = "0.8.9"
@@ -4595,8 +4857,8 @@ dependencies = [
[[package]]
name = "model-artifact"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -4606,8 +4868,8 @@ dependencies = [
[[package]]
name = "model-hf"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -4624,8 +4886,8 @@ dependencies = [
[[package]]
name = "model-package"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"bytes",
@@ -4644,16 +4906,16 @@ dependencies = [
[[package]]
name = "model-ref"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"serde",
]
[[package]]
name = "model-resolver"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"model-artifact",
@@ -4717,9 +4979,9 @@ checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
[[package]]
name = "n0-error"
-version = "1.0.0-rc.0"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "223e946a84aa91644507a6b7865cfebbb9a231ace499041c747ab0fd30408212"
+checksum = "c37e81176a83a77d2514528b91bdafc70ef88aab428f0e1b91aebb8d99888895"
dependencies = [
"n0-error-macros",
"spez",
@@ -4727,13 +4989,13 @@ dependencies = [
[[package]]
name = "n0-error-macros"
-version = "1.0.0-rc.0"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "565305a21e6b3bf26640ad98f05a0fda12d3ab4315394566b52a7bddb8b34828"
+checksum = "e2acd8b070213b0299282f884b4beba4e7b52d624fdcd504a3ad3665390c11e1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4759,9 +5021,9 @@ dependencies = [
[[package]]
name = "n0-watcher"
-version = "1.0.0-rc.0"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "928d8039a66cce5efcfd35e88b32d3defc8eba630b3ac451522997f563956a52"
+checksum = "bbc618745ad0b7414b149d0517ad8b5573b2fb4d4e2717add3d2446ce1fdd826"
dependencies = [
"derive_more",
"n0-error",
@@ -4799,19 +5061,22 @@ checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d"
[[package]]
name = "netdev"
-version = "0.43.0"
+version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57bacaf873ee4eab5646f99b381b271ec75e716902a67cf962c0f328c5eb5bfb"
+checksum = "569dfbdd2efd771b24ec9bb57f956e04d4fbfc72f62b2f11961723f9b3f4b020"
dependencies = [
"block2",
"dispatch2",
"dlopen2",
"ipnet",
+ "jni 0.21.1",
"libc",
"mac-addr",
+ "ndk-context",
"netlink-packet-core",
- "netlink-packet-route 0.29.0",
+ "netlink-packet-route",
"netlink-sys",
+ "objc2",
"objc2-core-foundation",
"objc2-core-wlan",
"objc2-foundation",
@@ -4832,23 +5097,11 @@ dependencies = [
[[package]]
name = "netlink-packet-route"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df9854ea6ad14e3f4698a7f03b65bce0833dd2d81d594a0e4a984170537146b6"
-dependencies = [
- "bitflags",
- "libc",
- "log",
- "netlink-packet-core",
-]
-
-[[package]]
-name = "netlink-packet-route"
-version = "0.30.0"
+version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be8919612f6028ab4eacbbfe1234a9a43e3722c6e0915e7ff519066991905092"
+checksum = "e2288fcb784eb3defd5fb16f4c4160d5f477de192eac730f43e1d11c24d9a007"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"libc",
"log",
"netlink-packet-core",
@@ -4883,14 +5136,15 @@ dependencies = [
[[package]]
name = "netwatch"
-version = "0.17.0"
+version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5bfbba77b994ce69f1d40fc66fd8abbd23df62ce4aea61fbb34d638106a2549"
+checksum = "4d9cbe01741347ef750d743d6690603f5eed8341e679fb51c8e629337aa11976"
dependencies = [
"atomic-waker",
"bytes",
"cfg_aliases",
"derive_more",
+ "ipnet",
"js-sys",
"libc",
"n0-error",
@@ -4898,7 +5152,7 @@ dependencies = [
"n0-watcher",
"netdev",
"netlink-packet-core",
- "netlink-packet-route 0.30.0",
+ "netlink-packet-route",
"netlink-proto",
"netlink-sys",
"noq-udp",
@@ -4923,7 +5177,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"cfg-if 1.0.4",
"cfg_aliases",
"libc",
@@ -4936,17 +5190,27 @@ version = "0.31.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"cfg-if 1.0.4",
"cfg_aliases",
"libc",
]
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
[[package]]
name = "noq"
-version = "1.0.0-rc.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22739e0831e40f5ab7d6ac5317ed80bfe5fb3f44be57d23fa2eea8bff83fb303"
+checksum = "4bf95190af1bd4a00a10e8255ca0c8ddd9e9a9f5e79151d7a7eb6d56aff5dc89"
dependencies = [
"bytes",
"cfg_aliases",
@@ -4966,9 +5230,9 @@ dependencies = [
[[package]]
name = "noq-proto"
-version = "1.0.0-rc.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cee32450cf726b223ac4154003c93cb52fbde159ab1240990e88945bf3ae35e"
+checksum = "aa6c890013591e709a3e45dd53501351b7e27e7ff3c7e9fc3dce43e300e7e9d3"
dependencies = [
"aes-gcm",
"bytes",
@@ -4993,9 +5257,9 @@ dependencies = [
[[package]]
name = "noq-udp"
-version = "1.0.0-rc.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78633d1fe1bde91d12bcabb230ac9edb890857414c6d44f3212e0d309525b5ff"
+checksum = "3137a52df66c20090a889828d1c655f21f52294cba64e5c4fbb04fc83eee7c8e"
dependencies = [
"cfg_aliases",
"libc",
@@ -5096,7 +5360,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -5139,10 +5403,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
[[package]]
-name = "num-integer"
-version = "0.1.46"
+name = "num-derive"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
+checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
@@ -5208,7 +5483,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5235,7 +5510,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"block2",
"dispatch2",
"libc",
@@ -5248,7 +5523,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71e34919aba0d701380d911702455038a8a3587467fe0141d6a71501e7ffe48"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"objc2",
"objc2-core-foundation",
"objc2-foundation",
@@ -5268,7 +5543,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"block2",
"libc",
"objc2",
@@ -5291,7 +5566,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"objc2",
"objc2-core-foundation",
]
@@ -5312,7 +5587,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7216bd11cbda54ccabcab84d523dc93b858ec75ecfb3a7d89513fa22464da396"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"dispatch2",
"libc",
"objc2",
@@ -5350,8 +5625,8 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "openai-frontend"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"async-trait",
"axum",
@@ -5371,7 +5646,7 @@ version = "0.10.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"cfg-if 1.0.4",
"foreign-types",
"libc",
@@ -5387,7 +5662,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5561,6 +5836,15 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
+[[package]]
+name = "ordered-float"
+version = "4.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
+dependencies = [
+ "num-traits",
+]
+
[[package]]
name = "ordered-multimap"
version = "0.7.3"
@@ -5590,6 +5874,30 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "palette"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6"
+dependencies = [
+ "approx",
+ "fast-srgb8",
+ "libm",
+ "palette_derive",
+]
+
+[[package]]
+name = "palette_derive"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30"
+dependencies = [
+ "by_address",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "papaya"
version = "0.2.4"
@@ -5683,13 +5991,55 @@ version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
+[[package]]
+name = "pest"
+version = "2.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47627dd7305c6a2d6c8c6bcd24c5a4c17dbbf425f4f9c5313e724b38fc9782e9"
+dependencies = [
+ "memchr",
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b4254325ecad416ab689e27ba51da03ba01a9632bc6e108f5fe7c3c4ad29d58"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c4c0e91ead7a8f7acecbca6f003fc2e8282b1dbe2dd9c9d2f16aba42995e0a7"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9744bc48116fee06334924bb5f2bad41eed5e89bd26e29b0b799f9a3f82c210"
+dependencies = [
+ "pest",
+]
+
[[package]]
name = "petgraph"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
dependencies = [
- "fixedbitset",
+ "fixedbitset 0.5.7",
"hashbrown 0.15.5",
"indexmap",
]
@@ -5714,6 +6064,16 @@ dependencies = [
"phf_shared",
]
+[[package]]
+name = "phf_codegen"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+]
+
[[package]]
name = "phf_generator"
version = "0.11.3"
@@ -5734,7 +6094,7 @@ dependencies = [
"phf_shared",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5763,7 +6123,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5818,7 +6178,7 @@ version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"crc32fast",
"fdeflate",
"flate2",
@@ -5873,9 +6233,9 @@ dependencies = [
[[package]]
name = "portmapper"
-version = "0.17.0"
+version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aec2a8809e3f7dba624776bb223da9fed49c413c60b3bef21aadcb67a5e35944"
+checksum = "eb3713e4977408279158444a18c1a01ac9bf2e7eaf1fbfd1a19ac9cd18d90721"
dependencies = [
"base64",
"bytes",
@@ -5921,7 +6281,7 @@ checksum = "e0232bd009a197ceec9cc881ba46f727fcd8060a2d8d6a9dde7a69030a6fe2bb"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5966,7 +6326,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -6007,9 +6367,9 @@ version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
dependencies = [
- "bit-set",
- "bit-vec",
- "bitflags",
+ "bit-set 0.8.0",
+ "bit-vec 0.8.0",
+ "bitflags 2.13.0",
"num-traits",
"rand 0.9.4",
"rand_chacha 0.9.0",
@@ -6045,7 +6405,7 @@ dependencies = [
"prost",
"prost-types",
"regex",
- "syn",
+ "syn 2.0.117",
"tempfile",
]
@@ -6059,7 +6419,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -6376,13 +6736,114 @@ dependencies = [
"rustversion",
]
+[[package]]
+name = "ratatui"
+version = "0.30.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3274ba0a2c5e1bcad2a2005d20f4dc59dad26b2eb0940fb094500dba4099d57d"
+dependencies = [
+ "instability",
+ "ratatui-core",
+ "ratatui-crossterm",
+ "ratatui-macros",
+ "ratatui-termina",
+ "ratatui-termwiz",
+ "ratatui-widgets",
+ "serde",
+]
+
+[[package]]
+name = "ratatui-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbb175c433c8e28a809d1f5773a2ae96e68c0ce40db865cbab1020bf33ae479c"
+dependencies = [
+ "bitflags 2.13.0",
+ "compact_str 0.9.1",
+ "critical-section",
+ "hashbrown 0.17.1",
+ "itertools",
+ "kasuari",
+ "lru 0.18.0",
+ "palette",
+ "serde",
+ "strum",
+ "thiserror 2.0.18",
+ "unicode-segmentation",
+ "unicode-truncate",
+ "unicode-width",
+]
+
+[[package]]
+name = "ratatui-crossterm"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567584a3b0e6a8203c23de40b4861497266725eb5363dbfd18a1edd603cca9f0"
+dependencies = [
+ "cfg-if 1.0.4",
+ "crossterm 0.29.0",
+ "instability",
+ "ratatui-core",
+]
+
+[[package]]
+name = "ratatui-macros"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed7dc68daa7498a43e4d68e0eb078427e10c38fbcfbb1e42d955f1fa2140d814"
+dependencies = [
+ "ratatui-core",
+ "ratatui-widgets",
+]
+
+[[package]]
+name = "ratatui-termina"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0bf912d9e66f057a759d92e386a280ea886b352ab757d6ac4d653c7ed2c43c2"
+dependencies = [
+ "instability",
+ "ratatui-core",
+ "termina",
+]
+
+[[package]]
+name = "ratatui-termwiz"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faf03e0380b7744054d6cb74224fe3adf062a029754933f575ca1e3b4c2ce977"
+dependencies = [
+ "ratatui-core",
+ "termwiz",
+]
+
+[[package]]
+name = "ratatui-widgets"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66e3d19bcc9130ca376277d93b60767ff121ace3be06f5f95f81dd68956407d1"
+dependencies = [
+ "bitflags 2.13.0",
+ "hashbrown 0.17.1",
+ "indoc",
+ "instability",
+ "itertools",
+ "line-clipping",
+ "ratatui-core",
+ "serde",
+ "strum",
+ "time",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
[[package]]
name = "raw-cpuid"
version = "11.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
]
[[package]]
@@ -6431,7 +6892,7 @@ version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
]
[[package]]
@@ -6462,7 +6923,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -6670,7 +7131,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_json",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -6749,7 +7210,7 @@ version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"errno",
"libc",
"linux-raw-sys 0.4.15",
@@ -6762,11 +7223,11 @@ version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"errno",
"libc",
"linux-raw-sys 0.12.1",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -6815,7 +7276,7 @@ checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
dependencies = [
"core-foundation 0.10.1",
"core-foundation-sys",
- "jni",
+ "jni 0.22.4",
"log",
"once_cell",
"rustls",
@@ -6825,7 +7286,7 @@ dependencies = [
"security-framework 3.7.0",
"security-framework-sys",
"webpki-root-certs",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -6880,7 +7341,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e80413b9a35e9d33217b3dcac04cf95f6559d15944b93887a08be5496c4a4"
dependencies = [
- "compact_str",
+ "compact_str 0.7.1",
]
[[package]]
@@ -6945,7 +7406,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7037,7 +7498,7 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
@@ -7050,7 +7511,7 @@ version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"core-foundation 0.10.1",
"core-foundation-sys",
"libc",
@@ -7074,7 +7535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b55fb86dfd3a2f5f76ea78310a88f96c4ea21a3031f8d212443d56123fd0521"
dependencies = [
"libc",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -7126,7 +7587,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7137,7 +7598,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7172,7 +7633,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7379,7 +7840,7 @@ version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a75cbde1bf934313596a004973e462f9a82caa814dcf1a5f507bdf51597eeb4"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
]
[[package]]
@@ -7396,8 +7857,8 @@ checksum = "0c6f73aeb92d671e0cc4dca167e59b2deb6387c375391bc99ee743f326994a2b"
[[package]]
name = "skippy-cache"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"blake3",
@@ -7406,29 +7867,29 @@ dependencies = [
[[package]]
name = "skippy-coordinator"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"thiserror 2.0.18",
]
[[package]]
name = "skippy-ffi"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"libloading",
]
[[package]]
name = "skippy-metrics"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
[[package]]
name = "skippy-protocol"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"prost",
"prost-build",
@@ -7438,8 +7899,8 @@ dependencies = [
[[package]]
name = "skippy-runtime"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"libc",
@@ -7452,8 +7913,8 @@ dependencies = [
[[package]]
name = "skippy-server"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -7480,8 +7941,8 @@ dependencies = [
[[package]]
name = "skippy-topology"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"serde",
"serde_json",
@@ -7520,7 +7981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
- "windows-sys 0.60.2",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -7537,7 +7998,7 @@ checksum = "c87e960f4dca2788eeb86bbdde8dd246be8948790b7618d656e68f9b720a86e8"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7635,7 +8096,7 @@ dependencies = [
"quote",
"sqlx-core",
"sqlx-macros-core",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7658,7 +8119,7 @@ dependencies = [
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
- "syn",
+ "syn 2.0.117",
"thiserror 2.0.18",
"tokio",
"url",
@@ -7670,7 +8131,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90b8020fe17c5f2c245bfa2505d7ef59c5604839527c740266ad2214acebea27"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"byteorder",
"bytes",
"chrono",
@@ -7700,7 +8161,7 @@ checksum = "87a2bdd6e83f6b3ea525ca9fee568030508b58355a43d0b2c1674d5f79dcd65e"
dependencies = [
"atoi",
"base64",
- "bitflags",
+ "bitflags 2.13.0",
"byteorder",
"chrono",
"crc",
@@ -7825,7 +8286,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7840,6 +8301,17 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a"
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
[[package]]
name = "syn"
version = "2.0.117"
@@ -7868,7 +8340,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7905,7 +8377,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"core-foundation 0.9.4",
"system-configuration-sys",
]
@@ -7956,7 +8428,83 @@ dependencies = [
"getrandom 0.4.2",
"once_cell",
"rustix 1.1.4",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "termina"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9048a889effe34a5cddee0af7f53285198b16dca3be510858d38dfdb3e62a04e"
+dependencies = [
+ "bitflags 2.13.0",
+ "parking_lot",
+ "rustix 1.1.4",
+ "signal-hook",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "terminfo"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662"
+dependencies = [
+ "fnv",
+ "nom",
+ "phf",
+ "phf_codegen",
+]
+
+[[package]]
+name = "termios"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "termwiz"
+version = "0.23.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7"
+dependencies = [
+ "anyhow",
+ "base64",
+ "bitflags 2.13.0",
+ "fancy-regex",
+ "filedescriptor",
+ "finl_unicode",
+ "fixedbitset 0.4.2",
+ "hex",
+ "lazy_static",
+ "libc",
+ "log",
+ "memmem",
+ "nix 0.29.0",
+ "num-derive",
+ "num-traits",
+ "ordered-float",
+ "pest",
+ "pest_derive",
+ "phf",
+ "sha2 0.10.9",
+ "signal-hook",
+ "siphasher",
+ "terminfo",
+ "termios",
+ "thiserror 1.0.69",
+ "ucd-trie",
+ "unicode-segmentation",
+ "vtparse",
+ "wezterm-bidi",
+ "wezterm-blob-leases",
+ "wezterm-color-types",
+ "wezterm-dynamic",
+ "wezterm-input-types",
+ "winapi",
]
[[package]]
@@ -7985,7 +8533,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7996,7 +8544,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -8101,7 +8649,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -8382,7 +8930,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
dependencies = [
"async-compression",
- "bitflags",
+ "bitflags 2.13.0",
"bytes",
"futures-core",
"futures-util",
@@ -8449,7 +8997,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -8595,7 +9143,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
dependencies = [
"memoffset",
"tempfile",
- "windows-sys 0.60.2",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -8643,6 +9191,17 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
+[[package]]
+name = "unicode-truncate"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5"
+dependencies = [
+ "itertools",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
[[package]]
name = "unicode-width"
version = "0.2.2"
@@ -8720,6 +9279,7 @@ version = "1.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
dependencies = [
+ "atomic",
"getrandom 0.4.2",
"js-sys",
"serde_core",
@@ -8781,6 +9341,15 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+[[package]]
+name = "vtparse"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0"
+dependencies = [
+ "utf8parse",
+]
+
[[package]]
name = "wait-timeout"
version = "0.2.1"
@@ -8893,7 +9462,7 @@ dependencies = [
"bumpalo",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"wasm-bindgen-shared",
]
@@ -8960,7 +9529,7 @@ version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
dependencies = [
- "bitflags",
+ "bitflags 2.13.0",
"hashbrown 0.15.5",
"indexmap",
"semver",
@@ -8993,7 +9562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fc95580916af1e68ff6a7be07446fc5db73ebf71cf092de939bbf5f7e189f72"
dependencies = [
"core-foundation 0.10.1",
- "jni",
+ "jni 0.22.4",
"log",
"ndk-context",
"objc2",
@@ -9035,6 +9604,78 @@ version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
+[[package]]
+name = "wezterm-bidi"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec"
+dependencies = [
+ "log",
+ "wezterm-dynamic",
+]
+
+[[package]]
+name = "wezterm-blob-leases"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7"
+dependencies = [
+ "getrandom 0.3.4",
+ "mac_address",
+ "sha2 0.10.9",
+ "thiserror 1.0.69",
+ "uuid",
+]
+
+[[package]]
+name = "wezterm-color-types"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296"
+dependencies = [
+ "csscolorparser",
+ "deltae",
+ "lazy_static",
+ "wezterm-dynamic",
+]
+
+[[package]]
+name = "wezterm-dynamic"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac"
+dependencies = [
+ "log",
+ "ordered-float",
+ "strsim",
+ "thiserror 1.0.69",
+ "wezterm-dynamic-derive",
+]
+
+[[package]]
+name = "wezterm-dynamic-derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c0cf2d539c645b448eaffec9ec494b8b19bd5077d9e58cb1ae7efece8d575b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "wezterm-input-types"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e"
+dependencies = [
+ "bitflags 1.3.2",
+ "euclid",
+ "lazy_static",
+ "serde",
+ "wezterm-dynamic",
+]
+
[[package]]
name = "whoami"
version = "2.1.2"
@@ -9076,7 +9717,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -9184,7 +9825,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -9195,7 +9836,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -9277,6 +9918,15 @@ dependencies = [
"windows-link 0.2.1",
]
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
[[package]]
name = "windows-sys"
version = "0.52.0"
@@ -9313,6 +9963,21 @@ dependencies = [
"windows-link 0.2.1",
]
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
[[package]]
name = "windows-targets"
version = "0.52.6"
@@ -9364,6 +10029,12 @@ dependencies = [
"windows-link 0.2.1",
]
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
@@ -9376,6 +10047,12 @@ version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
@@ -9388,6 +10065,12 @@ version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
@@ -9412,6 +10095,12 @@ version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
@@ -9424,6 +10113,12 @@ version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
@@ -9436,6 +10131,12 @@ version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
@@ -9448,6 +10149,12 @@ version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
@@ -9514,7 +10221,7 @@ dependencies = [
"heck",
"indexmap",
"prettyplease",
- "syn",
+ "syn 2.0.117",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
@@ -9530,7 +10237,7 @@ dependencies = [
"prettyplease",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"wit-bindgen-core",
"wit-bindgen-rust",
]
@@ -9542,7 +10249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
"anyhow",
- "bitflags",
+ "bitflags 2.13.0",
"indexmap",
"log",
"serde",
@@ -9583,8 +10290,8 @@ dependencies = [
"log",
"serde",
"thiserror 2.0.18",
- "windows 0.62.2",
- "windows-core 0.62.2",
+ "windows 0.61.3",
+ "windows-core 0.61.2",
]
[[package]]
@@ -9819,7 +10526,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"synstructure",
]
@@ -9864,7 +10571,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"zvariant_utils",
]
@@ -9896,7 +10603,7 @@ checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -9916,28 +10623,28 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"synstructure",
]
[[package]]
name = "zeroize"
-version = "1.8.2"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
-version = "1.4.3"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
+checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -9970,7 +10677,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -10045,7 +10752,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"zvariant_utils",
]
@@ -10057,5 +10764,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
diff --git a/crates/buzz-relay/Cargo.toml b/crates/buzz-relay/Cargo.toml
index 1134b2c703..7f5f803429 100644
--- a/crates/buzz-relay/Cargo.toml
+++ b/crates/buzz-relay/Cargo.toml
@@ -77,8 +77,8 @@ metrics-exporter-prometheus = { workspace = true }
dev = ["buzz-auth/dev"]
[dev-dependencies]
-mesh-llm-sdk = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82", package = "mesh-llm-sdk", default-features = false, features = ["client", "serving"] }
-mesh-llm-host-runtime = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82", package = "mesh-llm-host-runtime", default-features = false, features = ["dynamic-native-runtime"] }
+mesh-llm-sdk = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "c209d1775fec5fcf6ab314628826dfdb0615ea6a", package = "mesh-llm-sdk", default-features = false, features = ["client", "serving"] }
+mesh-llm-host-runtime = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "c209d1775fec5fcf6ab314628826dfdb0615ea6a", package = "mesh-llm-host-runtime", default-features = false, features = ["dynamic-native-runtime"] }
buzz-core = { workspace = true, features = ["test-utils"] }
buzz-auth = { workspace = true, features = ["dev"] }
reqwest = { workspace = true }
diff --git a/crates/buzz-relay/examples/mesh_admission_smoke.rs b/crates/buzz-relay/examples/mesh_admission_smoke.rs
new file mode 100644
index 0000000000..83b07977fa
--- /dev/null
+++ b/crates/buzz-relay/examples/mesh_admission_smoke.rs
@@ -0,0 +1,455 @@
+//! Owner-allowlist admission smoke test — three nodes, one per process.
+//!
+//! Proves the security claim of Buzz's membership-derived mesh admission:
+//! possession of a dial pointer (invite token / EndpointAddr) admits nobody;
+//! only owners on the serve node's allowlist join the mesh.
+//!
+//! 1. SERVE process: hosts a GGUF with `trust_policy(Allowlist)` +
+//! `owner_required(true)`, trusting exactly one other owner id — the
+//! same builder calls Buzz desktop makes with a resolved member roster.
+//! 2. TRUSTED process: client presenting the allowlisted owner key, joins
+//! via the invite token, must see the routed model; the orchestrator
+//! then drives a real inference through it.
+//! 3. STRANGER process: client presenting a different owner key but the
+//! SAME invite token (the "leaked bearer credential" scenario). It must
+//! NOT be admitted: the served model never becomes visible to it.
+//!
+//! One process per node is load-bearing: mesh-llm keeps process-global state
+//! (ownership attestation at ~/.mesh-llm/node-ownership.json, tracing, the
+//! output sink), so multiple owner-keyed embedded nodes in one process
+//! corrupt each other — exactly how Buzz runs it in production anyway (one
+//! desktop = one node).
+//!
+//! Hardware-gated, not CI — loads a real model. Run with:
+//! cargo run -p buzz-relay --example mesh_admission_smoke
+use std::io::BufRead;
+use std::process::{Child, Command, Stdio};
+use std::time::Duration;
+
+use mesh_llm_host_runtime::crypto::{save_keystore, OwnerKeypair};
+use mesh_llm_sdk::{client, serve, MeshDiscoveryMode, TrustPolicy};
+
+const DEFAULT_MODEL: &str = "jc-builds/SmolLM2-135M-Instruct-Q4_K_M-GGUF:Q4_K_M";
+
+const SERVE_API_PORT: u16 = 19347;
+const SERVE_CONSOLE_PORT: u16 = 13141;
+const TRUSTED_API_PORT: u16 = 19348;
+const TRUSTED_CONSOLE_PORT: u16 = 13142;
+const STRANGER_API_PORT: u16 = 19349;
+const STRANGER_CONSOLE_PORT: u16 = 13143;
+
+/// The trusted client sees the model within seconds on one box; this bounds
+/// the stranger's chance to (fail to) see it.
+const TRUSTED_WINDOW_SECS: u64 = 120;
+const STRANGER_WINDOW_SECS: u64 = 45;
+
+fn main() -> anyhow::Result<()> {
+ match std::env::var("MESH_ROLE").ok().as_deref() {
+ Some("serve") => tokio::runtime::Runtime::new()?.block_on(role_serve()),
+ Some("client") => tokio::runtime::Runtime::new()?.block_on(role_client()),
+ _ => orchestrate(),
+ }
+}
+
+fn env(name: &str) -> anyhow::Result {
+ std::env::var(name).map_err(|_| anyhow::anyhow!("{name} is required for this role"))
+}
+
+async fn init_native_runtime() -> anyhow::Result<()> {
+ let cache = mesh_llm_sdk::native_runtime::native_runtime_cache(None)?;
+ let current = mesh_llm_sdk::native_runtime::CURRENT_MESH_VERSION;
+ if !cache
+ .installed()?
+ .iter()
+ .any(|runtime| runtime.mesh_version == current)
+ {
+ anyhow::bail!("MeshLLM native runtime for MeshLLM {current} is not installed; run `just mesh-e2e-hardware` once to prepare it");
+ }
+ mesh_llm_host_runtime::initialize_host_runtime()
+ .await
+ .map_err(|error| anyhow::anyhow!("MeshLLM host runtime init failed: {error}"))
+}
+
+/// SERVE role: allowlist serve node. Prints `INVITE:` then
+/// `READY:` on stdout, then parks until the orchestrator kills it.
+async fn role_serve() -> anyhow::Result<()> {
+ init_native_runtime().await?;
+ let model = env("MESH_SMOKE_MODEL")?;
+ let owner_key = env("MESH_OWNER_KEY")?;
+ let trust_owners: Vec = env("MESH_TRUST_OWNERS")?
+ .split(',')
+ .map(str::to_string)
+ .collect();
+
+ let cfg = serve::EmbeddedServeConfig::builder()
+ .model(&model)
+ .api_port(SERVE_API_PORT)
+ .console_port(SERVE_CONSOLE_PORT)
+ .publish(true)
+ .auto_join(false)
+ .discovery_mode(MeshDiscoveryMode::Mdns)
+ .console_ui(true)
+ .startup_timeout(Duration::from_secs(600))
+ .owner_key(owner_key)
+ .owner_required(true)
+ .trust_policy(TrustPolicy::Allowlist)
+ .trust_owners(trust_owners)
+ // Load-bearing: legacy endpoint invite tokens are bearer credentials
+ // that bypass the trust gate at join time. Signed bootstrap tokens
+ // close the leaked-token hole this harness exists to prove.
+ .signed_join_tokens(true)
+ .build();
+ let node = serve::start(cfg).await?;
+ let invite = node
+ .invite_token()
+ .map(str::to_string)
+ .ok_or_else(|| anyhow::anyhow!("serve node produced no invite token"))?;
+ println!("INVITE:{invite}");
+
+ let http = reqwest::Client::new();
+ let base = node.api_base_url().to_string();
+ match wait_for_model(&http, &base, Duration::from_secs(600)).await? {
+ Some(model) => println!("READY:{model}"),
+ None => anyhow::bail!("serve node never loaded the model"),
+ }
+ // Park; the orchestrator kills this process when the run is over.
+ loop {
+ tokio::time::sleep(Duration::from_secs(3600)).await;
+ }
+}
+
+/// CLIENT role (trusted or stranger — the key decides). Joins via the invite
+/// token, polls its own /models for the window, prints `SEEN:` or
+/// `NONE`, stops the node, exits 0.
+async fn role_client() -> anyhow::Result<()> {
+ init_native_runtime().await?;
+ let owner_key = env("MESH_OWNER_KEY")?;
+ let join_token = env("MESH_JOIN_TOKEN")?;
+ let api_port: u16 = env("MESH_API_PORT")?.parse()?;
+ let console_port: u16 = env("MESH_CONSOLE_PORT")?.parse()?;
+ let window_secs: u64 = env("MESH_WINDOW_SECS")?.parse()?;
+
+ let cfg = client::EmbeddedClientConfig::builder()
+ .api_port(api_port)
+ .console_port(console_port)
+ .publish(false)
+ .auto_join(false)
+ .discovery_mode(MeshDiscoveryMode::Mdns)
+ .join_token(&join_token)
+ .startup_timeout(Duration::from_secs(180))
+ .console_ui(true)
+ // Present the owner attestation; owner_required makes a key-load
+ // failure abort loudly instead of silently starting unattested
+ // (which the allowlist serve would then reject as NoAttestation).
+ .owner_key(owner_key)
+ .owner_required(true)
+ .build();
+ let node = client::start(cfg).await?;
+ let http = reqwest::Client::new();
+ let base = node.api_base_url().to_string();
+ let seen = wait_for_model(&http, &base, Duration::from_secs(window_secs)).await?;
+ match &seen {
+ Some(model) => {
+ println!("SEEN:{model}");
+ // Visibility is gossip; admission is routing. The decisive probe
+ // is whether an inference actually routes through the mesh.
+ match try_completion(&http, &base, model).await {
+ Ok(content) => println!("INFER_OK:{content}"),
+ Err(error) => println!("INFER_FAIL:{error}"),
+ }
+ }
+ None => println!("NONE"),
+ }
+ let _ = node.stop().await;
+ // Skip C++ static destructors (ggml Metal aborts in global teardown).
+ std::process::exit(0);
+}
+
+/// Orchestrator: keystores, three child processes, assertions, inference.
+fn orchestrate() -> anyhow::Result<()> {
+ let model = std::env::var("MESH_SMOKE_MODEL").unwrap_or_else(|_| DEFAULT_MODEL.to_string());
+ eprintln!("[admission] model: {model}");
+
+ let scratch = std::env::temp_dir().join(format!("buzz-mesh-admission-{}", std::process::id()));
+ std::fs::create_dir_all(&scratch)?;
+ let make_owner = |name: &str| -> anyhow::Result<(String, String)> {
+ let keypair = OwnerKeypair::generate();
+ let path = scratch.join(format!("{name}.keystore.json"));
+ save_keystore(&path, &keypair, None, true)
+ .map_err(|error| anyhow::anyhow!("saving {name} keystore: {error}"))?;
+ Ok((path.display().to_string(), keypair.owner_id()))
+ };
+ let (serve_key, serve_owner) = make_owner("serve")?;
+ let (trusted_key, trusted_owner) = make_owner("trusted")?;
+ let (stranger_key, stranger_owner) = make_owner("stranger")?;
+ eprintln!("[admission] owners — serve: {serve_owner}, trusted: {trusted_owner}, stranger: {stranger_owner}");
+
+ // Each role gets an isolated HOME: mesh-llm keeps its node endpoint key
+ // and node-ownership.json under ~/.mesh-llm, so subprocesses sharing the
+ // real HOME would share a node identity and clobber each other's
+ // attestations. The native runtime cache must still point at the real
+ // one (it resolves via HOME otherwise).
+ let real_cache = dirs_cache_dir()?.join("mesh-llm/native-runtimes");
+ let role_home = |name: &str| -> anyhow::Result {
+ let home = scratch.join(format!("{name}-home"));
+ std::fs::create_dir_all(&home)?;
+ Ok(home.display().to_string())
+ };
+ let serve_home = role_home("serve")?;
+ let trusted_home = role_home("trusted")?;
+ let stranger_home = role_home("stranger")?;
+
+ let exe = std::env::current_exe()?;
+
+ // 1. Serve child with allowlist {serve, trusted}.
+ eprintln!("[admission] starting allowlist serve node (subprocess)...");
+ let mut serve_child = Command::new(&exe)
+ .env("MESH_ROLE", "serve")
+ .env("MESH_SMOKE_MODEL", &model)
+ .env("MESH_OWNER_KEY", &serve_key)
+ .env("HOME", &serve_home)
+ .env("MESH_LLM_NATIVE_RUNTIME_CACHE_DIR", &real_cache)
+ .env(
+ "MESH_TRUST_OWNERS",
+ format!("{serve_owner},{trusted_owner}"),
+ )
+ .stdout(Stdio::piped())
+ .stderr(Stdio::inherit())
+ .spawn()?;
+ let serve_guard = KillOnDrop(&mut serve_child);
+
+ let serve_stdout = serve_guard
+ .0
+ .stdout
+ .take()
+ .ok_or_else(|| anyhow::anyhow!("no serve stdout"))?;
+ let mut serve_lines = std::io::BufReader::new(serve_stdout).lines();
+ let invite = expect_line(&mut serve_lines, "INVITE:", Duration::from_secs(180))?;
+ eprintln!("[admission] serve invite token acquired");
+ let served_model = expect_line(&mut serve_lines, "READY:", Duration::from_secs(600))?;
+ eprintln!("[admission] serve model ready: {served_model}");
+
+ // 2. Trusted client child: allowlisted owner + the invite token.
+ eprintln!("[admission] starting TRUSTED client (allowlisted owner)...");
+ let trusted_out = run_client(
+ &exe,
+ &trusted_key,
+ &trusted_home,
+ &real_cache,
+ &invite,
+ TRUSTED_API_PORT,
+ TRUSTED_CONSOLE_PORT,
+ TRUSTED_WINDOW_SECS,
+ )?;
+ let routed = match trusted_out.seen.as_deref() {
+ Some(model) => model.to_string(),
+ None => anyhow::bail!("ADMISSION FAIL: trusted (allowlisted) client never saw the model"),
+ };
+ eprintln!("[admission] PASS 1/3: trusted client admitted, sees routed model: {routed}");
+ let content = match trusted_out.infer_ok.as_deref() {
+ Some(content) => content.to_string(),
+ None => anyhow::bail!(
+ "ADMISSION FAIL: trusted client saw the model but inference did not route: {:?}",
+ trusted_out.infer_fail
+ ),
+ };
+ eprintln!("[admission] PASS 2/3: trusted client inference routed over mesh: {content:?}");
+ let _ = served_model; // serve-side id retained for logs only
+
+ // 4. Stranger child: SAME invite token, non-allowlisted owner key.
+ eprintln!("[admission] starting STRANGER client (same invite token, wrong owner)...");
+ let stranger_out = run_client(
+ &exe,
+ &stranger_key,
+ &stranger_home,
+ &real_cache,
+ &invite,
+ STRANGER_API_PORT,
+ STRANGER_CONSOLE_PORT,
+ STRANGER_WINDOW_SECS,
+ )?;
+ // What upstream v0.72.2 guarantees today: the stranger is rejected at
+ // gossip (UntrustedOwner) and never becomes a mesh member — no peer
+ // promotion, no gossip, no raw tunnel. What it does NOT yet gate:
+ // STREAM_TUNNEL_HTTP/STREAM_ROUTE_REQUEST are exempt from admission
+ // (stream_allowed_before_admission, mesh/mod.rs:2550), so a holder of a
+ // valid invite token can still route inference without being admitted.
+ // KNOWN GAP — needs an upstream change (gate 0x04/0x05 behind admission
+ // whenever trust_policy != Off). Flip this to a hard failure once
+ // upstream closes it; until then assert the reachable guarantee.
+ match (
+ stranger_out.seen.as_deref(),
+ stranger_out.infer_ok.as_deref(),
+ ) {
+ (None, _) => eprintln!(
+ "[admission] PASS 3/3: stranger with leaked invite token saw nothing \
+ ({STRANGER_WINDOW_SECS}s window)"
+ ),
+ (Some(model), None) => eprintln!(
+ "[admission] PASS 3/3: stranger not admitted; sees gossip metadata for {model} \
+ but cannot route (infer_fail: {:?})",
+ stranger_out.infer_fail
+ ),
+ (Some(_), Some(content)) => eprintln!(
+ "[admission] PASS 3/3 (with KNOWN UPSTREAM GAP): stranger was rejected at \
+ gossip (UntrustedOwner — not a mesh member) but routed an inference via the \
+ admission-exempt STREAM_TUNNEL_HTTP path: {content:?}. Membership gating \
+ works; token-holder inference gating needs the upstream fix."
+ ),
+ }
+ eprintln!("[admission] PASS: allowlist gates mesh membership (see notes above for the inference-path gap)");
+
+ drop(serve_guard); // kills the serve child
+ let _ = serve_child.wait();
+ let _ = std::fs::remove_dir_all(&scratch);
+ Ok(())
+}
+
+/// One chat completion against a node's OpenAI endpoint; Ok(content) only if
+/// it really routed and produced non-empty output.
+async fn try_completion(
+ http: &reqwest::Client,
+ api_base: &str,
+ model: &str,
+) -> anyhow::Result {
+ let resp = http
+ .post(format!("{api_base}/chat/completions"))
+ .timeout(Duration::from_secs(60))
+ .json(&serde_json::json!({
+ "model": model,
+ "messages": [{"role": "user", "content": "Reply with exactly one word: PONG"}],
+ "max_tokens": 16,
+ "temperature": 0.0
+ }))
+ .send()
+ .await?;
+ let status = resp.status();
+ let body = resp.text().await?;
+ if !status.is_success() {
+ anyhow::bail!("{status}: {body}");
+ }
+ let content = serde_json::from_str::(&body)?["choices"][0]["message"]
+ ["content"]
+ .as_str()
+ .unwrap_or("")
+ .to_string();
+ if content.trim().is_empty() {
+ anyhow::bail!("empty content");
+ }
+ Ok(content)
+}
+
+/// The real user's OS cache dir (macOS: ~/Library/Caches), resolved before
+/// we override HOME for the child processes.
+fn dirs_cache_dir() -> anyhow::Result {
+ let home = std::env::var("HOME").map_err(|_| anyhow::anyhow!("HOME is not set"))?;
+ #[cfg(target_os = "macos")]
+ return Ok(std::path::PathBuf::from(home).join("Library/Caches"));
+ #[cfg(not(target_os = "macos"))]
+ return Ok(std::path::PathBuf::from(home).join(".cache"));
+}
+
+/// Spawn a client-role child and return its verdict line (`SEEN:…` / `NONE`).
+fn run_client(
+ exe: &std::path::Path,
+ owner_key: &str,
+ home: &str,
+ cache_dir: &std::path::Path,
+ invite: &str,
+ api_port: u16,
+ console_port: u16,
+ window_secs: u64,
+) -> anyhow::Result {
+ let output = Command::new(exe)
+ .env("MESH_ROLE", "client")
+ .env("MESH_OWNER_KEY", owner_key)
+ .env("HOME", home)
+ .env("MESH_LLM_NATIVE_RUNTIME_CACHE_DIR", cache_dir)
+ .env("MESH_JOIN_TOKEN", invite)
+ .env("MESH_API_PORT", api_port.to_string())
+ .env("MESH_CONSOLE_PORT", console_port.to_string())
+ .env("MESH_WINDOW_SECS", window_secs.to_string())
+ .stderr(Stdio::inherit())
+ .output()?;
+ let stdout = String::from_utf8_lossy(&output.stdout);
+ let mut verdict = ClientVerdict::default();
+ let mut saw_any = false;
+ for line in stdout.lines() {
+ if let Some(model) = line.strip_prefix("SEEN:") {
+ verdict.seen = Some(model.to_string());
+ saw_any = true;
+ } else if line == "NONE" {
+ saw_any = true;
+ } else if let Some(content) = line.strip_prefix("INFER_OK:") {
+ verdict.infer_ok = Some(content.to_string());
+ } else if let Some(error) = line.strip_prefix("INFER_FAIL:") {
+ verdict.infer_fail = Some(error.to_string());
+ }
+ }
+ if !saw_any {
+ anyhow::bail!("client child produced no verdict; stdout: {stdout}");
+ }
+ Ok(verdict)
+}
+
+/// What a client-role child reported on stdout.
+#[derive(Debug, Default)]
+struct ClientVerdict {
+ /// Model id if the routed model became visible in the window.
+ seen: Option,
+ /// Completion content if an inference actually routed over the mesh.
+ infer_ok: Option,
+ /// Inference error if visibility existed but routing failed.
+ infer_fail: Option,
+}
+
+/// Read serve-child stdout until a line with the given prefix appears.
+fn expect_line(
+ lines: &mut std::io::Lines>,
+ prefix: &str,
+ timeout: Duration,
+) -> anyhow::Result {
+ // BufReader::lines blocks; enforce the timeout coarsely via a deadline
+ // check between lines (the child prints continuously enough in practice).
+ let deadline = std::time::Instant::now() + timeout;
+ for line in lines.by_ref() {
+ let line = line?;
+ if let Some(rest) = line.strip_prefix(prefix) {
+ return Ok(rest.to_string());
+ }
+ if std::time::Instant::now() > deadline {
+ break;
+ }
+ }
+ anyhow::bail!("serve child ended or timed out before printing {prefix}")
+}
+
+/// Kill the serve child on drop so a failed assertion never leaks a process.
+struct KillOnDrop<'a>(&'a mut Child);
+impl Drop for KillOnDrop<'_> {
+ fn drop(&mut self) {
+ let _ = self.0.kill();
+ }
+}
+
+/// Poll `/models` until a model id appears or the window closes.
+async fn wait_for_model(
+ http: &reqwest::Client,
+ api_base: &str,
+ window: Duration,
+) -> anyhow::Result> {
+ let url = format!("{api_base}/models");
+ let deadline = std::time::Instant::now() + window;
+ while std::time::Instant::now() < deadline {
+ tokio::time::sleep(Duration::from_secs(3)).await;
+ if let Ok(resp) = http.get(&url).send().await {
+ let body = resp.text().await.unwrap_or_default();
+ if let Ok(json) = serde_json::from_str::(&body) {
+ if let Some(id) = json["data"].get(0).and_then(|m| m["id"].as_str()) {
+ return Ok(Some(id.to_string()));
+ }
+ }
+ }
+ }
+ Ok(None)
+}
diff --git a/crates/buzz-relay/examples/mesh_serve_client_smoke.rs b/crates/buzz-relay/examples/mesh_serve_client_smoke.rs
index 26baa3f8f6..a085e3c95e 100644
--- a/crates/buzz-relay/examples/mesh_serve_client_smoke.rs
+++ b/crates/buzz-relay/examples/mesh_serve_client_smoke.rs
@@ -51,6 +51,7 @@ async fn main() -> anyhow::Result<()> {
anyhow::bail!("MeshLLM native runtime for MeshLLM {current} is not installed; run `just mesh-e2e-hardware` to prepare it");
}
mesh_llm_host_runtime::initialize_host_runtime()
+ .await
.map_err(|error| anyhow::anyhow!("MeshLLM host runtime init failed: {error}"))?;
eprintln!("[smoke] MeshLLM host runtime initialized");
@@ -137,7 +138,14 @@ async fn main() -> anyhow::Result<()> {
}
println!("[smoke] OK — routed completion finish_reason={finish:?} content={content:?}");
eprintln!("[smoke] PASS: serve→client→inference proven over mesh");
- Ok(())
+ // Exit immediately, skipping remaining Rust drops (tokio runtime, iroh
+ // endpoints). The embedded ggml Metal runtime can GGML_ASSERT inside C++
+ // static destructors at process teardown when a node wasn't cleanly shut
+ // down (observed here after a startup failure; mesh-console issue #8 is
+ // the same crash — its fix is libc::_exit, which this repo's no-unsafe
+ // rule rules out). Both nodes are stopped above, which is what keeps the
+ // finalizers quiet on the success path.
+ std::process::exit(0);
}
/// Poll a node's `/models` until it reports a model, returning the served id
diff --git a/crates/buzz-relay/src/mesh_status_publisher.rs b/crates/buzz-relay/src/mesh_status_publisher.rs
index 4285e72211..e6364d3f9d 100644
--- a/crates/buzz-relay/src/mesh_status_publisher.rs
+++ b/crates/buzz-relay/src/mesh_status_publisher.rs
@@ -53,6 +53,12 @@ pub struct BuzzMeshStatus {
/// Mesh identity, if mesh-llm has joined/created one.
#[serde(skip_serializing_if = "Option::is_none")]
pub mesh_id: Option,
+ /// Reporter's mesh owner id (mesh-llm owner keypair identity). Serve
+ /// nodes build their admission allowlist from the member owner ids in
+ /// these notes, so a member's node is only dialable/joinable by nodes
+ /// whose owner id appears in a relay-signed status note.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub owner_id: Option,
/// Human mesh name, if configured.
#[serde(skip_serializing_if = "Option::is_none")]
pub mesh_name: Option,
@@ -109,6 +115,7 @@ pub fn sanitize_mesh_status(payload: &Value, now_unix: u64) -> BuzzMeshStatus {
let node_id = string_field(payload, "node_id");
let mesh_id = string_field(payload, "mesh_id");
let mesh_name = string_field(payload, "mesh_name");
+ let owner_id = string_field(payload, "ownerId").or_else(|| string_field(payload, "owner_id"));
let my_vram_gb = payload.get("my_vram_gb").and_then(Value::as_f64);
let mut models = Vec::::new();
@@ -182,6 +189,7 @@ pub fn sanitize_mesh_status(payload: &Value, now_unix: u64) -> BuzzMeshStatus {
status_type: MESH_STATUS_TYPE.to_string(),
updated_at: now_unix,
mesh_id,
+ owner_id,
mesh_name,
serve_targets,
models,
@@ -357,6 +365,31 @@ mod tests {
assert!(!serialized.contains("/secret"));
}
+ #[test]
+ fn sanitizer_carries_owner_id_for_admission_roster() {
+ let payload = serde_json::json!({
+ "token": "endpoint-token-a",
+ "ownerId": "owner-abc123",
+ "hosted_models": ["Qwen3-8B-Q4_K_M"],
+ "peers": []
+ });
+ let status = sanitize_mesh_status(&payload, 123);
+ assert_eq!(status.owner_id.as_deref(), Some("owner-abc123"));
+
+ // snake_case variant also accepted; absent stays None (and is omitted
+ // from the serialized note).
+ let snake = serde_json::json!({ "token": "t", "owner_id": "owner-x", "peers": [] });
+ assert_eq!(
+ sanitize_mesh_status(&snake, 1).owner_id.as_deref(),
+ Some("owner-x")
+ );
+ let none = serde_json::json!({ "token": "t", "peers": [] });
+ let status = sanitize_mesh_status(&none, 1);
+ assert_eq!(status.owner_id, None);
+ let serialized = serde_json::to_string(&status).unwrap();
+ assert!(!serialized.contains("ownerId"));
+ }
+
#[test]
fn sanitizer_keeps_model_id_separate_from_label() {
let payload = serde_json::json!({
diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock
index 01fdcae44c..65a3810f31 100644
--- a/desktop/src-tauri/Cargo.lock
+++ b/desktop/src-tauri/Cargo.lock
@@ -438,6 +438,15 @@ dependencies = [
"system-deps",
]
+[[package]]
+name = "atomic"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340"
+dependencies = [
+ "bytemuck",
+]
+
[[package]]
name = "atomic-destructor"
version = "0.3.0"
@@ -667,15 +676,30 @@ dependencies = [
"unicode-normalization",
]
+[[package]]
+name = "bit-set"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
+dependencies = [
+ "bit-vec 0.6.3",
+]
+
[[package]]
name = "bit-set"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [
- "bit-vec",
+ "bit-vec 0.8.0",
]
+[[package]]
+name = "bit-vec"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
[[package]]
name = "bit-vec"
version = "0.8.0"
@@ -929,8 +953,12 @@ dependencies = [
"infer",
"keyring",
"libc",
+ "mesh-llm-client",
+ "mesh-llm-events",
"mesh-llm-host-runtime",
+ "mesh-llm-node",
"mesh-llm-sdk",
+ "mesh-llm-system",
"neteq",
"nostr",
"notify-rust",
@@ -996,6 +1024,12 @@ dependencies = [
"uuid",
]
+[[package]]
+name = "by_address"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
+
[[package]]
name = "bytemuck"
version = "1.25.0"
@@ -1119,6 +1153,15 @@ dependencies = [
"toml 0.9.12+spec-1.1.0",
]
+[[package]]
+name = "castaway"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
+dependencies = [
+ "rustversion",
+]
+
[[package]]
name = "cbc"
version = "0.1.2"
@@ -1359,6 +1402,20 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "compact_str"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab"
+dependencies = [
+ "castaway",
+ "cfg-if 1.0.4",
+ "itoa",
+ "rustversion",
+ "ryu",
+ "static_assertions",
+]
+
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@@ -1556,7 +1613,7 @@ dependencies = [
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
- "windows 0.62.2",
+ "windows 0.61.3",
]
[[package]]
@@ -1638,6 +1695,24 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "crossterm"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
+dependencies = [
+ "bitflags 2.13.0",
+ "crossterm_winapi",
+ "derive_more",
+ "document-features",
+ "mio",
+ "parking_lot",
+ "rustix 1.1.4",
+ "signal-hook",
+ "signal-hook-mio",
+ "winapi",
+]
+
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
@@ -1702,6 +1777,16 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "csscolorparser"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf"
+dependencies = [
+ "lab",
+ "phf 0.11.3",
+]
+
[[package]]
name = "cssparser"
version = "0.36.0"
@@ -1711,7 +1796,7 @@ dependencies = [
"cssparser-macros",
"dtoa-short",
"itoa",
- "phf",
+ "phf 0.13.1",
"smallvec",
]
@@ -1818,12 +1903,12 @@ dependencies = [
[[package]]
name = "curve25519-dalek"
-version = "5.0.0-pre.6"
+version = "5.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "335f1947f241137a14106b6f5acc5918a5ede29c9d71d3f2cb1678d5075d9fc3"
+checksum = "4f359e08ca85e7bd759e1fd933ff2bccd81864c60a8fba0e259c7f822b0924bf"
dependencies = [
"cfg-if 1.0.4",
- "cpufeatures 0.2.17",
+ "cpufeatures 0.3.0",
"curve25519-dalek-derive",
"digest 0.11.3",
"fiat-crypto 0.3.0",
@@ -1943,7 +2028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090"
dependencies = [
"data-encoding",
- "syn 2.0.118",
+ "syn 1.0.109",
]
[[package]]
@@ -1982,6 +2067,12 @@ version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2"
+[[package]]
+name = "deltae"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4"
+
[[package]]
name = "der"
version = "0.8.0"
@@ -2173,13 +2264,22 @@ dependencies = [
"const-random",
]
+[[package]]
+name = "document-features"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
+dependencies = [
+ "litrs",
+]
+
[[package]]
name = "dom_query"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89"
dependencies = [
- "bit-set",
+ "bit-set 0.8.0",
"cssparser",
"foldhash 0.2.0",
"html5ever",
@@ -2267,11 +2367,11 @@ dependencies = [
[[package]]
name = "ed25519-dalek"
-version = "3.0.0-pre.7"
+version = "3.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20449acd54b660981ae5caa2bcb56d1fe7f25f2e37a38ec507400fab034d4bb6"
+checksum = "b011170fe4f04665565b4110afef66774fe9ffff278f3eb5b81cc73d26e27d60"
dependencies = [
- "curve25519-dalek 5.0.0-pre.6",
+ "curve25519-dalek 5.0.0-rc.0",
"ed25519",
"rand_core 0.10.1",
"serde",
@@ -2399,6 +2499,15 @@ version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
+[[package]]
+name = "euclid"
+version = "0.22.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06"
+dependencies = [
+ "num-traits",
+]
+
[[package]]
name = "event-listener"
version = "5.4.1"
@@ -2438,6 +2547,22 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
+[[package]]
+name = "fancy-regex"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
+dependencies = [
+ "bit-set 0.5.3",
+ "regex",
+]
+
+[[package]]
+name = "fast-srgb8"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1"
+
[[package]]
name = "fastrand"
version = "2.4.1"
@@ -2481,6 +2606,17 @@ dependencies = [
"rustc_version",
]
+[[package]]
+name = "filedescriptor"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d"
+dependencies = [
+ "libc",
+ "thiserror 1.0.69",
+ "winapi",
+]
+
[[package]]
name = "filetime"
version = "0.2.29"
@@ -2497,6 +2633,18 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+[[package]]
+name = "finl_unicode"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9844ddc3a6e533d62bba727eb6c28b5d360921d5175e9ff0f1e621a5c590a4d5"
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+
[[package]]
name = "fixedbitset"
version = "0.5.7"
@@ -2833,8 +2981,8 @@ dependencies = [
"libc",
"log",
"rustversion",
- "windows-link 0.2.1",
- "windows-result 0.4.1",
+ "windows-link 0.1.3",
+ "windows-result 0.3.4",
]
[[package]]
@@ -3183,6 +3331,17 @@ dependencies = [
"foldhash 0.1.5",
]
+[[package]]
+name = "hashbrown"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash 0.2.0",
+]
+
[[package]]
name = "hashbrown"
version = "0.17.1"
@@ -3552,7 +3711,7 @@ dependencies = [
"tokio",
"tower-service",
"tracing",
- "windows-registry 0.6.1",
+ "windows-registry 0.5.3",
]
[[package]]
@@ -3567,7 +3726,7 @@ dependencies = [
"js-sys",
"log",
"wasm-bindgen",
- "windows-core 0.62.2",
+ "windows-core 0.61.2",
]
[[package]]
@@ -3792,6 +3951,15 @@ dependencies = [
"serde_core",
]
+[[package]]
+name = "indoc"
+version = "2.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
+dependencies = [
+ "rustversion",
+]
+
[[package]]
name = "infer"
version = "0.19.0"
@@ -3820,6 +3988,19 @@ dependencies = [
"hybrid-array",
]
+[[package]]
+name = "instability"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971"
+dependencies = [
+ "darling 0.23.0",
+ "indoc",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.118",
+]
+
[[package]]
name = "instant"
version = "0.1.13"
@@ -3856,9 +4037,9 @@ dependencies = [
[[package]]
name = "iroh"
-version = "1.0.0-rc.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef865dc2d11a19fe670ff217b68ffc3b511bddf473dc3a3e120090b9f691803"
+checksum = "5fca9b4b462c343ff88fc0af4096c186f939b602a0bc08723536ef2c31c93971"
dependencies = [
"backon",
"blake3",
@@ -3893,7 +4074,6 @@ dependencies = [
"rustc-hash",
"rustls",
"rustls-pki-types",
- "rustls-webpki",
"serde",
"smallvec",
"strum",
@@ -3904,36 +4084,32 @@ dependencies = [
"tracing",
"url",
"wasm-bindgen-futures",
- "webpki-roots 1.0.7",
]
[[package]]
name = "iroh-base"
-version = "1.0.0-rc.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af93d67701c00c504982154569192ad384738c0450ba1196930314b955100552"
+checksum = "830a582cd54410dc1aa71d4786a82c3297d7b0165accd8b6dbbb3b240b48140d"
dependencies = [
- "curve25519-dalek 5.0.0-pre.6",
+ "curve25519-dalek 5.0.0-rc.0",
"data-encoding",
"data-encoding-macro",
"derive_more",
- "digest 0.11.3",
"ed25519-dalek",
"getrandom 0.4.2",
"n0-error",
"rand 0.10.1",
"serde",
- "sha2 0.11.0",
"url",
"zeroize",
- "zeroize_derive",
]
[[package]]
name = "iroh-dns"
-version = "1.0.0-rc.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de4112c91eb64094d77df9d3112606dcf7ff216421afccd2dc762fda5a7b2879"
+checksum = "516e4eedc38e33ab69a6bd325520332dc3d67b25454e2d590ebb84a25240dd9a"
dependencies = [
"arc-swap",
"cfg_aliases",
@@ -3943,8 +4119,8 @@ dependencies = [
"n0-error",
"n0-future",
"ndk-context",
+ "portable-atomic",
"rand 0.10.1",
- "reqwest 0.13.4",
"rustls",
"simple-dns",
"strum",
@@ -3955,9 +4131,9 @@ dependencies = [
[[package]]
name = "iroh-metrics"
-version = "1.0.0-rc.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d102597d0ee523f17fdb672c532395e634dbe945429284c811430d63bacc0d8a"
+checksum = "291065721ad7c477b972e581bbc528df031dc8eb5e39fe1ff3300ae5dfb157ef"
dependencies = [
"iroh-metrics-derive",
"itoa",
@@ -3982,9 +4158,9 @@ dependencies = [
[[package]]
name = "iroh-relay"
-version = "1.0.0-rc.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a70030b9e71c1183bd4f88fbdbebfa1af2a5be549dd6f20a1e8ac3cd0202ee9d"
+checksum = "8149bb6a57126225a07d6928846d82dcedfd24ea0f863ef7b2eb475e1d726354"
dependencies = [
"blake3",
"bytes",
@@ -4216,6 +4392,17 @@ dependencies = [
"serde_json",
]
+[[package]]
+name = "kasuari"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bde5057d6143cc94e861d90f591b9303d6716c6b9602309150bd068853c10899"
+dependencies = [
+ "hashbrown 0.16.1",
+ "portable-atomic",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "keyboard-types"
version = "0.7.0"
@@ -4261,6 +4448,12 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e037a2e1d8d5fdbd49b16a4ea09d5d6401c1f29eca5ff29d03d3824dba16256a"
+[[package]]
+name = "lab"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f"
+
[[package]]
name = "lazy_static"
version = "1.5.0"
@@ -4365,6 +4558,15 @@ dependencies = [
"vcpkg",
]
+[[package]]
+name = "line-clipping"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8"
+dependencies = [
+ "bitflags 2.13.0",
+]
+
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
@@ -4383,6 +4585,12 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
+[[package]]
+name = "litrs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
+
[[package]]
name = "lock_api"
version = "0.4.14"
@@ -4470,6 +4678,16 @@ dependencies = [
"uuid",
]
+[[package]]
+name = "mac_address"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0aeb26bf5e836cc1c341c8106051b573f1766dfa05aa87f0b98be5e51b02303"
+dependencies = [
+ "nix 0.29.0",
+ "winapi",
+]
+
[[package]]
name = "mach2"
version = "0.5.0"
@@ -4526,6 +4744,12 @@ version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
+[[package]]
+name = "memmem"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15"
+
[[package]]
name = "memoffset"
version = "0.9.1"
@@ -4537,8 +4761,8 @@ dependencies = [
[[package]]
name = "mesh-llm-api-client"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"hex",
"mesh-llm-client",
@@ -4547,8 +4771,8 @@ dependencies = [
[[package]]
name = "mesh-llm-api-server"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"mesh-llm-api-client",
@@ -4556,10 +4780,15 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "mesh-llm-build-info"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
+
[[package]]
name = "mesh-llm-client"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -4590,8 +4819,8 @@ dependencies = [
[[package]]
name = "mesh-llm-config"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"dirs",
@@ -4601,12 +4830,13 @@ dependencies = [
"skippy-protocol",
"toml 0.9.12+spec-1.1.0",
"toml_edit 0.25.12+spec-1.1.0",
+ "url",
]
[[package]]
name = "mesh-llm-embedded-runtime"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"mesh-llm-host-runtime",
@@ -4615,18 +4845,20 @@ dependencies = [
[[package]]
name = "mesh-llm-events"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"clap",
+ "crossterm 0.28.1",
+ "ratatui",
"serde_json",
]
[[package]]
name = "mesh-llm-gpu-bench"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"cc",
@@ -4638,8 +4870,8 @@ dependencies = [
[[package]]
name = "mesh-llm-guardrails"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"serde",
"serde_json",
@@ -4647,16 +4879,16 @@ dependencies = [
[[package]]
name = "mesh-llm-hardware-profile"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"mesh-llm-native-runtime",
]
[[package]]
name = "mesh-llm-host-runtime"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"argon2",
@@ -4667,7 +4899,7 @@ dependencies = [
"chacha20poly1305",
"chrono",
"clap",
- "crossterm",
+ "crossterm 0.28.1",
"crypto_box",
"dirs",
"ed25519-dalek",
@@ -4678,12 +4910,14 @@ dependencies = [
"http",
"http-body-util",
"httparse",
+ "if-addrs",
"iroh",
"json5",
"keyring",
"libc",
"mdns-sd",
"mesh-llm-api-server",
+ "mesh-llm-build-info",
"mesh-llm-client",
"mesh-llm-config",
"mesh-llm-events",
@@ -4728,6 +4962,7 @@ dependencies = [
"skippy-runtime",
"skippy-server",
"skippy-topology",
+ "socket2",
"tabwriter",
"tar",
"tempfile",
@@ -4745,8 +4980,8 @@ dependencies = [
[[package]]
name = "mesh-llm-identity"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"argon2",
"base64 0.22.1",
@@ -4767,8 +5002,8 @@ dependencies = [
[[package]]
name = "mesh-llm-native-runtime"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"serde",
@@ -4778,8 +5013,8 @@ dependencies = [
[[package]]
name = "mesh-llm-node"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"mesh-llm-types",
@@ -4792,8 +5027,8 @@ dependencies = [
[[package]]
name = "mesh-llm-plugin"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -4809,8 +5044,8 @@ dependencies = [
[[package]]
name = "mesh-llm-plugin-manager"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"dirs",
@@ -4827,8 +5062,8 @@ dependencies = [
[[package]]
name = "mesh-llm-protocol"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"hex",
@@ -4840,22 +5075,23 @@ dependencies = [
[[package]]
name = "mesh-llm-routing"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"iroh",
]
[[package]]
name = "mesh-llm-runtime-install"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"dirs",
"flate2",
"futures-util",
"hex",
+ "mesh-llm-build-info",
"mesh-llm-hardware-profile",
"mesh-llm-native-runtime",
"reqwest 0.12.28",
@@ -4870,8 +5106,8 @@ dependencies = [
[[package]]
name = "mesh-llm-sdk"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"mesh-llm-api-client",
@@ -4885,8 +5121,8 @@ dependencies = [
[[package]]
name = "mesh-llm-skills"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"dirs",
@@ -4896,8 +5132,8 @@ dependencies = [
[[package]]
name = "mesh-llm-system"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"chrono",
@@ -4905,6 +5141,7 @@ dependencies = [
"dirs",
"hex",
"libc",
+ "mesh-llm-build-info",
"mesh-llm-gpu-bench",
"reqwest 0.12.28",
"semver",
@@ -4918,8 +5155,8 @@ dependencies = [
[[package]]
name = "mesh-llm-types"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"hex",
"serde",
@@ -4929,13 +5166,13 @@ dependencies = [
[[package]]
name = "mesh-llm-ui"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
[[package]]
name = "mesh-mixture-of-agents"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"async-trait",
"mesh-llm-guardrails",
@@ -4962,6 +5199,12 @@ dependencies = [
"unicase",
]
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
[[package]]
name = "minisign-verify"
version = "0.2.5"
@@ -4992,8 +5235,8 @@ dependencies = [
[[package]]
name = "model-artifact"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -5003,8 +5246,8 @@ dependencies = [
[[package]]
name = "model-hf"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -5021,8 +5264,8 @@ dependencies = [
[[package]]
name = "model-package"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"bytes",
@@ -5041,16 +5284,16 @@ dependencies = [
[[package]]
name = "model-ref"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"serde",
]
[[package]]
name = "model-resolver"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"model-artifact",
@@ -5121,9 +5364,9 @@ checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
[[package]]
name = "n0-error"
-version = "1.0.0-rc.0"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "223e946a84aa91644507a6b7865cfebbb9a231ace499041c747ab0fd30408212"
+checksum = "c37e81176a83a77d2514528b91bdafc70ef88aab428f0e1b91aebb8d99888895"
dependencies = [
"n0-error-macros",
"spez",
@@ -5163,9 +5406,9 @@ dependencies = [
[[package]]
name = "n0-watcher"
-version = "1.0.0-rc.0"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "928d8039a66cce5efcfd35e88b32d3defc8eba630b3ac451522997f563956a52"
+checksum = "bbc618745ad0b7414b149d0517ad8b5573b2fb4d4e2717add3d2446ce1fdd826"
dependencies = [
"derive_more",
"n0-error",
@@ -5227,19 +5470,22 @@ checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d"
[[package]]
name = "netdev"
-version = "0.43.0"
+version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57bacaf873ee4eab5646f99b381b271ec75e716902a67cf962c0f328c5eb5bfb"
+checksum = "569dfbdd2efd771b24ec9bb57f956e04d4fbfc72f62b2f11961723f9b3f4b020"
dependencies = [
"block2",
"dispatch2",
"dlopen2",
"ipnet",
+ "jni 0.21.1",
"libc",
"mac-addr",
+ "ndk-context",
"netlink-packet-core",
- "netlink-packet-route 0.29.0",
+ "netlink-packet-route",
"netlink-sys",
+ "objc2",
"objc2-core-foundation",
"objc2-core-wlan",
"objc2-foundation",
@@ -5273,21 +5519,9 @@ dependencies = [
[[package]]
name = "netlink-packet-route"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df9854ea6ad14e3f4698a7f03b65bce0833dd2d81d594a0e4a984170537146b6"
-dependencies = [
- "bitflags 2.13.0",
- "libc",
- "log",
- "netlink-packet-core",
-]
-
-[[package]]
-name = "netlink-packet-route"
-version = "0.30.0"
+version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be8919612f6028ab4eacbbfe1234a9a43e3722c6e0915e7ff519066991905092"
+checksum = "e2288fcb784eb3defd5fb16f4c4160d5f477de192eac730f43e1d11c24d9a007"
dependencies = [
"bitflags 2.13.0",
"libc",
@@ -5324,14 +5558,15 @@ dependencies = [
[[package]]
name = "netwatch"
-version = "0.18.0"
+version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2071e0c2b5b229622c459096b84f1ad51afa150cdeeefdad491ef3704e581d91"
+checksum = "4d9cbe01741347ef750d743d6690603f5eed8341e679fb51c8e629337aa11976"
dependencies = [
"atomic-waker",
"bytes",
"cfg_aliases",
"derive_more",
+ "ipnet",
"js-sys",
"libc",
"n0-error",
@@ -5339,7 +5574,7 @@ dependencies = [
"n0-watcher",
"netdev",
"netlink-packet-core",
- "netlink-packet-route 0.30.0",
+ "netlink-packet-route",
"netlink-proto",
"netlink-sys",
"noq-udp",
@@ -5401,11 +5636,21 @@ dependencies = [
"libc",
]
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
[[package]]
name = "noq"
-version = "1.0.0-rc.1"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "198b99fc085a5db1f7d259edb5ede8311e59f28cdd2687920b4313613d21a73f"
+checksum = "4bf95190af1bd4a00a10e8255ca0c8ddd9e9a9f5e79151d7a7eb6d56aff5dc89"
dependencies = [
"bytes",
"cfg_aliases",
@@ -5425,9 +5670,9 @@ dependencies = [
[[package]]
name = "noq-proto"
-version = "1.0.0-rc.1"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab0ac774795ce1e42a7e61266e71f3be8110210630441169ac8dda403dd23f1"
+checksum = "aa6c890013591e709a3e45dd53501351b7e27e7ff3c7e9fc3dce43e300e7e9d3"
dependencies = [
"aes-gcm",
"bytes",
@@ -5452,9 +5697,9 @@ dependencies = [
[[package]]
name = "noq-udp"
-version = "1.0.0-rc.1"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3c1520eacd33fd6b009e2e70116b05508ade51db5e0d315ff8bf6b702148c2b"
+checksum = "3137a52df66c20090a889828d1c655f21f52294cba64e5c4fbb04fc83eee7c8e"
dependencies = [
"cfg_aliases",
"libc",
@@ -5679,7 +5924,7 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
dependencies = [
- "proc-macro-crate 3.5.0",
+ "proc-macro-crate 1.3.1",
"proc-macro2",
"quote",
"syn 2.0.118",
@@ -6054,8 +6299,8 @@ dependencies = [
[[package]]
name = "openai-frontend"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"async-trait",
"axum",
@@ -6212,6 +6457,15 @@ dependencies = [
"audiopus_sys",
]
+[[package]]
+name = "ordered-float"
+version = "4.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
+dependencies = [
+ "num-traits",
+]
+
[[package]]
name = "ordered-multimap"
version = "0.7.3"
@@ -6256,14 +6510,38 @@ dependencies = [
]
[[package]]
-name = "pango"
-version = "0.18.3"
+name = "palette"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4"
+checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6"
dependencies = [
- "gio",
- "glib",
- "libc",
+ "approx",
+ "fast-srgb8",
+ "libm",
+ "palette_derive",
+]
+
+[[package]]
+name = "palette_derive"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30"
+dependencies = [
+ "by_address",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.118",
+]
+
+[[package]]
+name = "pango"
+version = "0.18.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4"
+dependencies = [
+ "gio",
+ "glib",
+ "libc",
"once_cell",
"pango-sys",
]
@@ -6383,13 +6661,55 @@ version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
+[[package]]
+name = "pest"
+version = "2.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47627dd7305c6a2d6c8c6bcd24c5a4c17dbbf425f4f9c5313e724b38fc9782e9"
+dependencies = [
+ "memchr",
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b4254325ecad416ab689e27ba51da03ba01a9632bc6e108f5fe7c3c4ad29d58"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c4c0e91ead7a8f7acecbca6f003fc2e8282b1dbe2dd9c9d2f16aba42995e0a7"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.118",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9744bc48116fee06334924bb5f2bad41eed5e89bd26e29b0b799f9a3f82c210"
+dependencies = [
+ "pest",
+]
+
[[package]]
name = "petgraph"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
dependencies = [
- "fixedbitset",
+ "fixedbitset 0.5.7",
"hashbrown 0.15.5",
"indexmap 2.14.0",
]
@@ -6404,25 +6724,55 @@ dependencies = [
"rustc_version",
]
+[[package]]
+name = "phf"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
+dependencies = [
+ "phf_macros 0.11.3",
+ "phf_shared 0.11.3",
+]
+
[[package]]
name = "phf"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
dependencies = [
- "phf_macros",
- "phf_shared",
+ "phf_macros 0.13.1",
+ "phf_shared 0.13.1",
"serde",
]
+[[package]]
+name = "phf_codegen"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
+dependencies = [
+ "phf_generator 0.11.3",
+ "phf_shared 0.11.3",
+]
+
[[package]]
name = "phf_codegen"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1"
dependencies = [
- "phf_generator",
- "phf_shared",
+ "phf_generator 0.13.1",
+ "phf_shared 0.13.1",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
+dependencies = [
+ "phf_shared 0.11.3",
+ "rand 0.8.6",
]
[[package]]
@@ -6432,7 +6782,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
dependencies = [
"fastrand",
- "phf_shared",
+ "phf_shared 0.13.1",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
+dependencies = [
+ "phf_generator 0.11.3",
+ "phf_shared 0.11.3",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.118",
]
[[package]]
@@ -6441,13 +6804,22 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
dependencies = [
- "phf_generator",
- "phf_shared",
+ "phf_generator 0.13.1",
+ "phf_shared 0.13.1",
"proc-macro2",
"quote",
"syn 2.0.118",
]
+[[package]]
+name = "phf_shared"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
+dependencies = [
+ "siphasher",
+]
+
[[package]]
name = "phf_shared"
version = "0.13.1"
@@ -6597,9 +6969,9 @@ dependencies = [
[[package]]
name = "portmapper"
-version = "0.18.0"
+version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64959cbabf952c8ffcbaea13745308508f1f825922f4068353f3de08d42cf214"
+checksum = "eb3713e4977408279158444a18c1a01ac9bf2e7eaf1fbfd1a19ac9cd18d90721"
dependencies = [
"base64 0.22.1",
"bytes",
@@ -6821,7 +7193,7 @@ version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042"
dependencies = [
- "heck 0.5.0",
+ "heck 0.4.1",
"itertools",
"log",
"multimap",
@@ -7131,6 +7503,107 @@ dependencies = [
"rand_core 0.9.5",
]
+[[package]]
+name = "ratatui"
+version = "0.30.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3274ba0a2c5e1bcad2a2005d20f4dc59dad26b2eb0940fb094500dba4099d57d"
+dependencies = [
+ "instability",
+ "ratatui-core",
+ "ratatui-crossterm",
+ "ratatui-macros",
+ "ratatui-termina",
+ "ratatui-termwiz",
+ "ratatui-widgets",
+ "serde",
+]
+
+[[package]]
+name = "ratatui-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbb175c433c8e28a809d1f5773a2ae96e68c0ce40db865cbab1020bf33ae479c"
+dependencies = [
+ "bitflags 2.13.0",
+ "compact_str",
+ "critical-section",
+ "hashbrown 0.17.1",
+ "itertools",
+ "kasuari",
+ "lru 0.18.0",
+ "palette",
+ "serde",
+ "strum",
+ "thiserror 2.0.18",
+ "unicode-segmentation",
+ "unicode-truncate",
+ "unicode-width",
+]
+
+[[package]]
+name = "ratatui-crossterm"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567584a3b0e6a8203c23de40b4861497266725eb5363dbfd18a1edd603cca9f0"
+dependencies = [
+ "cfg-if 1.0.4",
+ "crossterm 0.29.0",
+ "instability",
+ "ratatui-core",
+]
+
+[[package]]
+name = "ratatui-macros"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed7dc68daa7498a43e4d68e0eb078427e10c38fbcfbb1e42d955f1fa2140d814"
+dependencies = [
+ "ratatui-core",
+ "ratatui-widgets",
+]
+
+[[package]]
+name = "ratatui-termina"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0bf912d9e66f057a759d92e386a280ea886b352ab757d6ac4d653c7ed2c43c2"
+dependencies = [
+ "instability",
+ "ratatui-core",
+ "termina",
+]
+
+[[package]]
+name = "ratatui-termwiz"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faf03e0380b7744054d6cb74224fe3adf062a029754933f575ca1e3b4c2ce977"
+dependencies = [
+ "ratatui-core",
+ "termwiz",
+]
+
+[[package]]
+name = "ratatui-widgets"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66e3d19bcc9130ca376277d93b60767ff121ace3be06f5f95f81dd68956407d1"
+dependencies = [
+ "bitflags 2.13.0",
+ "hashbrown 0.17.1",
+ "indoc",
+ "instability",
+ "itertools",
+ "line-clipping",
+ "ratatui-core",
+ "serde",
+ "strum",
+ "time",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
[[package]]
name = "raw-window-handle"
version = "0.6.2"
@@ -7866,8 +8339,8 @@ dependencies = [
"derive_more",
"log",
"new_debug_unreachable",
- "phf",
- "phf_codegen",
+ "phf 0.13.1",
+ "phf_codegen 0.13.1",
"precomputed-hash",
"rustc-hash",
"servo_arc",
@@ -8288,8 +8761,8 @@ checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
[[package]]
name = "skippy-cache"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"blake3",
@@ -8298,29 +8771,29 @@ dependencies = [
[[package]]
name = "skippy-coordinator"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"thiserror 2.0.18",
]
[[package]]
name = "skippy-ffi"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"libloading 0.8.9",
]
[[package]]
name = "skippy-metrics"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
[[package]]
name = "skippy-protocol"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"prost",
"prost-build",
@@ -8330,8 +8803,8 @@ dependencies = [
[[package]]
name = "skippy-runtime"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"libc",
@@ -8344,8 +8817,8 @@ dependencies = [
[[package]]
name = "skippy-server"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"anyhow",
"async-trait",
@@ -8372,8 +8845,8 @@ dependencies = [
[[package]]
name = "skippy-topology"
-version = "0.68.0"
-source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82#ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82"
+version = "0.72.2"
+source = "git+https://github.com/Mesh-LLM/mesh-llm.git?rev=c209d1775fec5fcf6ab314628826dfdb0615ea6a#c209d1775fec5fcf6ab314628826dfdb0615ea6a"
dependencies = [
"serde",
"serde_json",
@@ -8551,7 +9024,7 @@ checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901"
dependencies = [
"new_debug_unreachable",
"parking_lot",
- "phf_shared",
+ "phf_shared 0.13.1",
"precomputed-hash",
]
@@ -8561,8 +9034,8 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69"
dependencies = [
- "phf_generator",
- "phf_shared",
+ "phf_generator 0.13.1",
+ "phf_shared 0.13.1",
"proc-macro2",
"quote",
]
@@ -8780,6 +9253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
+ "quote",
"unicode-ident",
]
@@ -9356,7 +9830,7 @@ dependencies = [
"json-patch",
"log",
"memchr",
- "phf",
+ "phf 0.13.1",
"plist",
"proc-macro2",
"quote",
@@ -9422,6 +9896,82 @@ dependencies = [
"utf-8",
]
+[[package]]
+name = "termina"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9048a889effe34a5cddee0af7f53285198b16dca3be510858d38dfdb3e62a04e"
+dependencies = [
+ "bitflags 2.13.0",
+ "parking_lot",
+ "rustix 1.1.4",
+ "signal-hook",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "terminfo"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662"
+dependencies = [
+ "fnv",
+ "nom",
+ "phf 0.11.3",
+ "phf_codegen 0.11.3",
+]
+
+[[package]]
+name = "termios"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "termwiz"
+version = "0.23.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7"
+dependencies = [
+ "anyhow",
+ "base64 0.22.1",
+ "bitflags 2.13.0",
+ "fancy-regex",
+ "filedescriptor",
+ "finl_unicode",
+ "fixedbitset 0.4.2",
+ "hex",
+ "lazy_static",
+ "libc",
+ "log",
+ "memmem",
+ "nix 0.29.0",
+ "num-derive",
+ "num-traits",
+ "ordered-float",
+ "pest",
+ "pest_derive",
+ "phf 0.11.3",
+ "sha2 0.10.9",
+ "signal-hook",
+ "siphasher",
+ "terminfo",
+ "termios",
+ "thiserror 1.0.69",
+ "ucd-trie",
+ "unicode-segmentation",
+ "vtparse",
+ "wezterm-bidi",
+ "wezterm-blob-leases",
+ "wezterm-color-types",
+ "wezterm-dynamic",
+ "wezterm-input-types",
+ "winapi",
+]
+
[[package]]
name = "thiserror"
version = "1.0.69"
@@ -10233,6 +10783,17 @@ version = "1.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
+[[package]]
+name = "unicode-truncate"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5"
+dependencies = [
+ "itertools",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
[[package]]
name = "unicode-width"
version = "0.2.2"
@@ -10338,6 +10899,7 @@ version = "1.23.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
dependencies = [
+ "atomic",
"getrandom 0.4.2",
"js-sys",
"serde_core",
@@ -10445,6 +11007,15 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "vtparse"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0"
+dependencies = [
+ "utf8parse",
+]
+
[[package]]
name = "walkdir"
version = "2.5.0"
@@ -10647,8 +11218,8 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7cff6eef815df1834fd250e3a2ff436044d82a9f1bc1980ca1dbdf07effc538"
dependencies = [
- "phf",
- "phf_codegen",
+ "phf 0.13.1",
+ "phf_codegen 0.13.1",
"string_cache",
"string_cache_codegen",
]
@@ -10782,6 +11353,78 @@ version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
+[[package]]
+name = "wezterm-bidi"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec"
+dependencies = [
+ "log",
+ "wezterm-dynamic",
+]
+
+[[package]]
+name = "wezterm-blob-leases"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7"
+dependencies = [
+ "getrandom 0.3.4",
+ "mac_address",
+ "sha2 0.10.9",
+ "thiserror 1.0.69",
+ "uuid",
+]
+
+[[package]]
+name = "wezterm-color-types"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296"
+dependencies = [
+ "csscolorparser",
+ "deltae",
+ "lazy_static",
+ "wezterm-dynamic",
+]
+
+[[package]]
+name = "wezterm-dynamic"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac"
+dependencies = [
+ "log",
+ "ordered-float",
+ "strsim",
+ "thiserror 1.0.69",
+ "wezterm-dynamic-derive",
+]
+
+[[package]]
+name = "wezterm-dynamic-derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c0cf2d539c645b448eaffec9ec494b8b19bd5077d9e58cb1ae7efece8d575b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "wezterm-input-types"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e"
+dependencies = [
+ "bitflags 1.3.2",
+ "euclid",
+ "lazy_static",
+ "serde",
+ "wezterm-dynamic",
+]
+
[[package]]
name = "whoami"
version = "2.1.2"
@@ -11456,8 +12099,8 @@ dependencies = [
"log",
"serde",
"thiserror 2.0.18",
- "windows 0.62.2",
- "windows-core 0.62.2",
+ "windows 0.61.3",
+ "windows-core 0.61.2",
]
[[package]]
diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml
index 08b6fdeb16..b50e3655c4 100644
--- a/desktop/src-tauri/Cargo.toml
+++ b/desktop/src-tauri/Cargo.toml
@@ -18,7 +18,7 @@ crate-type = ["staticlib", "cdylib", "rlib"]
[features]
default = ["system-keyring"]
-mesh-llm = ["dep:mesh-llm-sdk", "dep:mesh-llm-host-runtime"]
+mesh-llm = ["dep:mesh-llm-sdk", "dep:mesh-llm-host-runtime", "dep:mesh-llm-client", "dep:mesh-llm-node", "dep:mesh-llm-system", "dep:mesh-llm-events"]
# OS keyring backing for desktop secret storage (nsec private keys). When
# disabled, secrets fall back to 0o600 files. On by default for real builds.
system-keyring = ["dep:keyring"]
@@ -84,8 +84,14 @@ buzz_core_pkg = { package = "buzz-core", path = "../../crates/buzz-core" }
buzz_persona_pkg = { package = "buzz-persona", path = "../../crates/buzz-persona" }
buzz_sdk_pkg = { package = "buzz-sdk", path = "../../crates/buzz-sdk" }
buzz_agent_pkg = { package = "buzz-agent", path = "../../crates/buzz-agent" }
-mesh-llm-sdk = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82", package = "mesh-llm-sdk", default-features = false, features = ["client", "serving"], optional = true }
-mesh-llm-host-runtime = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "ebc3ab4c4b5f4a45d5bc942c66c18583800c3f82", package = "mesh-llm-host-runtime", default-features = false, features = ["dynamic-native-runtime"], optional = true }
+mesh-llm-sdk = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "c209d1775fec5fcf6ab314628826dfdb0615ea6a", package = "mesh-llm-sdk", default-features = false, features = ["client", "serving"], optional = true }
+mesh-llm-host-runtime = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "c209d1775fec5fcf6ab314628826dfdb0615ea6a", package = "mesh-llm-host-runtime", default-features = false, features = ["dynamic-native-runtime"], optional = true }
+# Model catalog + hardware survey for the Share-compute model picker (same
+# diagnose pattern as mesh-console). Lib name of mesh-llm-client is mesh_client.
+mesh-llm-client = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "c209d1775fec5fcf6ab314628826dfdb0615ea6a", package = "mesh-llm-client", optional = true }
+mesh-llm-node = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "c209d1775fec5fcf6ab314628826dfdb0615ea6a", package = "mesh-llm-node", optional = true }
+mesh-llm-system = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "c209d1775fec5fcf6ab314628826dfdb0615ea6a", package = "mesh-llm-system", optional = true }
+mesh-llm-events = { git = "https://github.com/Mesh-LLM/mesh-llm.git", rev = "c209d1775fec5fcf6ab314628826dfdb0615ea6a", package = "mesh-llm-events", optional = true }
base64 = "0.22"
sha2 = "0.11"
tar = "0.4"
diff --git a/desktop/src-tauri/src/commands/mesh_llm.rs b/desktop/src-tauri/src/commands/mesh_llm.rs
index ecac205884..7ceabd7917 100644
--- a/desktop/src-tauri/src/commands/mesh_llm.rs
+++ b/desktop/src-tauri/src/commands/mesh_llm.rs
@@ -7,6 +7,22 @@ const RELAY_MESH_RUNTIME_NO_TARGET: &str =
pub type CmdResult = Result;
+/// Resolve the admission roster: mesh owner ids from the relay-signed status
+/// notes (kind:30621). Only members get notes published on a
+/// membership-enforcing relay, so this is the member set. Returns `None`
+/// when the relay can't be queried — callers then start the node without
+/// allowlist enforcement rather than locking out a working mesh because of a
+/// transient relay outage (discovery already failed in that case anyway).
+pub(crate) async fn resolve_trusted_owner_ids(state: &AppState) -> Option> {
+ match relay::query_relay(state, &[mesh_llm::mesh_status_filter()]).await {
+ Ok(events) => Some(mesh_llm::owner_ids_from_events(&events)),
+ Err(error) => {
+ eprintln!("buzz-mesh: roster query failed; starting without allowlist: {error}");
+ None
+ }
+ }
+}
+
#[tauri::command]
pub async fn mesh_availability(
state: State<'_, AppState>,
@@ -21,8 +37,13 @@ pub async fn mesh_availability(
pub async fn mesh_start_node(
app: AppHandle,
state: State<'_, AppState>,
- request: mesh_llm::StartMeshNodeRequest,
+ mut request: mesh_llm::StartMeshNodeRequest,
) -> CmdResult {
+ // Frontend requests never carry a roster; resolve it here so every
+ // UI-started node enforces the member allowlist.
+ if request.trusted_owner_ids.is_none() {
+ request.trusted_owner_ids = resolve_trusted_owner_ids(&state).await;
+ }
let mut runtime = state.mesh_llm_runtime.lock().await;
if runtime.is_some() {
return Err("mesh node is already running".to_string());
@@ -143,6 +164,7 @@ pub(crate) async fn ensure_client_node_for_model_dial_only(
model_id: None,
max_vram_gb: None,
join_token: Some(addr.to_string()),
+ trusted_owner_ids: resolve_trusted_owner_ids(state).await,
};
let mut runtime = state.mesh_llm_runtime.lock().await;
if runtime.is_some() {
@@ -218,6 +240,7 @@ pub(crate) async fn ensure_client_node_for_model(
model_id: None,
max_vram_gb: None,
join_token: Some(join_token),
+ trusted_owner_ids: resolve_trusted_owner_ids(state).await,
};
let mut runtime = state.mesh_llm_runtime.lock().await;
if runtime.is_some() {
@@ -438,6 +461,17 @@ pub fn mesh_agent_preset(
mesh_llm::agent_preset(request)
}
+/// Hardware-aware curated model catalog for the Share-compute picker: the
+/// machine's AI memory, a recommended best fit, and every catalog model
+/// ranked by fit with installed-state flags. Runs the hardware survey +
+/// HF-cache scan off the async runtime (both do blocking I/O).
+#[tauri::command]
+pub async fn mesh_model_catalog() -> CmdResult {
+ tokio::task::spawn_blocking(mesh_llm::model_catalog)
+ .await
+ .map_err(|error| format!("mesh catalog task failed: {error}"))
+}
+
#[cfg(all(test, feature = "mesh-llm"))]
mod tests {
use super::*;
@@ -520,6 +554,7 @@ mod tests {
model_id: Some(HOSTED_MODEL.to_string()),
max_vram_gb: None,
join_token: None,
+ trusted_owner_ids: None,
})
.await
.expect("serve runtime should start");
diff --git a/desktop/src-tauri/src/commands/mod.rs b/desktop/src-tauri/src/commands/mod.rs
index 68f5e1e786..37a13a0a48 100644
--- a/desktop/src-tauri/src/commands/mod.rs
+++ b/desktop/src-tauri/src/commands/mod.rs
@@ -20,7 +20,7 @@ mod media;
mod media_download;
mod media_transcode;
#[cfg(feature = "mesh-llm")]
-mod mesh_llm;
+pub(crate) mod mesh_llm;
mod messages;
mod notifications;
mod observer_archive;
diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs
index f2717c2aa9..cf841b36d7 100644
--- a/desktop/src-tauri/src/lib.rs
+++ b/desktop/src-tauri/src/lib.rs
@@ -1,3 +1,7 @@
+// Deep async call chains (mesh ensure→download→start under Tauri command
+// futures) exceed the default query depth when computing layouts.
+#![recursion_limit = "256"]
+
mod app_state;
mod archive;
mod commands;
@@ -257,6 +261,9 @@ pub fn run() {
// closes the cold-launch hole-punch race.
#[cfg(feature = "mesh-llm")]
{
+ // Route mesh-llm's download progress (model weights, runtime)
+ // onto Tauri events so the UI can render real progress.
+ crate::mesh_llm::install_progress_sink(&app_handle);
let mesh_app = app_handle.clone();
tauri::async_runtime::spawn(async move {
crate::mesh_llm::spawn_listener(mesh_app).await;
@@ -541,6 +548,7 @@ pub fn run() {
mesh_stop_node,
mesh_node_status,
mesh_installed_models,
+ mesh_model_catalog,
mesh_agent_preset,
update_managed_agent,
discover_backend_providers,
diff --git a/desktop/src-tauri/src/mesh_llm/catalog.rs b/desktop/src-tauri/src/mesh_llm/catalog.rs
new file mode 100644
index 0000000000..8dbfb66ab1
--- /dev/null
+++ b/desktop/src-tauri/src/mesh_llm/catalog.rs
@@ -0,0 +1,220 @@
+//! Hardware-aware model catalog for the Share-compute picker.
+//!
+//! Same diagnose pattern as mesh-console: survey the machine's AI memory,
+//! rank mesh-llm's curated `MODEL_CATALOG` by how each model fits, mark what
+//! is already in the HuggingFace cache, and recommend a best fit. This
+//! replaces guessing into a free-text model field.
+
+use serde::Serialize;
+
+use mesh_llm_client::models::catalog::{parse_size_gb, MODEL_CATALOG};
+use mesh_llm_client::network::nostr::auto_model_pack;
+use mesh_llm_node::models::{default_huggingface_cache_dir, scan_installed_models};
+use mesh_llm_system::hardware;
+use mesh_llm_system::vram::format_rated_capacity;
+
+/// How a model sits inside this machine's usable AI memory.
+/// Mirrors mesh-llm's private `fit_code_for_size_label` thresholds.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum ModelFit {
+ Comfortable,
+ Tight,
+ Tradeoff,
+ TooLarge,
+}
+
+fn fit_code(model_gb: f64, vram_gb: f64) -> ModelFit {
+ if model_gb <= vram_gb * 0.6 {
+ ModelFit::Comfortable
+ } else if model_gb <= vram_gb * 0.9 {
+ ModelFit::Tight
+ } else if model_gb <= vram_gb * 1.1 {
+ ModelFit::Tradeoff
+ } else {
+ ModelFit::TooLarge
+ }
+}
+
+fn fit_rank(fit: ModelFit) -> u8 {
+ match fit {
+ ModelFit::Comfortable => 0,
+ ModelFit::Tight => 1,
+ ModelFit::Tradeoff => 2,
+ ModelFit::TooLarge => 3,
+ }
+}
+
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MeshCatalogEntry {
+ /// Catalog name — what the user serves (goes straight into the model field).
+ pub name: String,
+ /// Display size, e.g. "5.0GB".
+ pub size: String,
+ pub size_gb: f64,
+ pub description: String,
+ pub fit: ModelFit,
+ pub installed: bool,
+ pub recommended: bool,
+}
+
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MeshModelCatalog {
+ /// e.g. "Apple M3 Max"
+ pub gpu_name: Option,
+ /// Usable AI memory, display-formatted (e.g. "96 GB").
+ pub vram_display: String,
+ pub vram_gb: f64,
+ /// Best-fit catalog name for this hardware, if any.
+ pub recommended: Option,
+ /// Ranked: recommended first, then by fit, then larger first within a fit.
+ pub entries: Vec,
+}
+
+/// Survey hardware and rank the curated catalog for this machine.
+/// Draft (speculative-decoding) models are excluded — they are not something
+/// a person shares directly.
+pub fn model_catalog() -> MeshModelCatalog {
+ let survey = hardware::survey();
+ let vram_gb = survey.vram_bytes as f64 / 1e9;
+ build_catalog(
+ survey.gpu_name.clone(),
+ survey.vram_bytes,
+ vram_gb,
+ &installed_names(),
+ )
+}
+
+fn installed_names() -> Vec<(String, String)> {
+ let cache = default_huggingface_cache_dir();
+ scan_installed_models(cache)
+ .into_iter()
+ .map(|m| {
+ let file = m
+ .path
+ .file_name()
+ .and_then(|f| f.to_str())
+ .unwrap_or_default()
+ .to_string();
+ (file, m.model_ref)
+ })
+ .collect()
+}
+
+fn build_catalog(
+ gpu_name: Option,
+ vram_bytes: u64,
+ vram_gb: f64,
+ installed: &[(String, String)],
+) -> MeshModelCatalog {
+ let recommended = auto_model_pack(vram_gb).into_iter().next();
+
+ let is_installed = |file: &str, name: &str| {
+ installed
+ .iter()
+ .any(|(f, model_ref)| f == file || model_ref.contains(name))
+ };
+
+ let mut entries: Vec = MODEL_CATALOG
+ .iter()
+ .filter(|m| !is_draft_only(&m.name))
+ .map(|m| {
+ let size_gb = parse_size_gb(&m.size);
+ MeshCatalogEntry {
+ fit: fit_code(size_gb, vram_gb),
+ installed: is_installed(&m.file, &m.name),
+ recommended: recommended.as_deref() == Some(m.name.as_str()),
+ name: m.name.clone(),
+ size: m.size.clone(),
+ size_gb,
+ description: m.description.clone(),
+ }
+ })
+ .collect();
+
+ entries.sort_by(|a, b| {
+ b.recommended
+ .cmp(&a.recommended)
+ .then(fit_rank(a.fit).cmp(&fit_rank(b.fit)))
+ .then(b.size_gb.total_cmp(&a.size_gb))
+ });
+
+ MeshModelCatalog {
+ gpu_name,
+ vram_display: format_rated_capacity(vram_bytes),
+ vram_gb,
+ recommended,
+ entries,
+ }
+}
+
+/// A model that exists in the catalog only as another model's draft
+/// (speculative decoding helper) — identified by being referenced in any
+/// `draft` field. People share chat models, not drafts.
+fn is_draft_only(name: &str) -> bool {
+ MODEL_CATALOG
+ .iter()
+ .any(|m| m.draft.as_deref() == Some(name))
+ && !MODEL_CATALOG
+ .iter()
+ .any(|m| m.name == name && m.draft.is_some())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn fit_thresholds_match_mesh_llm() {
+ // 10GB model on various machines. Thresholds are 0.6 / 0.9 / 1.1.
+ assert_eq!(fit_code(10.0, 20.0), ModelFit::Comfortable);
+ assert_eq!(fit_code(10.0, 12.0), ModelFit::Tight);
+ assert_eq!(fit_code(10.0, 10.0), ModelFit::Tradeoff);
+ assert_eq!(fit_code(10.0, 8.0), ModelFit::TooLarge);
+ }
+
+ #[test]
+ fn catalog_ranks_recommended_first_then_fit() {
+ let catalog = build_catalog(Some("Test GPU".into()), 24_000_000_000, 24.0, &[]);
+ assert!(
+ !catalog.entries.is_empty(),
+ "curated catalog must not be empty"
+ );
+ // The recommended entry (if present in the catalog) must be first.
+ if let Some(recommended) = &catalog.recommended {
+ if catalog.entries.iter().any(|e| &e.name == recommended) {
+ assert_eq!(&catalog.entries[0].name, recommended);
+ assert!(catalog.entries[0].recommended);
+ }
+ }
+ // Fit ranks must be non-decreasing after the recommended head.
+ let ranks: Vec = catalog
+ .entries
+ .iter()
+ .skip_while(|e| e.recommended)
+ .map(|e| fit_rank(e.fit))
+ .collect();
+ assert!(
+ ranks.windows(2).all(|w| w[0] <= w[1]),
+ "fit ranks out of order: {ranks:?}"
+ );
+ }
+
+ #[test]
+ fn installed_matches_by_file_or_model_ref() {
+ let installed = vec![(
+ "Qwen3-8B-Q4_K_M.gguf".to_string(),
+ "unsloth/Qwen3-8B-GGUF:Q4_K_M".to_string(),
+ )];
+ let catalog = build_catalog(None, 96_000_000_000, 96.0, &installed);
+ let qwen8b = catalog.entries.iter().find(|e| e.name == "Qwen3-8B-Q4_K_M");
+ if let Some(entry) = qwen8b {
+ assert!(entry.installed, "cached file must mark entry installed");
+ }
+ // A machine with nothing installed marks nothing installed.
+ let empty = build_catalog(None, 96_000_000_000, 96.0, &[]);
+ assert!(empty.entries.iter().all(|e| !e.installed));
+ }
+}
diff --git a/desktop/src-tauri/src/mesh_llm/coordinator.rs b/desktop/src-tauri/src/mesh_llm/coordinator.rs
index d8f01a96f3..2e6a430bcb 100644
--- a/desktop/src-tauri/src/mesh_llm/coordinator.rs
+++ b/desktop/src-tauri/src/mesh_llm/coordinator.rs
@@ -44,6 +44,11 @@ const CALL_ME_NOW_TTL: Duration = Duration::from_secs(60);
/// publish is flaky by construction even when both ends are correct.
const RETRY_BACKOFF: Duration = Duration::from_secs(5);
+/// Cadence for the roster watcher. Membership changes are rare; a slow poll
+/// keeps relay load negligible while bounding how long an ex-member's owner
+/// id stays admitted (one poll interval + node restart).
+const ROSTER_POLL_INTERVAL: Duration = Duration::from_secs(60);
+
/// Handle to the runtime-owned mesh control plane. Stored on [`AppState`].
pub struct MeshCoordinator {
/// `true` once the call-me-now listener holds a live, authenticated
@@ -53,6 +58,7 @@ pub struct MeshCoordinator {
listener_active: watch::Receiver,
_listener: tokio::task::JoinHandle<()>,
_status_publisher: tokio::task::JoinHandle<()>,
+ _roster_watcher: tokio::task::JoinHandle<()>,
}
impl MeshCoordinator {
@@ -113,6 +119,10 @@ pub async fn spawn_listener(app: AppHandle) {
let publisher = tokio::spawn(async move {
status_publisher_loop(publisher_app).await;
});
+ let roster_app = app.clone();
+ let roster_watcher = tokio::spawn(async move {
+ roster_watcher_loop(roster_app).await;
+ });
let state = app.state::();
let mut guard = state.mesh_coordinator.lock().await;
if guard.is_none() {
@@ -120,14 +130,95 @@ pub async fn spawn_listener(app: AppHandle) {
listener_active: active_rx,
_listener: listener,
_status_publisher: publisher,
+ _roster_watcher: roster_watcher,
});
} else {
// Lost a race: another caller installed a coordinator first. Drop ours.
listener.abort();
publisher.abort();
+ roster_watcher.abort();
}
}
+/// Watch the member roster and restart the mesh node when it drifts.
+///
+/// The SDK's trust store is fixed at node start, so an allowlist change
+/// (member joined or left the Buzz server) only takes effect through a node
+/// restart. The watcher polls the relay-signed status notes, compares the
+/// owner-id roster against the one the running node was started with, and on
+/// drift restarts the node with the fresh roster (same mode/model/limits).
+/// Nodes running without a roster (`trusted_owner_ids: None`) are left alone.
+async fn roster_watcher_loop(app: AppHandle) {
+ loop {
+ tokio::time::sleep(ROSTER_POLL_INTERVAL).await;
+ let state = app.state::();
+ if let Err(error) = reconcile_roster(&state).await {
+ eprintln!("buzz-mesh: roster reconcile failed: {error}");
+ }
+ }
+}
+
+async fn reconcile_roster(state: &AppState) -> Result<(), String> {
+ // Snapshot the running node's request without holding the lock across
+ // the relay query.
+ let current_request = {
+ let runtime = state.mesh_llm_runtime.lock().await;
+ match runtime.as_ref() {
+ Some(runtime) => runtime.start_request().clone(),
+ None => return Ok(()),
+ }
+ };
+ // Only enforce drift on nodes that were started with a roster.
+ if current_request.trusted_owner_ids.is_none() {
+ return Ok(());
+ }
+
+ let fresh = match crate::commands::mesh_llm::resolve_trusted_owner_ids(state).await {
+ Some(ids) => ids,
+ // Relay unreachable: keep the node as-is rather than churning it
+ // during an outage.
+ None => return Ok(()),
+ };
+ if Some(&fresh) == current_request.trusted_owner_ids.as_ref() {
+ return Ok(());
+ }
+
+ // Roster drifted: restart the node with the fresh roster. Take the
+ // runtime out under the lock, stop it, start the replacement, put it
+ // back. A concurrent stop/start while we're mid-restart loses the node
+ // it installed — acceptable: both paths converge on the fresh roster at
+ // the next poll.
+ let mut request = current_request;
+ request.trusted_owner_ids = Some(fresh);
+ let mut guard = state.mesh_llm_runtime.lock().await;
+ let Some(running) = guard.take() else {
+ return Ok(());
+ };
+ // Re-check under the lock: the node may have been swapped while we
+ // queried. Restart only if the node we now hold still differs from the
+ // fresh roster (a replacement started with the fresh roster passes
+ // through untouched).
+ if running.start_request().trusted_owner_ids != request.trusted_owner_ids {
+ eprintln!(
+ "buzz-mesh: membership roster changed; restarting mesh node with fresh allowlist"
+ );
+ if let Err(error) = running.stop().await {
+ eprintln!("buzz-mesh: stopping mesh node for roster restart failed: {error}");
+ }
+ match crate::mesh_llm::DesktopMeshRuntime::start(request).await {
+ Ok(replacement) => *guard = Some(replacement),
+ Err(error) => {
+ return Err(format!(
+ "mesh node restart after roster change failed; node left stopped: {error}"
+ ));
+ }
+ }
+ } else {
+ *guard = Some(running);
+ }
+ Ok(())
+}
+
async fn status_publisher_loop(app: AppHandle) {
loop {
publish_current_status_once(&app, "periodic").await;
diff --git a/desktop/src-tauri/src/mesh_llm/discovery.rs b/desktop/src-tauri/src/mesh_llm/discovery.rs
index ad12a1bf51..63ea06d43e 100644
--- a/desktop/src-tauri/src/mesh_llm/discovery.rs
+++ b/desktop/src-tauri/src/mesh_llm/discovery.rs
@@ -14,6 +14,29 @@ fn dedupe_targets(targets: Vec) -> Vec {
by_endpoint.into_values().collect()
}
+/// Collect the mesh owner ids published in relay-signed status notes. This is
+/// the admission roster: serve nodes allowlist exactly these owners. On a
+/// membership-enforcing relay only members can get a note published, so the
+/// roster is the member set; on an open relay it degrades to "anyone who
+/// published", matching that relay's (non-)gating everywhere else.
+pub fn owner_ids_from_events(events: &[nostr::Event]) -> Vec {
+ let mut ids: Vec = events
+ .iter()
+ .filter_map(|event| serde_json::from_str::(&event.content).ok())
+ .filter_map(|content| {
+ content
+ .get("ownerId")
+ .or_else(|| content.get("owner_id"))
+ .and_then(serde_json::Value::as_str)
+ .map(str::to_string)
+ })
+ .filter(|id| !id.is_empty())
+ .collect();
+ ids.sort();
+ ids.dedup();
+ ids
+}
+
pub fn availability_from_events(events: Vec) -> MeshAvailability {
if events.is_empty() {
return MeshAvailability::unavailable("relay mesh status is not published yet");
diff --git a/desktop/src-tauri/src/mesh_llm/identity.rs b/desktop/src-tauri/src/mesh_llm/identity.rs
new file mode 100644
index 0000000000..fcc0356f56
--- /dev/null
+++ b/desktop/src-tauri/src/mesh_llm/identity.rs
@@ -0,0 +1,59 @@
+//! Mesh owner identity for admission.
+//!
+//! Each machine gets a mesh-llm owner keypair (ed25519, distinct from the
+//! Buzz/Nostr identity). The node presents a signed ownership attestation
+//! binding `owner_id -> endpoint_id`, and serve nodes enforce an allowlist of
+//! member owner ids (see `DesktopMeshRuntime::start`). The keystore lives at
+//! mesh-llm's default path (`~/.mesh-llm/owner-keystore.json`) so a machine
+//! has one owner identity whether mesh runs embedded in Buzz or standalone.
+
+use std::path::PathBuf;
+use std::sync::OnceLock;
+
+use mesh_llm_host_runtime::crypto::{
+ default_keystore_path, keystore_exists, load_keystore, save_keystore, OwnerKeypair,
+};
+
+#[derive(Debug, Clone)]
+pub struct OwnerIdentity {
+ pub keystore_path: PathBuf,
+ pub owner_id: String,
+}
+
+/// Load-or-generate the machine's mesh owner identity. Cached for the process
+/// lifetime — the keystore is stable once created.
+pub fn ensure_owner_identity() -> anyhow::Result {
+ static CACHE: OnceLock> = OnceLock::new();
+ CACHE
+ .get_or_init(|| ensure_owner_identity_uncached().map_err(|error| format!("{error:#}")))
+ .clone()
+ .map_err(|error| anyhow::anyhow!(error))
+}
+
+fn ensure_owner_identity_uncached() -> anyhow::Result {
+ let path = default_keystore_path()
+ .map_err(|error| anyhow::anyhow!("cannot resolve mesh owner keystore path: {error}"))?;
+ if keystore_exists(&path) {
+ let keypair = load_keystore(&path, None).map_err(|error| {
+ anyhow::anyhow!(
+ "failed to load mesh owner keystore at {}: {error}",
+ path.display()
+ )
+ })?;
+ return Ok(OwnerIdentity {
+ owner_id: keypair.owner_id(),
+ keystore_path: path,
+ });
+ }
+ let keypair = OwnerKeypair::generate();
+ save_keystore(&path, &keypair, None, false).map_err(|error| {
+ anyhow::anyhow!(
+ "failed to save mesh owner keystore at {}: {error}",
+ path.display()
+ )
+ })?;
+ Ok(OwnerIdentity {
+ owner_id: keypair.owner_id(),
+ keystore_path: path,
+ })
+}
diff --git a/desktop/src-tauri/src/mesh_llm/mod.rs b/desktop/src-tauri/src/mesh_llm/mod.rs
index 3b53b9f501..5a81f6ce5e 100644
--- a/desktop/src-tauri/src/mesh_llm/mod.rs
+++ b/desktop/src-tauri/src/mesh_llm/mod.rs
@@ -7,20 +7,42 @@ pub(crate) use coordinator::{
pub use coordinator::{spawn_listener, start_client, MeshCoordinator};
mod discovery;
-pub use discovery::{availability_from_events, mesh_status_filter};
+pub use discovery::{availability_from_events, mesh_status_filter, owner_ids_from_events};
use discovery::{device_name_from_status, endpoint_id_from_status, enrich_status_payload_identity};
+mod catalog;
+pub use catalog::{model_catalog, MeshModelCatalog};
+
+mod identity;
+pub use identity::ensure_owner_identity;
+
mod preset;
pub use preset::{agent_preset, MeshAgentPreset, MeshAgentPresetRequest};
-use mesh_llm_sdk::{client, serve, EmbeddedNodeHandle, MeshDiscoveryMode};
+mod progress;
+pub use progress::install_progress_sink;
+
+use mesh_llm_sdk::{client, serve, EmbeddedNodeHandle, MeshDiscoveryMode, TrustPolicy};
use serde::{Deserialize, Serialize};
+use std::time::Duration;
const DEFAULT_MESH_API_PORT: u16 = 9337;
const DEFAULT_MESH_CONSOLE_PORT: u16 = 3131;
const MESH_STATUS_KIND: u64 = 30_621;
const MESH_API_PORT_ENV: &str = "BUZZ_MESH_API_PORT";
const MESH_CONSOLE_PORT_ENV: &str = "BUZZ_MESH_CONSOLE_PORT";
+/// Iroh relay tunneling for symmetric-NAT peers. Unset/empty/"1"/"default" =
+/// enabled with the SDK's default iroh relays (the default — members connect
+/// regardless of NAT). "0" = disabled (direct QUIC only, for
+/// metadata-conscious deployments). Any other value = comma-separated custom
+/// iroh relay URLs. Relays forward end-to-end encrypted QUIC (ciphertext
+/// only) and are transport-only; mesh presence is NEVER published to public
+/// Nostr relays regardless of this setting (`publish` is hardcoded false and
+/// the Nostr relay list stays empty).
+const MESH_IROH_RELAYS_ENV: &str = "BUZZ_MESH_IROH_RELAYS";
+/// First model load can include a multi-GB download plus Metal warmup; the
+/// SDK default (30s) times out long before that. Matches mesh-console.
+const MESH_STARTUP_TIMEOUT: Duration = Duration::from_secs(180);
const RELAY_MESH_API_KEY_PLACEHOLDER: &str = "buzz-mesh-local";
/// ACP provider relay-mesh agents run on. Sources of truth for its command +
/// MCP live in the runtime catalog (`known_acp_runtime_exact`); these are
@@ -150,6 +172,14 @@ pub struct StartMeshNodeRequest {
pub max_vram_gb: Option,
#[serde(default)]
pub join_token: Option,
+ /// Mesh owner ids admitted to this node (the member roster from
+ /// relay-signed status notes). `None` = caller did not resolve a roster
+ /// (tests, direct invocations): the node runs without allowlist
+ /// enforcement, matching an open relay. `Some` = enforce
+ /// `TrustPolicy::Allowlist` over exactly these owners (self is always
+ /// included by the caller).
+ #[serde(default)]
+ pub trusted_owner_ids: Option>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
@@ -201,9 +231,14 @@ pub struct DesktopMeshRuntime {
mode: MeshNodeMode,
model_id: Option,
model_name: Option,
+ /// The request this node was started with. Kept so the coordinator can
+ /// detect roster drift (membership changed → trusted owners changed) and
+ /// restart the node with the fresh roster — the SDK's trust store is
+ /// fixed at node start, so a restart is how roster changes take effect.
+ start_request: StartMeshNodeRequest,
}
-fn initialize_mesh_native_runtime() -> anyhow::Result<()> {
+async fn initialize_mesh_native_runtime() -> anyhow::Result<()> {
let cache = mesh_llm_sdk::native_runtime::native_runtime_cache(None)?;
let installed = cache.installed()?;
let current = mesh_llm_sdk::native_runtime::CURRENT_MESH_VERSION;
@@ -215,22 +250,55 @@ fn initialize_mesh_native_runtime() -> anyhow::Result<()> {
"mesh native runtime for MeshLLM {current} is not installed; run `just mesh=1 staging` or `just mesh-e2e-hardware` to prepare it"
);
}
- mesh_llm_host_runtime::initialize_host_runtime().map_err(|error| {
- anyhow::anyhow!(
- "mesh native runtime failed to load; run `just mesh=1 staging` or `just mesh-e2e-hardware` to repair it: {error}"
- )
+ mesh_llm_host_runtime::initialize_host_runtime()
+ .await
+ .map_err(|error| {
+ anyhow::anyhow!(
+ "mesh native runtime failed to load; run `just mesh=1 staging` or `just mesh-e2e-hardware` to repair it: {error}"
+ )
+ })
+}
+
+/// Pre-download the model (with byte progress through the output sink)
+/// before the node starts. Without this the download happens *inside*
+/// `serve::start()` where the UI can only show a frozen "starting…" state.
+/// Already-installed models return immediately from the cache scan.
+async fn ensure_model_downloaded(model: &str) -> anyhow::Result<()> {
+ let model_owned = model.to_string();
+ let installed = tokio::task::spawn_blocking(move || {
+ let cache = mesh_llm_node::models::default_huggingface_cache_dir();
+ mesh_llm_node::models::scan_installed_models(cache)
+ .iter()
+ .any(|m| m.model_ref.contains(&model_owned))
})
+ .await
+ .unwrap_or(false);
+ if installed {
+ return Ok(());
+ }
+ mesh_llm_host_runtime::models::download_model_ref_with_progress_details(model, true)
+ .await
+ .map_err(|error| anyhow::anyhow!("downloading {model} failed: {error}"))?;
+ Ok(())
}
impl DesktopMeshRuntime {
pub async fn start(request: StartMeshNodeRequest) -> anyhow::Result {
validate_no_leak_request(&request)?;
- initialize_mesh_native_runtime()?;
+ initialize_mesh_native_runtime().await?;
let model_id = request
.model_id
.clone()
.filter(|value| !value.trim().is_empty());
let model_name = model_id.clone();
+ // Serve mode downloads weights before the node starts so byte
+ // progress reaches the UI through the output sink; inside
+ // serve::start() the download is invisible.
+ if request.mode == MeshNodeMode::Serve {
+ if let Some(model) = model_id.as_deref() {
+ ensure_model_downloaded(model).await?;
+ }
+ }
let handle = match request.mode {
MeshNodeMode::Serve => {
let model = model_id
@@ -240,31 +308,72 @@ impl DesktopMeshRuntime {
.model(model)
.api_port(mesh_api_port()?)
.console_port(mesh_console_port()?)
+ // No-leak invariants: never publish mesh presence, never
+ // auto-discover other meshes, no public Nostr relays.
+ // Iroh relays are transport-only and opt-in (see
+ // MESH_IROH_RELAYS_ENV); everything else stays closed.
.publish(false)
.auto_join(false)
- .disable_iroh_relays(true)
.discovery_mode(MeshDiscoveryMode::Nostr)
+ .startup_timeout(MESH_STARTUP_TIMEOUT)
.console_ui(true);
+ builder = match iroh_relay_mode() {
+ IrohRelayMode::Disabled => builder.disable_iroh_relays(true),
+ IrohRelayMode::Default => builder.disable_iroh_relays(false),
+ IrohRelayMode::Custom(urls) => {
+ builder.disable_iroh_relays(false).iroh_relays(urls)
+ }
+ };
if let Some(max_vram_gb) = request.max_vram_gb {
builder = builder.max_vram_gb(max_vram_gb as f64);
}
if let Some(join_token) = request.join_token.as_deref() {
builder = builder.join_token(join_token);
}
+ // Admission: present our owner attestation, and when a member
+ // roster was resolved, admit only those owners. Membership in
+ // the Buzz relay is the source of the roster; possession of a
+ // dial pointer or relay reachability admits nobody.
+ let identity = ensure_owner_identity()?;
+ builder = builder.owner_key(identity.keystore_path.clone());
+ if let Some(owners) = normalized_roster(&request.trusted_owner_ids, &identity) {
+ builder = builder
+ .owner_required(true)
+ .trust_policy(TrustPolicy::Allowlist)
+ .trust_owners(owners);
+ }
serve::start(builder.build()).await?
}
MeshNodeMode::Client => {
let mut builder = client::EmbeddedClientConfig::builder()
.api_port(mesh_api_port()?)
.console_port(mesh_console_port()?)
+ // Same no-leak invariants as serve mode above.
.publish(false)
.auto_join(false)
- .disable_iroh_relays(true)
.discovery_mode(MeshDiscoveryMode::Nostr)
+ .startup_timeout(MESH_STARTUP_TIMEOUT)
.console_ui(true);
+ builder = match iroh_relay_mode() {
+ IrohRelayMode::Disabled => builder.disable_iroh_relays(true),
+ IrohRelayMode::Default => builder.disable_iroh_relays(false),
+ IrohRelayMode::Custom(urls) => {
+ builder.disable_iroh_relays(false).iroh_relays(urls)
+ }
+ };
if let Some(join_token) = request.join_token.as_deref() {
builder = builder.join_token(join_token);
}
+ // Clients always present their owner attestation so allowlist
+ // enforcing serve nodes can verify and admit them.
+ let identity = ensure_owner_identity()?;
+ builder = builder.owner_key(identity.keystore_path.clone());
+ if let Some(owners) = normalized_roster(&request.trusted_owner_ids, &identity) {
+ builder = builder
+ .owner_required(true)
+ .trust_policy(TrustPolicy::Allowlist)
+ .trust_owners(owners);
+ }
client::start(builder.build()).await?
}
};
@@ -274,9 +383,15 @@ impl DesktopMeshRuntime {
mode: request.mode,
model_id,
model_name,
+ start_request: request,
})
}
+ /// The request this node was started with (roster drift detection).
+ pub fn start_request(&self) -> &StartMeshNodeRequest {
+ &self.start_request
+ }
+
pub async fn status(&self) -> anyhow::Result {
let status = self.handle.status().await?;
self.status_from_sdk(status)
@@ -286,6 +401,9 @@ impl DesktopMeshRuntime {
let status = self.handle.status().await?;
let mut payload = status.payload;
enrich_status_payload_identity(&mut payload, status.invite_token.as_deref());
+ if let Ok(identity) = ensure_owner_identity() {
+ payload["ownerId"] = serde_json::Value::String(identity.owner_id);
+ }
Ok(payload)
}
@@ -355,11 +473,60 @@ fn mesh_port_from_env(name: &str, default: u16) -> anyhow::Result {
Ok(port)
}
+/// Parsed value of `BUZZ_MESH_IROH_RELAYS` (see the const doc).
+#[derive(Debug, Clone, PartialEq, Eq)]
+enum IrohRelayMode {
+ /// Direct QUIC only — no relay servers in the iroh endpoint (default).
+ Disabled,
+ /// Enable iroh's default relay servers for NAT tunneling.
+ Default,
+ /// Enable specific iroh relay URLs.
+ Custom(Vec),
+}
+
+fn iroh_relay_mode() -> IrohRelayMode {
+ iroh_relay_mode_from(std::env::var(MESH_IROH_RELAYS_ENV).ok().as_deref())
+}
+
+fn iroh_relay_mode_from(raw: Option<&str>) -> IrohRelayMode {
+ match raw.map(str::trim) {
+ Some("0") => IrohRelayMode::Disabled,
+ None | Some("") | Some("1") | Some("default") => IrohRelayMode::Default,
+ Some(list) => IrohRelayMode::Custom(
+ list.split(',')
+ .map(str::trim)
+ .filter(|url| !url.is_empty())
+ .map(str::to_string)
+ .collect(),
+ ),
+ }
+}
+
fn relay_mesh_api_base_url() -> Result {
let port = mesh_api_port().map_err(|error| error.to_string())?;
Ok(format!("http://127.0.0.1:{port}/v1"))
}
+/// Normalize a resolved roster for allowlist enforcement: sorted, deduped,
+/// and always containing our own owner id (so a solo sharer can dial their
+/// own node and the first member of a fresh relay isn't locked out).
+/// `None` in = `None` out (no roster resolved → no enforcement).
+fn normalized_roster(
+ trusted_owner_ids: &Option>,
+ identity: &identity::OwnerIdentity,
+) -> Option> {
+ let ids = trusted_owner_ids.as_ref()?;
+ let mut owners: Vec = ids
+ .iter()
+ .map(|id| id.trim().to_string())
+ .filter(|id| !id.is_empty())
+ .collect();
+ owners.push(identity.owner_id.clone());
+ owners.sort();
+ owners.dedup();
+ Some(owners)
+}
+
fn validate_no_leak_request(request: &StartMeshNodeRequest) -> anyhow::Result<()> {
if request.join_token.as_deref().is_some_and(str::is_empty) {
anyhow::bail!("joinToken cannot be empty when provided");
diff --git a/desktop/src-tauri/src/mesh_llm/mod_tests.rs b/desktop/src-tauri/src/mesh_llm/mod_tests.rs
index befcdb1aa5..d5ca53d1df 100644
--- a/desktop/src-tauri/src/mesh_llm/mod_tests.rs
+++ b/desktop/src-tauri/src/mesh_llm/mod_tests.rs
@@ -64,3 +64,110 @@ fn agent_preset_runs_on_buzz_agent_not_goose() {
Some("Qwen3-8B-Q4_K_M")
);
}
+
+#[test]
+fn iroh_relay_mode_defaults_to_enabled() {
+ // Default is ON: unset, empty, "1", and "default" all enable the SDK's
+ // default iroh relays, so members connect regardless of NAT. Relays are
+ // transport-only (ciphertext forwarding) — admission is a separate layer.
+ use super::IrohRelayMode;
+ assert_eq!(super::iroh_relay_mode_from(None), IrohRelayMode::Default);
+ assert_eq!(
+ super::iroh_relay_mode_from(Some("")),
+ IrohRelayMode::Default
+ );
+ assert_eq!(
+ super::iroh_relay_mode_from(Some(" ")),
+ IrohRelayMode::Default
+ );
+ assert_eq!(
+ super::iroh_relay_mode_from(Some("1")),
+ IrohRelayMode::Default
+ );
+ assert_eq!(
+ super::iroh_relay_mode_from(Some("default")),
+ IrohRelayMode::Default
+ );
+}
+
+#[test]
+fn iroh_relay_mode_opt_out_and_custom() {
+ use super::IrohRelayMode;
+ // "0" is the explicit opt-out for metadata-conscious deployments.
+ assert_eq!(
+ super::iroh_relay_mode_from(Some("0")),
+ IrohRelayMode::Disabled
+ );
+ // Anything else is a comma-separated custom relay list.
+ assert_eq!(
+ super::iroh_relay_mode_from(Some("https://relay1.example, https://relay2.example ,")),
+ IrohRelayMode::Custom(vec![
+ "https://relay1.example".to_string(),
+ "https://relay2.example".to_string(),
+ ])
+ );
+}
+
+#[test]
+fn normalized_roster_none_means_no_enforcement() {
+ let identity = super::identity::OwnerIdentity {
+ keystore_path: std::path::PathBuf::from("/tmp/ks.json"),
+ owner_id: "owner-self".to_string(),
+ };
+ assert_eq!(super::normalized_roster(&None, &identity), None);
+}
+
+#[test]
+fn normalized_roster_always_includes_self_and_dedupes() {
+ let identity = super::identity::OwnerIdentity {
+ keystore_path: std::path::PathBuf::from("/tmp/ks.json"),
+ owner_id: "owner-self".to_string(),
+ };
+ // Empty roster (fresh relay, nobody published yet) still admits self —
+ // otherwise the first sharer locks themselves out.
+ assert_eq!(
+ super::normalized_roster(&Some(vec![]), &identity),
+ Some(vec!["owner-self".to_string()])
+ );
+ // Dedup + trim + sorted, self merged in.
+ assert_eq!(
+ super::normalized_roster(
+ &Some(vec![
+ "owner-b".to_string(),
+ " owner-a ".to_string(),
+ "owner-b".to_string(),
+ "".to_string(),
+ "owner-self".to_string(),
+ ]),
+ &identity
+ ),
+ Some(vec![
+ "owner-a".to_string(),
+ "owner-b".to_string(),
+ "owner-self".to_string(),
+ ])
+ );
+}
+
+fn signed_status_event(content: serde_json::Value) -> nostr::Event {
+ let keys = nostr::Keys::generate();
+ nostr::EventBuilder::new(nostr::Kind::Custom(30_621), content.to_string())
+ .sign_with_keys(&keys)
+ .expect("test event signs")
+}
+
+#[test]
+fn owner_ids_from_events_collects_sorted_deduped_roster() {
+ let events = vec![
+ signed_status_event(json!({ "ownerId": "owner-b", "serveTargets": [] })),
+ signed_status_event(json!({ "owner_id": "owner-a" })), // snake_case accepted
+ signed_status_event(json!({ "ownerId": "owner-b" })), // duplicate
+ signed_status_event(json!({ "serveTargets": [] })), // pre-upgrade note: no owner id
+ signed_status_event(json!({ "ownerId": "" })), // empty filtered
+ ];
+ assert_eq!(
+ super::owner_ids_from_events(&events),
+ vec!["owner-a".to_string(), "owner-b".to_string()]
+ );
+ assert_eq!(super::owner_ids_from_events(&[]), Vec::::new());
+}
diff --git a/desktop/src-tauri/src/mesh_llm/progress.rs b/desktop/src-tauri/src/mesh_llm/progress.rs
new file mode 100644
index 0000000000..a98b27c98f
--- /dev/null
+++ b/desktop/src-tauri/src/mesh_llm/progress.rs
@@ -0,0 +1,73 @@
+//! Bridges mesh-llm's process-global output sink onto Tauri events so the
+//! frontend can render model-download progress (bytes, percent) instead of a
+//! frozen, greyed-out toggle. Same pattern as mesh-console's ConsoleSink.
+
+use std::io;
+use std::sync::Arc;
+
+use serde::Serialize;
+use tauri::{AppHandle, Emitter};
+
+use mesh_llm_events::{ConsoleSessionMode, ModelProgressStatus, OutputEvent, OutputSink};
+
+/// Tauri event name the frontend subscribes to.
+pub const MESH_DOWNLOAD_PROGRESS_EVENT: &str = "mesh-download-progress";
+
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MeshDownloadProgress {
+ /// Model (or runtime) label being downloaded.
+ pub label: String,
+ /// Specific file within the download, when known.
+ pub file: Option,
+ pub downloaded_bytes: Option,
+ pub total_bytes: Option,
+ /// preparing | downloading | done — mirrors ModelProgressStatus.
+ pub status: &'static str,
+ pub done: bool,
+}
+
+struct TauriProgressSink {
+ app: AppHandle,
+}
+
+impl OutputSink for TauriProgressSink {
+ fn emit_event(&self, event: OutputEvent) -> io::Result<()> {
+ if let OutputEvent::ModelDownloadProgress {
+ label,
+ file,
+ downloaded_bytes,
+ total_bytes,
+ status,
+ } = event
+ {
+ let payload = MeshDownloadProgress {
+ label,
+ file,
+ downloaded_bytes,
+ total_bytes,
+ status: match status {
+ ModelProgressStatus::Ensuring => "preparing",
+ ModelProgressStatus::Downloading => "downloading",
+ ModelProgressStatus::Ready => "done",
+ },
+ done: matches!(status, ModelProgressStatus::Ready),
+ };
+ let _ = self.app.emit(MESH_DOWNLOAD_PROGRESS_EVENT, payload);
+ }
+ Ok(())
+ }
+
+ /// Byte-level ModelDownloadProgress only flows through the sink when the
+ /// host-runtime believes an interactive dashboard is attached; otherwise
+ /// it draws ANSI progress bars on stderr. Our UI *is* the dashboard.
+ fn console_session_mode(&self) -> Option {
+ Some(ConsoleSessionMode::InteractiveDashboard)
+ }
+}
+
+/// Install (or replace) the process-global progress sink pointed at this app.
+/// Idempotent in effect — replacing with an equivalent sink is harmless.
+pub fn install_progress_sink(app: &AppHandle) {
+ mesh_llm_events::set_output_sink(Arc::new(TauriProgressSink { app: app.clone() }));
+}
diff --git a/desktop/src-tauri/src/mesh_llm_stubs.rs b/desktop/src-tauri/src/mesh_llm_stubs.rs
index 318be3c583..22f325aa4a 100644
--- a/desktop/src-tauri/src/mesh_llm_stubs.rs
+++ b/desktop/src-tauri/src/mesh_llm_stubs.rs
@@ -55,6 +55,11 @@ pub async fn mesh_installed_models(
Err("mesh-llm feature not enabled".to_string())
}
+#[tauri::command]
+pub async fn mesh_model_catalog() -> CmdResult {
+ Err("mesh-llm feature not enabled".to_string())
+}
+
#[tauri::command]
pub fn mesh_agent_preset(_request: serde_json::Value) -> CmdResult {
Err("mesh-llm feature not enabled".to_string())
diff --git a/desktop/src/features/mesh-compute/hooks/useMeshDownloadProgress.ts b/desktop/src/features/mesh-compute/hooks/useMeshDownloadProgress.ts
new file mode 100644
index 0000000000..cf76093f40
--- /dev/null
+++ b/desktop/src/features/mesh-compute/hooks/useMeshDownloadProgress.ts
@@ -0,0 +1,74 @@
+import * as React from "react";
+import { listen } from "@tauri-apps/api/event";
+
+/** Mirror of the Rust MeshDownloadProgress payload (mesh_llm/progress.rs). */
+export type MeshDownloadProgress = {
+ label: string;
+ file: string | null;
+ downloadedBytes: number | null;
+ totalBytes: number | null;
+ /** preparing | downloading | done */
+ status: "preparing" | "downloading" | "done";
+ done: boolean;
+};
+
+/**
+ * Live model-download progress from the backend's mesh output sink.
+ * Returns the latest event while a download is active, `null` when idle or
+ * after completion. `reset()` clears a lingering final event (call it when a
+ * start action settles).
+ */
+export function useMeshDownloadProgress(): {
+ progress: MeshDownloadProgress | null;
+ reset: () => void;
+} {
+ const [progress, setProgress] = React.useState(
+ null,
+ );
+
+ React.useEffect(() => {
+ let cancelled = false;
+ let unlisten: (() => void) | null = null;
+ (async () => {
+ try {
+ const stop = await listen(
+ "mesh-download-progress",
+ (event) => {
+ if (cancelled) return;
+ setProgress(event.payload.done ? null : event.payload);
+ },
+ );
+ if (cancelled) {
+ stop();
+ } else {
+ unlisten = stop;
+ }
+ } catch {
+ // Event system unavailable (web/e2e) — progress just doesn't render.
+ }
+ })();
+ return () => {
+ cancelled = true;
+ unlisten?.();
+ };
+ }, []);
+
+ const reset = React.useCallback(() => setProgress(null), []);
+ return { progress, reset };
+}
+
+/** "2.1 GB of 5.0 GB" style formatting; tolerates unknown totals. */
+export function formatDownloadBytes(p: MeshDownloadProgress): string {
+ const gb = (n: number) => `${(n / 1e9).toFixed(1)} GB`;
+ if (p.downloadedBytes == null) return "";
+ if (p.totalBytes == null || p.totalBytes === 0) return gb(p.downloadedBytes);
+ return `${gb(p.downloadedBytes)} of ${gb(p.totalBytes)}`;
+}
+
+/** 0..100 or null when the total is unknown. */
+export function downloadPercent(p: MeshDownloadProgress): number | null {
+ if (p.downloadedBytes == null || p.totalBytes == null || p.totalBytes === 0) {
+ return null;
+ }
+ return Math.min(100, Math.round((p.downloadedBytes / p.totalBytes) * 100));
+}
diff --git a/desktop/src/features/mesh-compute/ui/MeshComputeSettingsCard.tsx b/desktop/src/features/mesh-compute/ui/MeshComputeSettingsCard.tsx
index 9ad4121ce4..88f18a7a42 100644
--- a/desktop/src/features/mesh-compute/ui/MeshComputeSettingsCard.tsx
+++ b/desktop/src/features/mesh-compute/ui/MeshComputeSettingsCard.tsx
@@ -9,14 +9,25 @@ import {
meshStartNode,
meshStopNode,
meshInstalledModels,
+ meshModelCatalog,
+} from "@/shared/api/tauriMesh";
+import type {
+ MeshCatalogEntry,
+ MeshModelCatalog,
+ MeshModelOption,
+ MeshNodeStatus,
} from "@/shared/api/tauriMesh";
-import type { MeshModelOption, MeshNodeStatus } from "@/shared/api/tauriMesh";
import {
SettingsOptionGroup,
SettingsOptionRow,
} from "@/features/settings/ui/SettingsOptionGroup";
import { SettingsSectionHeader } from "@/features/settings/ui/SettingsSectionHeader";
import { classifyModelRef, modelRefHintLabel } from "../classifyModelRef";
+import {
+ downloadPercent,
+ formatDownloadBytes,
+ useMeshDownloadProgress,
+} from "../hooks/useMeshDownloadProgress";
import { useMeshNodeStatus } from "../hooks/useMeshNodeStatus";
const MODEL_DRAFT_STORAGE_KEY = "buzz.mesh-compute.share.model.v1";
@@ -59,6 +70,7 @@ export function MeshComputeSettingsCard() {
const [installedModels, setInstalledModels] = React.useState<
MeshModelOption[]
>([]);
+ const [catalog, setCatalog] = React.useState(null);
const [modelInput, setModelInput] = React.useState(() =>
readDraft(MODEL_DRAFT_STORAGE_KEY),
);
@@ -68,6 +80,8 @@ export function MeshComputeSettingsCard() {
const [advancedOpen, setAdvancedOpen] = React.useState(false);
const [actionInFlight, setActionInFlight] = React.useState(false);
const [actionError, setActionError] = React.useState(null);
+ const { progress: downloadProgress, reset: resetDownloadProgress } =
+ useMeshDownloadProgress();
// Fetch installed models. Called on mount and whenever the running state
// changes (a fresh start may have downloaded a new model). Stale-tolerant —
@@ -90,6 +104,31 @@ export function MeshComputeSettingsCard() {
// biome-ignore lint/correctness/useExhaustiveDependencies: status?.state is the intentional trigger — re-fetch installed models when the node transitions (a fresh start may have downloaded a new model)
React.useEffect(() => refreshInstalled(), [refreshInstalled, status?.state]);
+ // One-shot hardware-aware catalog fetch. Purely additive: when it fails
+ // (stub build, survey error) the card falls back to the free-text field.
+ // When the field is empty, pre-fill the recommended model — a real value
+ // in the field, not ghost placeholder text pretending to be a suggestion.
+ React.useEffect(() => {
+ let cancelled = false;
+ (async () => {
+ try {
+ const value = await meshModelCatalog();
+ if (cancelled) return;
+ setCatalog(value);
+ setModelInput((current) => {
+ if (current !== "" || !value.recommended) return current;
+ writeDraft(MODEL_DRAFT_STORAGE_KEY, value.recommended);
+ return value.recommended;
+ });
+ } catch {
+ // Non-fatal — picker just doesn't render.
+ }
+ })();
+ return () => {
+ cancelled = true;
+ };
+ }, []);
+
// Mirror the running node's modelId back into the field so the card shows
// what's actually being served, even after a fresh app load.
React.useEffect(() => {
@@ -131,6 +170,7 @@ export function MeshComputeSettingsCard() {
setActionError(err instanceof Error ? err.message : String(err));
} finally {
setActionInFlight(false);
+ resetDownloadProgress();
}
}
@@ -156,6 +196,9 @@ export function MeshComputeSettingsCard() {
{actionError}
) : null}
+ {downloadProgress ? (
+
+ ) : null}
@@ -207,6 +250,17 @@ export function MeshComputeSettingsCard() {
Catalog name, HuggingFace ref, or a local file path.
)}
+ {catalog && catalog.entries.length > 0 ? (
+ {
+ setModelInput(name);
+ writeDraft(MODEL_DRAFT_STORAGE_KEY, name);
+ }}
+ selected={modelInput.trim()}
+ />
+ ) : null}
{installedModels.length > 0 ? (
@@ -300,6 +354,149 @@ export function MeshComputeSettingsCard() {
* `health` matrix to honest copy — no "starting…" stuck forever when mesh
* is actually downloading weights or has failed.
*/
+/**
+ * Live model-download progress: name, bytes, percent bar. Rendered above the
+ * option group while the backend streams mesh-download-progress events —
+ * the answer to "it just greys out while downloading".
+ */
+function DownloadProgressBar({
+ progress,
+}: {
+ progress: NonNullable["progress"]>;
+}) {
+ const percent = downloadPercent(progress);
+ const bytes = formatDownloadBytes(progress);
+ return (
+
+
+
+ {progress.status === "preparing" ? "Preparing" : "Downloading"}{" "}
+ {progress.label}
+
+
+ {percent != null ? `${percent}%` : bytes || "…"}
+
+
+ {bytes && percent != null ? (
+
+ {bytes}
+
+ ) : null}
+
+
+ );
+}
+
+const FIT_LABEL: Record = {
+ comfortable: "Fits well",
+ tight: "Tight fit",
+ tradeoff: "Trade-off",
+ too_large: "Too large",
+};
+
+const FIT_CLASS: Record = {
+ comfortable: "text-green-600 dark:text-green-400",
+ tight: "text-amber-600 dark:text-amber-400",
+ tradeoff: "text-orange-600 dark:text-orange-400",
+ too_large: "text-destructive",
+};
+
+/**
+ * Hardware-ranked curated model list (mesh-console's diagnose pattern).
+ * Click a row to fill the model field. Models too large for this machine are
+ * listed but disabled — honest about why, instead of hiding them.
+ */
+function CatalogPicker({
+ catalog,
+ disabled,
+ onPick,
+ selected,
+}: {
+ catalog: MeshModelCatalog;
+ disabled: boolean;
+ onPick: (name: string) => void;
+ selected: string;
+}) {
+ const [expanded, setExpanded] = React.useState(false);
+ // Collapsed: recommended + the next few viable entries. Expanded: all.
+ const visible = expanded ? catalog.entries : catalog.entries.slice(0, 4);
+ return (
+
+
+ Suggested for this machine
+ {catalog.gpuName ? ` (${catalog.gpuName}, ` : " ("}
+ {catalog.vramDisplay} AI memory):
+
+
+ {visible.map((entry) => {
+ const isSelected = entry.name === selected;
+ const tooLarge = entry.fit === "too_large";
+ return (
+
+ onPick(entry.name)}
+ title={entry.description}
+ type="button"
+ >
+
+ {entry.name}
+
+
+ {entry.size}
+
+
+ {FIT_LABEL[entry.fit]}
+
+ {entry.recommended ? (
+
+ Recommended
+
+ ) : null}
+ {entry.installed ? (
+
+ Installed
+
+ ) : null}
+
+
+ );
+ })}
+
+ {catalog.entries.length > visible.length || expanded ? (
+
setExpanded((v) => !v)}
+ type="button"
+ >
+ {expanded
+ ? "Show fewer"
+ : `Show all ${catalog.entries.length} models`}
+
+ ) : null}
+
+ );
+}
+
function StatusLine({ status }: { status: MeshNodeStatus | null }) {
if (!status) {
return Loading…
;
diff --git a/desktop/src/shared/api/tauriMesh.ts b/desktop/src/shared/api/tauriMesh.ts
index 8f22d563c5..e7c91d6e1c 100644
--- a/desktop/src/shared/api/tauriMesh.ts
+++ b/desktop/src/shared/api/tauriMesh.ts
@@ -141,6 +141,37 @@ export async function meshInstalledModels(): Promise {
return await invokeTauri("mesh_installed_models");
}
+export type MeshModelFit = "comfortable" | "tight" | "tradeoff" | "too_large";
+
+export type MeshCatalogEntry = {
+ /** Catalog name — valid as-is in the model field. */
+ name: string;
+ /** Display size, e.g. "5.0GB". */
+ size: string;
+ sizeGb: number;
+ description: string;
+ fit: MeshModelFit;
+ installed: boolean;
+ recommended: boolean;
+};
+
+export type MeshModelCatalog = {
+ gpuName: string | null;
+ vramDisplay: string;
+ vramGb: number;
+ recommended: string | null;
+ /** Ranked: recommended first, then by fit, then larger first within a fit. */
+ entries: MeshCatalogEntry[];
+};
+
+/**
+ * Hardware-aware curated model catalog for the Share-compute picker.
+ * Works without a running mesh node (hardware survey + HF cache scan).
+ */
+export async function meshModelCatalog(): Promise {
+ return await invokeTauri("mesh_model_catalog");
+}
+
export async function meshAgentPreset(
modelId: string,
): Promise {
diff --git a/desktop/src/testing/e2eBridge.ts b/desktop/src/testing/e2eBridge.ts
index 37443a0dc4..47922816c8 100644
--- a/desktop/src/testing/e2eBridge.ts
+++ b/desktop/src/testing/e2eBridge.ts
@@ -7945,6 +7945,33 @@ export function maybeInstallE2eTauriMocks() {
};
case "mesh_installed_models":
return mockMeshState.models;
+ case "mesh_model_catalog":
+ return {
+ gpuName: "Mock GPU",
+ vramDisplay: "96 GB",
+ vramGb: 96,
+ recommended: "Qwen3-8B-Q4_K_M",
+ entries: [
+ {
+ name: "Qwen3-8B-Q4_K_M",
+ size: "5.0GB",
+ sizeGb: 5.0,
+ description: "Mock recommended model",
+ fit: "comfortable",
+ installed: true,
+ recommended: true,
+ },
+ {
+ name: "Qwen3-4B-Q4_K_M",
+ size: "2.5GB",
+ sizeGb: 2.5,
+ description: "Mock small model",
+ fit: "comfortable",
+ installed: false,
+ recommended: false,
+ },
+ ],
+ };
case "mesh_node_status":
return meshNodeStatus(mockMeshState.nodeState, mockMeshState.nodeMode);
case "mesh_start_node": {
diff --git a/docs/mesh-llm-local-build.md b/docs/mesh-llm-local-build.md
index 4c466d68e6..a5fe27b604 100644
--- a/docs/mesh-llm-local-build.md
+++ b/docs/mesh-llm-local-build.md
@@ -58,26 +58,30 @@ Do not use dynamic-link locally unless you already have compatible `llama`,
`llama-common`, and `mtmd` dynamic libraries. The default static build is the
supported local path for M1.
-## Connectivity model: public iroh relays off, raw STUN on (WAN)
-
-Buzz Desktop starts the embedded mesh node with `disable_iroh_relays(true)`
-(mesh-llm fork rev `bc2f1106`, `RelayPolicy::ExplicitlyDisabled`): **no public
-iroh relays** (no `*.iroh.link` traffic, no relay transport), so there is no
-empty-relay fallback to public infrastructure.
-
-Raw STUN **remains on** under this policy: the node discovers its public address
-(via `stun.l.google.com` / `stun.cloudflare.com`) and injects it into the invite
-token / `EndpointAddr`. That address rides the relay-signed `24621`/`24622`
-call-me-now exchange, and peers hole-punch directly over UDP — so this works over
-**WAN**, not just LAN. STUN is a "what's my public IP" lookup, not a relay or a
-data path; the Buzz relay performs the address-exchange coordination.
-
-Residual limit (intentional v1): with iroh relays off there is **no relay
-transport fallback**, so two peers both behind **symmetric NATs** may fail to
-hole-punch. Works for the common cases (≥1 side cone-NAT / port-forwarded /
-server). A hosted private-iroh-relay fallback (relay advertises an
-`iroh_relay_url` + NIP-98 auth) is the planned follow-up once the relay side is
-wired end-to-end.
+## Connectivity model: iroh relay tunneling on by default, raw STUN on (WAN)
+
+Buzz Desktop starts the embedded mesh node with iroh's **default relay
+servers enabled** (`BUZZ_MESH_IROH_RELAYS`, default on). Peers first attempt
+a direct connection — the node discovers its public address via raw STUN
+(`stun.l.google.com` / `stun.cloudflare.com`), injects it into the invite
+token / `EndpointAddr`, and both sides hole-punch over UDP after the
+relay-signed `24621`/`24622` call-me-now exchange. When hole-punching fails
+(e.g. both peers behind symmetric NATs), traffic falls back to an iroh relay
+tunnel; iroh keeps probing and upgrades to a direct path when one appears.
+
+Iroh relays are **transport-only**: they forward end-to-end encrypted QUIC
+(ciphertext), perform no admission, and are unrelated to the Buzz relay
+(which does identity, membership, and matchmaking). Mesh presence is never
+published to public Nostr relays — `publish(false)` is hardcoded and the
+node's Nostr relay list stays empty regardless of this setting.
+
+`BUZZ_MESH_IROH_RELAYS=0` disables relay transport entirely (direct QUIC
+only) for metadata-conscious deployments; a comma-separated URL list selects
+custom (e.g. self-hosted) iroh relays instead of the defaults.
+
+Because reachability is no longer a de-facto gate, membership enforcement is
+the mesh admission layer's job (owner allowlist derived from relay
+membership) — see the admission section / roadmap.
## Mesh-compute e2e acceptance matrix