diff --git a/Cargo.lock b/Cargo.lock index bcb25cae..57da983b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,6 +245,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -731,6 +737,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bufstream" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" + [[package]] name = "bumpalo" version = "3.19.0" @@ -873,7 +885,7 @@ version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn", @@ -2032,6 +2044,12 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -2201,8 +2219,8 @@ dependencies = [ "http 1.3.1", "hyper 1.7.0", "hyper-util", - "rustls", - "rustls-native-certs", + "rustls 0.23.34", + "rustls-native-certs 0.8.2", "rustls-pki-types", "tokio", "tokio-rustls", @@ -2486,6 +2504,32 @@ dependencies = [ "zune-jpeg", ] +[[package]] +name = "imap" +version = "3.0.0-alpha.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b81eb9a89c9a40e9d6c670d9b3c4cda734573592bd49b7cd906152c95d9af2" +dependencies = [ + "base64 0.22.1", + "bufstream", + "chrono", + "imap-proto", + "lazy_static", + "nom", + "ouroboros", + "regex", + "rustls-connector", +] + +[[package]] +name = "imap-proto" +version = "0.16.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1f9b30846c3d04371159ef3a0413ce7c1ae0a8c619cd255c60b3d902553f22" +dependencies = [ + "nom", +] + [[package]] name = "impl-more" version = "0.1.9" @@ -2776,6 +2820,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "mail-parser" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93c3b9e5d8b17faf573330bbc43b37d6e918c0a3bf8a88e7d0a220ebc84af9fc" +dependencies = [ + "encoding_rs", +] + [[package]] name = "matchers" version = "0.2.0" @@ -2965,11 +3018,14 @@ dependencies = [ "chrono", "clap", "home", + "imap", "nocodo-llm-sdk", "nocodo-tools", "refinery", "regex", + "rpassword", "rusqlite", + "rustls-connector", "schemars 0.8.22", "serde", "serde_json", @@ -3041,9 +3097,13 @@ dependencies = [ "codex-process-hardening", "glob", "home", + "imap", + "imap-proto", + "mail-parser", "regex", "reqwest 0.12.24", "rusqlite", + "rustls-connector", "schemars 0.8.22", "serde", "serde_json", @@ -3410,6 +3470,30 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ouroboros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + [[package]] name = "parking" version = "2.2.1" @@ -3653,6 +3737,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + [[package]] name = "process-wrap" version = "8.2.1" @@ -3720,7 +3817,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", - "rustls", + "rustls 0.23.34", "socket2 0.6.1", "thiserror 2.0.17", "tokio", @@ -3740,7 +3837,7 @@ dependencies = [ "rand 0.9.2", "ring", "rustc-hash 2.1.1", - "rustls", + "rustls 0.23.34", "rustls-pki-types", "slab", "thiserror 2.0.17", @@ -3990,7 +4087,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -4035,8 +4132,8 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls", - "rustls-native-certs", + "rustls 0.23.34", + "rustls-native-certs 0.8.2", "rustls-pki-types", "serde", "serde_json", @@ -4130,6 +4227,27 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "rpassword" +version = "7.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d4c8b64f049c6721ec8ccec37ddfc3d641c4a7fca57e8f2a89de509c73df39" +dependencies = [ + "libc", + "rtoolbox", + "windows-sys 0.59.0", +] + +[[package]] +name = "rtoolbox" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cc970b249fbe527d6e02e0a227762c9108b2f49d81094fe357ffc6d14d7f6f" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "rusqlite" version = "0.37.0" @@ -4192,6 +4310,20 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls" version = "0.23.34" @@ -4201,11 +4333,37 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.7", "subtle", "zeroize", ] +[[package]] +name = "rustls-connector" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5bd40675c79c896f46d0031bf64c448b35e583dd2bc949751ddd800351e453a" +dependencies = [ + "log", + "rustls 0.22.4", + "rustls-native-certs 0.7.3", + "rustls-pki-types", + "rustls-webpki 0.102.8", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "schannel", + "security-framework 2.11.1", +] + [[package]] name = "rustls-native-certs" version = "0.8.2" @@ -4227,6 +4385,15 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" version = "1.12.0" @@ -4237,6 +4404,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.7" @@ -4750,7 +4928,7 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn", @@ -5081,7 +5259,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls", + "rustls 0.23.34", "tokio", ] @@ -6301,6 +6479,12 @@ dependencies = [ "hashlink 0.8.4", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yoke" version = "0.8.0" diff --git a/gui/api-types/types.ts b/gui/api-types/types.ts index 8f2e7afe..d62952df 100644 --- a/gui/api-types/types.ts +++ b/gui/api-types/types.ts @@ -47,6 +47,16 @@ export type SettingsManagementAgentConfig = { agent_schemas: Array; }; +/** + * Configuration for IMAP Email agent + */ +export type ImapAgentConfig = { + host: string; + port: number; + username: string; + password: string; +}; + /** * Schema describing all settings an agent needs */ @@ -85,7 +95,8 @@ export type AgentConfig = | ({ type: 'tesseract' } & TesseractAgentConfig) | ({ type: 'structured-json' } & StructuredJsonAgentConfig) | ({ type: 'requirements-gathering' } & RequirementsGatheringAgentConfig) - | ({ type: 'settings-management' } & SettingsManagementAgentConfig); + | ({ type: 'settings-management' } & SettingsManagementAgentConfig) + | ({ type: 'imap' } & ImapAgentConfig); /** * Generic agent execution request with type-safe config diff --git a/gui/src/pages/Agents.tsx b/gui/src/pages/Agents.tsx index 46ee52b5..61471974 100644 --- a/gui/src/pages/Agents.tsx +++ b/gui/src/pages/Agents.tsx @@ -6,6 +6,7 @@ import type { AgentConfig, AgentExecutionRequest, AgentExecutionResponse, + ImapAgentConfig, SettingsManagementAgentConfig, } from '../../api-types/types'; @@ -24,6 +25,10 @@ const Agents: Component = () => { const [typeNames, setTypeNames] = createSignal(''); const [domainDescription, setDomainDescription] = createSignal(''); const [settingsFilePath, setSettingsFilePath] = createSignal(''); + const [imapHost, setImapHost] = createSignal(''); + const [imapPort, setImapPort] = createSignal('993'); + const [imapUsername, setImapUsername] = createSignal(''); + const [imapPassword, setImapPassword] = createSignal(''); onMount(async () => { try { @@ -124,6 +129,28 @@ const Agents: Component = () => { agent_schemas: [], }; endpoint = 'http://127.0.0.1:8080/agents/settings-management/execute'; + } else if (agentId === 'imap') { + if (!imapHost().trim()) { + throw new Error('Please enter an IMAP server host'); + } + if (!imapUsername().trim()) { + throw new Error('Please enter an IMAP username'); + } + if (!imapPassword().trim()) { + throw new Error('Please enter an IMAP password'); + } + const port = parseInt(imapPort(), 10); + if (isNaN(port) || port <= 0 || port > 65535) { + throw new Error('Please enter a valid port number (1-65535)'); + } + config = { + type: 'imap', + host: imapHost(), + port: port, + username: imapUsername(), + password: imapPassword(), + }; + endpoint = 'http://127.0.0.1:8080/agents/imap/execute'; } else { throw new Error('Unknown agent type'); } @@ -303,6 +330,61 @@ const Agents: Component = () => { + +
+ + setImapHost(e.currentTarget.value)} + disabled={executing()} + /> +
+
+ + setImapPort(e.currentTarget.value)} + disabled={executing()} + /> +
+
+ + setImapUsername(e.currentTarget.value)} + disabled={executing()} + /> +
+
+ + setImapPassword(e.currentTarget.value)} + disabled={executing()} + /> +
+
+