A local-first private AI assistant for everyday use. Runs on-device models with encrypted P2P sync, and supports sharing chats publicly on ATProto.
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: added mDNS discovery but via tickets

madclaws 5b1d846b 3495b96c

+101 -11
+39 -2
Cargo.lock
··· 3 3 version = 4 4 4 5 5 [[package]] 6 + name = "acto" 7 + version = "0.8.0" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "148541f13c28e3e840354ee4d6c99046c10be2c81068bbd23b9e3a38f95a917e" 10 + dependencies = [ 11 + "parking_lot", 12 + "pin-project-lite", 13 + "rustc_version", 14 + "smol_str", 15 + "sync_wrapper", 16 + "tokio", 17 + "tracing", 18 + ] 19 + 20 + [[package]] 6 21 name = "adler2" 7 22 version = "2.0.1" 8 23 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3097 3112 "serde", 3098 3113 "smallvec", 3099 3114 "strum", 3115 + "swarm-discovery", 3100 3116 "sync_wrapper", 3101 3117 "time", 3102 3118 "tokio", ··· 5289 5305 5290 5306 [[package]] 5291 5307 name = "rustls-webpki" 5292 - version = "0.103.9" 5308 + version = "0.103.10" 5293 5309 source = "registry+https://github.com/rust-lang/crates.io-index" 5294 - checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" 5310 + checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" 5295 5311 dependencies = [ 5296 5312 "ring", 5297 5313 "rustls-pki-types", ··· 5731 5747 checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 5732 5748 5733 5749 [[package]] 5750 + name = "smol_str" 5751 + version = "0.1.24" 5752 + source = "registry+https://github.com/rust-lang/crates.io-index" 5753 + checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" 5754 + 5755 + [[package]] 5734 5756 name = "snap" 5735 5757 version = "1.1.1" 5736 5758 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5875 5897 version = "2.6.1" 5876 5898 source = "registry+https://github.com/rust-lang/crates.io-index" 5877 5899 checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 5900 + 5901 + [[package]] 5902 + name = "swarm-discovery" 5903 + version = "0.5.0" 5904 + source = "registry+https://github.com/rust-lang/crates.io-index" 5905 + checksum = "1a5ab62937edac8b23fa40e55a358ea1924245b17fc1eb20d14929c8f11be98d" 5906 + dependencies = [ 5907 + "acto", 5908 + "hickory-proto", 5909 + "rand 0.9.2", 5910 + "socket2 0.6.3", 5911 + "thiserror 2.0.18", 5912 + "tokio", 5913 + "tracing", 5914 + ] 5878 5915 5879 5916 [[package]] 5880 5917 name = "syn"
+1 -1
tiles/Cargo.toml
··· 21 21 rusqlite_migration = "2.4.1" 22 22 uuid = {version = "1.21.0", features = ["v7"]} 23 23 axum = "0.8.8" 24 - iroh = "0.97.0" 24 + iroh = {version = "0.97.0", features = ["address-lookup-mdns"]} 25 25 iroh-ping = "0.9.0" 26 26 iroh-tickets = "0.4.0" 27 27 axum-macros = "0.5.0"
+61 -8
tiles/src/core/network/mod.rs
··· 5 5 io, 6 6 str::FromStr, 7 7 sync::{Arc, Mutex}, 8 + time::Duration, 8 9 }; 9 10 10 11 use anyhow::Result; 11 - use futures_util::TryStreamExt; 12 + use futures_util::{Stream, StreamExt, TryStreamExt}; 12 13 use iroh::{ 13 - Endpoint, EndpointId, SecretKey, 14 + Endpoint, EndpointId, NET_REPORT_TIMEOUT, SecretKey, 15 + address_lookup::{self, mdns}, 14 16 endpoint::{BindError, presets}, 15 17 protocol::Router, 16 18 }; ··· 112 114 return Ok(()); 113 115 } 114 116 let endpoint = create_endpoint(&user).await?; 115 - endpoint.online().await; 117 + let mut is_online = false; 118 + tokio::select! { 119 + _ = endpoint.online() => { 120 + is_online = true; 121 + println!("Yep online") 122 + } 123 + _ = tokio::time::sleep(Duration::from_secs(NET_REPORT_TIMEOUT)) => { 124 + is_online = false; 125 + println!("ur offline") 126 + } 127 + }; 128 + 129 + let mdns = address_lookup::mdns::MdnsAddressLookup::builder().build(endpoint.id())?; 130 + 131 + if !is_online { 132 + endpoint.address_lookup()?.add(mdns.clone()); 133 + // let mut mdns_event = mdns.subscribe().await; 134 + // while let Some(event) = mdns_event.next().await { 135 + // match event { 136 + // mdns::DiscoveryEvent::Discovered { 137 + // endpoint_info, 138 + // last_updated, 139 + // } => { 140 + // println!("peer discoverd {:?}", endpoint_info) 141 + // } 142 + // mdns::DiscoveryEvent::Expired { endpoint_id } => { 143 + // println!("peer left {:?}", endpoint_id) 144 + // } 145 + // } 146 + // } 147 + // mdns_event 148 + }; 116 149 let gossip = Gossip::builder().spawn(endpoint.clone()); 117 150 118 151 let recv_router = Router::builder(endpoint.clone()) ··· 153 186 endpoint.close().await; 154 187 } else { 155 188 let endpoint = create_endpoint(&user).await?; 156 - endpoint.online().await; 189 + let mut is_online = false; 190 + tokio::select! { 191 + _ = endpoint.online() => { 192 + is_online = true; 193 + println!("Yep online") 194 + } 195 + _ = tokio::time::sleep(Duration::from_secs(NET_REPORT_TIMEOUT)) => { 196 + is_online = false; 197 + println!("ur offline") 198 + } 199 + }; 157 200 201 + let mdns = address_lookup::mdns::MdnsAddressLookup::builder().build(endpoint.id())?; 202 + 203 + if !is_online { 204 + endpoint.address_lookup()?.add(mdns.clone()); 205 + } 158 206 let gossip = Gossip::builder().spawn(endpoint.clone()); 159 207 160 208 let recv_router = Router::builder(endpoint.clone()) ··· 164 212 let topic_id = create_topic_id("com.tilesprivacy.tiles.link"); 165 213 166 214 let (sender, receiver) = gossip.subscribe(topic_id, vec![]).await?.split(); 167 - 168 215 let ticket = LinkTicket::new( 169 216 topic_id, 170 217 endpoint.addr(), 171 218 user.user_id.clone(), 172 219 user.username.clone(), 173 220 ); 221 + println!("{:?}", endpoint.addr()); 222 + println!("Link Ticket: {:?}\n", ticket.to_string()); 174 223 175 - println!("Link Ticket: {:?}\n", ticket.to_string()); 176 224 println!( 177 225 "Use this link ticket with `tiles link <ticket>` on the system you want to connect to\n" 178 226 ); ··· 269 317 let signing_key = get_secret_key("tiles", &user.user_id)?; 270 318 271 319 let secret_key = SecretKey::from_bytes(&signing_key); 272 - 320 + let mdns = address_lookup::mdns::MdnsAddressLookup::builder(); 273 321 Endpoint::builder(presets::N0) 322 + // .address_lookup(mdns) 274 323 .secret_key(secret_key) 275 324 .bind() 276 325 .await 277 326 .map_err(<BindError as Into<anyhow::Error>>::into) 278 327 } else { 279 - Endpoint::bind(presets::N0) 328 + let mdns = address_lookup::mdns::MdnsAddressLookup::builder(); 329 + Endpoint::builder(presets::N0) 330 + // .address_lookup(mdns) 331 + .bind() 280 332 .await 281 333 .map_err(<BindError as Into<anyhow::Error>>::into) 282 334 } ··· 293 345 get_did_from_public_key(endpoint_id.as_bytes()) 294 346 } 295 347 348 + // fn subsribe_mdns_events(mdns_events) {} 296 349 //TODO: Add tests, can we get some from iroh reference?