From 7cf24c66f5df8dafaacc6cc51b646a93a3b9f9ce Mon Sep 17 00:00:00 2001 From: Weekendsuperhero <4048475+WeekendSuperhero@users.noreply.github.com> Date: Tue, 24 Mar 2026 03:06:45 -0700 Subject: [PATCH 1/4] updated all files to use hashbrown::Hashbrown --- crates/agentmail/Cargo.toml | 6 ++++-- crates/agentmail/src/config.rs | 2 +- crates/agentmail/src/connection.rs | 2 +- crates/agentmail/src/imap_client.rs | 4 ++-- crates/agentmail/src/lib.rs | 6 +++--- crates/agentmail/src/parser.rs | 2 +- crates/agentmail/src/types.rs | 3 ++- 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/crates/agentmail/Cargo.toml b/crates/agentmail/Cargo.toml index 2999ad7..3ffb682 100644 --- a/crates/agentmail/Cargo.toml +++ b/crates/agentmail/Cargo.toml @@ -8,7 +8,7 @@ repository = "https://github.com/weekendsuperhero-io/agentmail" documentation = "https://docs.rs/agentmail" homepage = "https://github.com/weekendsuperhero-io/agentmail" readme = "../../README.md" -keywords = ["email", "imap", "mail", "mcp", "agent"] +keywords = ["agent", "email", "imap", "mail", "mcp"] categories = ["email", "network-programming"] authors = ["WeekendSuperhero "] rust-version = "1.94" @@ -26,6 +26,8 @@ dirs = "6" fast_html2md = "0.0" # Async utilities futures = "0.3" +# Fast hash map (SwissTable) +hashbrown = { version = "0.16", features = ["rayon", "serde"] } # RFC822 message composition (for drafts) lettre = { version = "0.11", default-features = false, features = ["builder"] } # Email parsing from raw RFC822 @@ -33,6 +35,7 @@ mail-parser = "0.11" native-tls = "0.2" # HTTP client (for RFC 8058 one-click unsubscribe) reqwest = { version = "0.13", features = ["json"] } +schemars = { version = "1.2", features = ["chrono04"] } # Credential storage (raw, shell command, or system keyring) secret-lib = { version = "1", features = [ "command", @@ -41,7 +44,6 @@ secret-lib = { version = "1", features = [ "rustls", "tokio" ] } -schemars = { version = "1.2", features = ["chrono04"] } serde = { version = "1", features = ["derive"] } serde_json = "1" # Error handling diff --git a/crates/agentmail/src/config.rs b/crates/agentmail/src/config.rs index 96e3e9d..dbc2240 100644 --- a/crates/agentmail/src/config.rs +++ b/crates/agentmail/src/config.rs @@ -1,6 +1,6 @@ use secret::Secret; use serde::Deserialize; -use std::collections::HashMap; +use hashbrown::HashMap; use std::path::PathBuf; /// Top-level configuration file. diff --git a/crates/agentmail/src/connection.rs b/crates/agentmail/src/connection.rs index 9c7b6a5..3a91fc8 100644 --- a/crates/agentmail/src/connection.rs +++ b/crates/agentmail/src/connection.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use hashbrown::HashMap; use std::sync::Arc; use tokio::sync::{Mutex, OwnedSemaphorePermit, Semaphore}; diff --git a/crates/agentmail/src/imap_client.rs b/crates/agentmail/src/imap_client.rs index 52eaaae..7861bcb 100644 --- a/crates/agentmail/src/imap_client.rs +++ b/crates/agentmail/src/imap_client.rs @@ -1005,8 +1005,8 @@ pub async fn fetch_flags( let uids_raw = imap_timeout(session.uid_search("ALL")).await?; let uids: Vec = uids_raw.into_iter().collect(); let total = uids.len() as u64; - let mut flag_counts: std::collections::HashMap = std::collections::HashMap::new(); - let mut color_counts: std::collections::HashMap = std::collections::HashMap::new(); + let mut flag_counts: hashbrown::HashMap = hashbrown::HashMap::new(); + let mut color_counts: hashbrown::HashMap = hashbrown::HashMap::new(); let mut completed = 0u64; for chunk in uids.chunks(1000) { diff --git a/crates/agentmail/src/lib.rs b/crates/agentmail/src/lib.rs index 4f5d1f9..0c2187c 100644 --- a/crates/agentmail/src/lib.rs +++ b/crates/agentmail/src/lib.rs @@ -290,7 +290,7 @@ impl Agentmail { None => list_scannable_mailbox_names(session.session()).await?, }; - use std::collections::HashMap; + use hashbrown::HashMap; // Key by (email, display_name) so "Find My " and // "iCloud " are separate entries. let mut map: HashMap<(String, String), SenderSummary> = HashMap::new(); @@ -379,7 +379,7 @@ impl Agentmail { None => list_scannable_mailbox_names(session.session()).await?, }; - use std::collections::HashMap; + use hashbrown::HashMap; use types::ListSummary; // Key by (email, display_name) for exact sender grouping @@ -712,7 +712,7 @@ impl Agentmail { None => list_scannable_mailbox_names(session.session()).await?, }; - use std::collections::HashMap; + use hashbrown::HashMap; let mut total_flags: HashMap = HashMap::new(); let mut total_colors: HashMap = HashMap::new(); let mut per_mailbox = Vec::new(); diff --git a/crates/agentmail/src/parser.rs b/crates/agentmail/src/parser.rs index 83f4cec..2d70c7f 100644 --- a/crates/agentmail/src/parser.rs +++ b/crates/agentmail/src/parser.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use hashbrown::HashMap; use mail_parser::{MessageParser, MimeHeaders}; diff --git a/crates/agentmail/src/types.rs b/crates/agentmail/src/types.rs index 186762d..68b45a9 100644 --- a/crates/agentmail/src/types.rs +++ b/crates/agentmail/src/types.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use hashbrown::HashMap; use chrono::{DateTime, Utc}; use schemars::JsonSchema; @@ -95,6 +95,7 @@ pub struct MessageInfo { // All headers (raw original values) #[serde(skip_serializing_if = "HashMap::is_empty", default)] + #[schemars(with = "std::collections::HashMap>")] pub headers: HashMap>, } From e4d8f84d4b9cd41c405d89827a9543976692abbc Mon Sep 17 00:00:00 2001 From: Weekendsuperhero <4048475+WeekendSuperhero@users.noreply.github.com> Date: Tue, 24 Mar 2026 03:14:33 -0700 Subject: [PATCH 2/4] updated agent mail cargo --- Cargo.lock | 97 +++++++++++++++++++++++++++++++++ Cargo.toml | 19 +++++++ crates/agentmail-mcp/Cargo.toml | 28 ++++------ crates/agentmail/Cargo.toml | 38 ++++--------- 4 files changed, 138 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a251745..da6db3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,7 @@ dependencies = [ "dirs", "fast_html2md", "futures", + "hashbrown 0.16.1", "lettre", "mail-parser", "native-tls", @@ -674,6 +675,25 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -867,6 +887,12 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "email-encoding" version = "0.4.1" @@ -1245,6 +1271,9 @@ dependencies = [ "allocator-api2", "equivalent", "foldhash 0.2.0", + "rayon", + "serde", + "serde_core", ] [[package]] @@ -1769,6 +1798,15 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.29" @@ -2081,6 +2119,29 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + [[package]] name = "pastey" version = "0.2.1" @@ -2477,6 +2538,35 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.5.2" @@ -2780,6 +2870,12 @@ dependencies = [ "syn", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "secret-lib" version = "1.0.0" @@ -3240,6 +3336,7 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", diff --git a/Cargo.toml b/Cargo.toml index 2786b5b..2763101 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,22 @@ [workspace] resolver = "2" members = ["crates/agentmail", "crates/agentmail-mcp"] + +[workspace.dependencies] +agentmail = { path = "crates/agentmail" } +chrono = { version = "0.4", features = ["serde"] } +clap = { version = "4", features = ["derive"] } +dirs = "6" +futures = "0.3" +hashbrown = { version = "0.16", features = ["rayon", "serde"] } +reqwest = { version = "0.13", features = ["json"] } +rmcp = "1.2" +schemars = { version = "1.2", features = ["chrono04"] } +secret-lib = { version = "1", features = ["keyring", "rustls", "tokio"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" +thiserror = "2" +tokio = { version = "1", features = ["full"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +uuid = { version = "1", features = ["v4"] } diff --git a/crates/agentmail-mcp/Cargo.toml b/crates/agentmail-mcp/Cargo.toml index 3701e2a..8ed51cb 100644 --- a/crates/agentmail-mcp/Cargo.toml +++ b/crates/agentmail-mcp/Cargo.toml @@ -22,21 +22,13 @@ name = "agentmail" path = "src/main.rs" [dependencies] -agentmail = { path = "../agentmail" } -clap = { version = "4", features = ["derive"] } -rmcp = { version = "1.2", default-features = true, features = [ - "transport-async-rw", - "transport-worker", -] } -schemars = "1.2" -secret-lib = { version = "1", features = ["keyring", "rustls", "tokio"] } -serde = { version = "1", features = ["derive"] } -serde_json = "1" -tokio = { version = "1", features = [ - "io-std", - "macros", - "rt", - "rt-multi-thread" -] } -tracing-subscriber = { version = "0.3", features = ["env-filter"] } -uuid = { version = "1", features = ["v4"] } +agentmail.workspace = true +clap.workspace = true +rmcp = { workspace = true, features = ["transport-async-rw", "transport-worker"] } +schemars.workspace = true +secret-lib.workspace = true +serde.workspace = true +serde_json.workspace = true +tokio = { workspace = true, features = ["io-std", "macros", "rt", "rt-multi-thread"] } +tracing-subscriber.workspace = true +uuid.workspace = true diff --git a/crates/agentmail/Cargo.toml b/crates/agentmail/Cargo.toml index 3ffb682..d91c3e6 100644 --- a/crates/agentmail/Cargo.toml +++ b/crates/agentmail/Cargo.toml @@ -18,41 +18,27 @@ rust-version = "1.94" async-imap = { version = "0.11", default-features = false, features = [ "runtime-tokio" ] } -# Date/time handling -chrono = { version = "0.4", features = ["serde"] } -# Directory paths -dirs = "6" +chrono.workspace = true +dirs.workspace = true # HTML to markdown conversion fast_html2md = "0.0" -# Async utilities -futures = "0.3" -# Fast hash map (SwissTable) -hashbrown = { version = "0.16", features = ["rayon", "serde"] } +futures.workspace = true +hashbrown.workspace = true # RFC822 message composition (for drafts) lettre = { version = "0.11", default-features = false, features = ["builder"] } # Email parsing from raw RFC822 mail-parser = "0.11" native-tls = "0.2" -# HTTP client (for RFC 8058 one-click unsubscribe) -reqwest = { version = "0.13", features = ["json"] } -schemars = { version = "1.2", features = ["chrono04"] } +reqwest.workspace = true +schemars.workspace = true # Credential storage (raw, shell command, or system keyring) -secret-lib = { version = "1", features = [ - "command", - "derive", - "keyring", - "rustls", - "tokio" -] } -serde = { version = "1", features = ["derive"] } -serde_json = "1" -# Error handling -thiserror = "2" -# Async runtime -tokio = { version = "1", features = ["fs", "net", "rt", "sync", "time"] } +secret-lib = { workspace = true, features = ["command", "derive"] } +serde.workspace = true +serde_json.workspace = true +thiserror.workspace = true +tokio.workspace = true # TLS for IMAP connections (tokio-native) tokio-native-tls = "0.3" # Configuration file parsing toml = "1.1" -# Logging -tracing = "0.1" +tracing.workspace = true From 78f324df786d55bb6ed88daa981d9ab15ab83ac7 Mon Sep 17 00:00:00 2001 From: Weekendsuperhero <4048475+WeekendSuperhero@users.noreply.github.com> Date: Tue, 24 Mar 2026 03:27:25 -0700 Subject: [PATCH 3/4] updated agent mail one more time --- Cargo.toml | 7 +++++++ crates/agentmail/Cargo.toml | 16 +++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2763101..37cdbef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,10 @@ tokio = { version = "1", features = ["full"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } uuid = { version = "1", features = ["v4"] } +async-imap = { version = "0.11", default-features = false } +fast_html2md = "0.0" +lettre = { version = "0.11", default-features = false } +mail-parser = "0.11" +native-tls = "0.2" +tokio-native-tls = "0.3" +toml = "1.1" diff --git a/crates/agentmail/Cargo.toml b/crates/agentmail/Cargo.toml index d91c3e6..a1b468d 100644 --- a/crates/agentmail/Cargo.toml +++ b/crates/agentmail/Cargo.toml @@ -15,20 +15,18 @@ rust-version = "1.94" [dependencies] # IMAP protocol (tokio runtime, no async-std) -async-imap = { version = "0.11", default-features = false, features = [ - "runtime-tokio" -] } +async-imap = { workspace = true, features = ["runtime-tokio"] } chrono.workspace = true dirs.workspace = true # HTML to markdown conversion -fast_html2md = "0.0" +fast_html2md = { workspace = true } futures.workspace = true hashbrown.workspace = true # RFC822 message composition (for drafts) -lettre = { version = "0.11", default-features = false, features = ["builder"] } +lettre = { workspace = true, features = ["builder"] } # Email parsing from raw RFC822 -mail-parser = "0.11" -native-tls = "0.2" +mail-parser = { workspace = true } +native-tls = { workspace = true } reqwest.workspace = true schemars.workspace = true # Credential storage (raw, shell command, or system keyring) @@ -38,7 +36,7 @@ serde_json.workspace = true thiserror.workspace = true tokio.workspace = true # TLS for IMAP connections (tokio-native) -tokio-native-tls = "0.3" +tokio-native-tls = { workspace = true } # Configuration file parsing -toml = "1.1" +toml = { workspace = true } tracing.workspace = true From ed4a336222de6304853265415c946b2dff07f072 Mon Sep 17 00:00:00 2001 From: Weekendsuperhero <4048475+WeekendSuperhero@users.noreply.github.com> Date: Tue, 24 Mar 2026 05:29:50 -0700 Subject: [PATCH 4/4] updated sort order --- crates/agentmail/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/agentmail/src/config.rs b/crates/agentmail/src/config.rs index dbc2240..962ca10 100644 --- a/crates/agentmail/src/config.rs +++ b/crates/agentmail/src/config.rs @@ -1,6 +1,6 @@ +use hashbrown::HashMap; use secret::Secret; use serde::Deserialize; -use hashbrown::HashMap; use std::path::PathBuf; /// Top-level configuration file.