diff --git a/Cargo.lock b/Cargo.lock index 5637b427f8..44214a8019 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,7 +130,7 @@ dependencies = [ "aws-http", "aws-runtime", "aws-smithy-async", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-json", "aws-smithy-runtime", "aws-smithy-runtime-api", @@ -181,9 +181,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -211,22 +211,22 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -246,9 +246,9 @@ dependencies = [ [[package]] name = "arboard" -version = "3.6.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f533f8e0af236ffe5eb979b99381df3258853f00ba2e44b6e1955292c75227" +checksum = "c1df21f715862ede32a0c525ce2ca4d52626bb0007f8c18b87a384503ac33e70" dependencies = [ "clipboard-win", "log", @@ -295,9 +295,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.27" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddb939d66e4ae03cee6091612804ba446b12878410cfa17f785f4dd67d4014e8" +checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4" dependencies = [ "flate2", "futures-core", @@ -331,9 +331,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-config" -version = "1.8.4" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483020b893cdef3d89637e428d588650c71cfae7ea2e6ecbaee4de4ff99fb2dd" +checksum = "455e9fb7743c6f6267eb2830ccc08686fbb3d13c9a689369562fd4d4ef9ea462" dependencies = [ "aws-credential-types", "aws-runtime", @@ -341,7 +341,7 @@ dependencies = [ "aws-sdk-ssooidc", "aws-sdk-sts", "aws-smithy-async", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-json", "aws-smithy-runtime", "aws-smithy-runtime-api", @@ -361,9 +361,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.5" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1541072f81945fa1251f8795ef6c92c4282d74d59f88498ae7d4bf00f0ebdad9" +checksum = "687bc16bc431a8533fe0097c7f0182874767f920989d7260950172ae8e3c4465" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -382,9 +382,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.13.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +checksum = "93fcc8f365936c834db5514fc45aee5b1202d677e6b40e48468aaaa8183ca8c7" dependencies = [ "aws-lc-sys", "zeroize", @@ -392,9 +392,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.30.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +checksum = "61b1d86e7705efe1be1b569bab41d4fa1e14e220b60a160f78de2db687add079" dependencies = [ "bindgen 0.69.5", "cc", @@ -405,14 +405,14 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.5.10" +version = "1.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c034a1bc1d70e16e7f4e4caf7e9f7693e4c9c24cd91cf17c2a0b21abaebc7c8b" +checksum = "4f6c68419d8ba16d9a7463671593c54f81ba58cab466e9b759418da606dcc2e2" dependencies = [ "aws-credential-types", "aws-sigv4", "aws-smithy-async", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-runtime", "aws-smithy-runtime-api", "aws-smithy-types", @@ -429,14 +429,14 @@ dependencies = [ [[package]] name = "aws-sdk-cognitoidentity" -version = "1.80.0" +version = "1.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "606ea1307a8caf6ecddf1d8bbe55b7d1d967c7b6c217d13d5e81c2c8e24e0cf8" +checksum = "2a14e1e7fbff8dccd5ad97c52478c888bd8ccc70206d06b027db2eb4904c4a24" dependencies = [ "aws-credential-types", "aws-runtime", "aws-smithy-async", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-json", "aws-smithy-runtime", "aws-smithy-runtime-api", @@ -451,14 +451,14 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.79.0" +version = "1.73.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a847168f15b46329fa32c7aca4e4f1a2e072f9b422f0adb19756f2e1457f111" +checksum = "b2ac1674cba7872061a29baaf02209fefe499ff034dfd91bd4cc59e4d7741489" dependencies = [ "aws-credential-types", "aws-runtime", "aws-smithy-async", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-json", "aws-smithy-runtime", "aws-smithy-runtime-api", @@ -473,14 +473,14 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.80.0" +version = "1.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b654dd24d65568738593e8239aef279a86a15374ec926ae8714e2d7245f34149" +checksum = "3a6a22f077f5fd3e3c0270d4e1a110346cddf6769e9433eb9e6daceb4ca3b149" dependencies = [ "aws-credential-types", "aws-runtime", "aws-smithy-async", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-json", "aws-smithy-runtime", "aws-smithy-runtime-api", @@ -495,14 +495,14 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.81.0" +version = "1.75.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92ea8a7602321c83615c82b408820ad54280fb026e92de0eeea937342fafa24" +checksum = "e3258fa707f2f585ee3049d9550954b959002abd59176975150a01d5cf38ae3f" dependencies = [ "aws-credential-types", "aws-runtime", "aws-smithy-async", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-json", "aws-smithy-query", "aws-smithy-runtime", @@ -518,12 +518,12 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.3.4" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084c34162187d39e3740cb635acd73c4e3a551a36146ad6fe8883c929c9f876c" +checksum = "ddfb9021f581b71870a17eac25b52335b82211cdc092e02b6876b2bcefa61666" dependencies = [ "aws-credential-types", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-runtime-api", "aws-smithy-types", "bytes", @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "aws-smithy-eventstream" -version = "0.60.10" +version = "0.60.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604c7aec361252b8f1c871a7641d5e0ba3a7f5a586e51b66bc9510a5519594d9" +checksum = "338a3642c399c0a5d157648426110e199ca7fd1c689cc395676b81aa563700c4" dependencies = [ "aws-smithy-types", "bytes", @@ -583,9 +583,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.62.3" +version = "0.62.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4dacf2d38996cf729f55e7a762b30918229917eca115de45dfa8dfb97796c9" +checksum = "99335bec6cdc50a346fda1437f9fefe33abf8c99060739a546a16457f2862ca9" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", @@ -603,17 +603,17 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.0.6" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f108f1ca850f3feef3009bdcc977be201bca9a91058864d9de0684e64514bee0" +checksum = "7f491388e741b7ca73b24130ff464c1478acc34d5b331b7dd0a2ee4643595a15" dependencies = [ "aws-smithy-async", "aws-smithy-protocol-test", "aws-smithy-runtime-api", "aws-smithy-types", "bytes", - "h2 0.3.27", - "h2 0.4.12", + "h2 0.3.26", + "h2 0.4.10", "http 0.2.12", "http 1.3.1", "http-body 0.4.6", @@ -626,7 +626,7 @@ dependencies = [ "indexmap", "pin-project-lite", "rustls 0.21.12", - "rustls 0.23.31", + "rustls 0.23.28", "rustls-native-certs 0.8.1", "rustls-pki-types", "serde", @@ -685,12 +685,12 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.8.6" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e107ce0783019dbff59b3a244aa0c114e4a8c9d93498af9162608cd5474e796" +checksum = "14302f06d1d5b7d333fd819943075b13d27c7700b414f574c3c35859bfb55d5e" dependencies = [ "aws-smithy-async", - "aws-smithy-http 0.62.3", + "aws-smithy-http 0.62.1", "aws-smithy-http-client", "aws-smithy-observability", "aws-smithy-runtime-api", @@ -710,9 +710,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.8.7" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75d52251ed4b9776a3e8487b2a01ac915f73b2da3af8fc1e77e0fce697a550d4" +checksum = "bd8531b6d8882fd8f48f82a9754e682e29dd44cff27154af51fa3eb730f59efb" dependencies = [ "aws-smithy-async", "aws-smithy-types", @@ -775,9 +775,9 @@ dependencies = [ [[package]] name = "aws-types" -version = "1.3.8" +version = "1.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b069d19bf01e46298eaedd7c6f283fe565a59263e53eebec945f3e6398f42390" +checksum = "8a322fec39e4df22777ed3ad8ea868ac2f94cd15e1a55f6ee8d8d6305057689a" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -948,9 +948,9 @@ dependencies = [ [[package]] name = "bm25" -version = "2.3.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84ff0d57042bc263e2ebadb3703424b59b65870902649a2b3d0f4d7ab863244" +checksum = "9874599901ae2aaa19b1485145be2fa4e9af42d1b127672a03a7099ab6350bac" dependencies = [ "cached", "deunicode", @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" [[package]] name = "bytecount" @@ -1001,18 +1001,18 @@ checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" +checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" dependencies = [ "proc-macro2", "quote", @@ -1043,14 +1043,14 @@ dependencies = [ [[package]] name = "cached" -version = "0.56.0" +version = "0.55.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801927ee168e17809ab8901d9f01f700cd7d8d6a6527997fee44e4b0327a253c" +checksum = "b0839c297f8783316fcca9d90344424e968395413f0662a5481f79c6648bbc14" dependencies = [ "ahash", "cached_proc_macro", "cached_proc_macro_types", - "hashbrown 0.15.5", + "hashbrown 0.14.5", "once_cell", "thiserror 2.0.12", "web-time", @@ -1058,9 +1058,9 @@ dependencies = [ [[package]] name = "cached_proc_macro" -version = "0.25.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9225bdcf4e4a9a4c08bf16607908eb2fbf746828d5e0b5e019726dbf6571f201" +checksum = "673992d934f0711b68ebb3e1b79cdc4be31634b37c98f26867ced0438ca5c603" dependencies = [ "darling", "proc-macro2", @@ -1076,9 +1076,9 @@ checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "camino" -version = "1.1.11" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d07aa9a93b00c76f71bc35d598bed923f6d4f3a9ca5c24b7737ae1a292841c0" +checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" dependencies = [ "serde", ] @@ -1095,7 +1095,7 @@ dependencies = [ "memmap2", "num-traits", "num_cpus", - "rand 0.9.2", + "rand 0.9.1", "rand_distr", "rayon", "safetensors", @@ -1131,7 +1131,7 @@ dependencies = [ "candle-nn", "fancy-regex 0.13.0", "num-traits", - "rand 0.9.2", + "rand 0.9.1", "rayon", "serde", "serde_json", @@ -1145,15 +1145,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" -[[package]] -name = "castaway" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" -dependencies = [ - "rustversion", -] - [[package]] name = "cbor-diag" version = "0.1.12" @@ -1175,9 +1166,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.32" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ "jobserver", "libc", @@ -1276,17 +1267,17 @@ dependencies = [ "quote", "r2d2", "r2d2_sqlite", - "rand 0.9.2", + "rand 0.9.1", "regex", "reqwest", "ring", "rusqlite", - "rustls 0.23.31", + "rustls 0.23.28", "rustls-native-certs 0.8.1", "rustls-pemfile 2.2.0", "rustyline", "schemars", - "security-framework 3.3.0", + "security-framework 3.2.0", "semantic_search_client", "semver", "serde", @@ -1300,7 +1291,7 @@ dependencies = [ "skim", "spinners", "strip-ansi-escapes", - "strum 0.27.2", + "strum 0.27.1", "syn 2.0.104", "syntect", "sysinfo", @@ -1392,9 +1383,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.43" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -1402,9 +1393,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.43" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -1417,9 +1408,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.56" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e4efcbb5da11a92e8a609233aa1e8a7d91e38de0be865f016d14700d45a7fd" +checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677" dependencies = [ "clap", ] @@ -1436,9 +1427,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "anstyle", "heck 0.5.0", @@ -1456,9 +1447,9 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "clipboard-win" -version = "5.4.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" dependencies = [ "error-code", ] @@ -1545,21 +1536,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "compact_str" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "serde", - "static_assertions", -] - [[package]] name = "console" version = "0.15.11" @@ -1658,9 +1634,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -1782,9 +1758,9 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "crypto-common" @@ -1841,15 +1817,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "dary_heap" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d2cd9c18b9f454ed67da600630b021a8a80bf33f8c95896ab33aaf1c26b728" -dependencies = [ - "serde", -] - [[package]] name = "data-encoding" version = "2.9.0" @@ -2009,7 +1976,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users 0.5.2", + "redox_users 0.5.0", "windows-sys 0.60.2", ] @@ -2074,9 +2041,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dyn-clone" -version = "1.0.20" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" [[package]] name = "dyn-stack" @@ -2285,7 +2252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", - "rustix 1.0.8", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -2781,9 +2748,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.27" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -2800,9 +2767,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.12" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" dependencies = [ "atomic-waker", "bytes", @@ -2827,7 +2794,7 @@ dependencies = [ "cfg-if", "crunchy", "num-traits", - "rand 0.9.2", + "rand 0.9.1", "rand_distr", ] @@ -2843,9 +2810,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "allocator-api2", "equivalent", @@ -3012,14 +2979,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.27", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.10", + "socket2", "tokio", "tower-service", "tracing", @@ -3035,7 +3002,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.12", + "h2 0.4.10", "http 1.3.1", "http-body 1.0.1", "httparse", @@ -3072,20 +3039,20 @@ dependencies = [ "http 1.3.1", "hyper 1.6.0", "hyper-util", - "rustls 0.23.31", + "rustls 0.23.28", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", "tokio-rustls 0.26.2", "tower-service", - "webpki-roots 1.0.2", + "webpki-roots 1.0.1", ] [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" dependencies = [ "base64 0.22.1", "bytes", @@ -3099,7 +3066,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.0", + "socket2", "tokio", "tower-service", "tracing", @@ -3244,18 +3211,18 @@ dependencies = [ [[package]] name = "indenter" -version = "0.3.4" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.10.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.15.4", "serde", ] @@ -3298,17 +3265,6 @@ dependencies = [ "rustversion", ] -[[package]] -name = "io-uring" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -3359,27 +3315,27 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] [[package]] name = "itertools" -version = "0.13.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itertools" -version = "0.14.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -3486,7 +3442,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-targets 0.53.2", ] [[package]] @@ -3518,13 +3474,12 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.9.1", "libc", - "redox_syscall", ] [[package]] @@ -3576,9 +3531,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "litrs" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "lock_api" @@ -3602,7 +3557,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.15.4", ] [[package]] @@ -3668,9 +3623,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memmap2" -version = "0.9.7" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", "stable_deref_trait", @@ -3788,7 +3743,7 @@ dependencies = [ "hyper 1.6.0", "hyper-util", "log", - "rand 0.9.2", + "rand 0.9.1", "regex", "serde_json", "serde_urlencoded", @@ -4462,9 +4417,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owo-colors" -version = "4.2.2" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" +checksum = "26995317201fa17f3656c36716aed4a7c81743a9634ac4c99c0eeda495db0cec" [[package]] name = "parking_lot" @@ -4531,13 +4486,13 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plist" -version = "1.7.4" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" +checksum = "3d77244ce2d584cd84f6a15f86195b8c9b2a0dfbfd817c09e0464244091a58ed" dependencies = [ "base64 0.22.1", "indexmap", - "quick-xml 0.38.1", + "quick-xml", "serde", "time", ] @@ -4651,9 +4606,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.36" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", "syn 2.0.104", @@ -4692,9 +4647,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.96" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beef09f85ae72cea1ef96ba6870c51e6382ebfa4f0e85b643459331f3daa5be0" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -4802,15 +4757,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "quick-xml" -version = "0.38.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9845d9dccf565065824e69f9f235fafba1587031eda353c1f1561cd6a6be78f4" -dependencies = [ - "memchr", -] - [[package]] name = "quinn" version = "0.11.8" @@ -4823,8 +4769,8 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", - "rustls 0.23.31", - "socket2 0.5.10", + "rustls 0.23.28", + "socket2", "thiserror 2.0.12", "tokio", "tracing", @@ -4840,10 +4786,10 @@ dependencies = [ "bytes", "getrandom 0.3.3", "lru-slab", - "rand 0.9.2", + "rand 0.9.1", "ring", "rustc-hash 2.1.1", - "rustls 0.23.31", + "rustls 0.23.28", "rustls-pki-types", "slab", "thiserror 2.0.12", @@ -4861,7 +4807,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2", "tracing", "windows-sys 0.59.0", ] @@ -4926,9 +4872,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", @@ -4979,7 +4925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" dependencies = [ "num-traits", - "rand 0.9.2", + "rand 0.9.1", ] [[package]] @@ -5012,12 +4958,12 @@ dependencies = [ [[package]] name = "rayon-cond" -version = "0.4.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964d0cf57a3e7a06e8183d14a8b527195c706b7983549cd5462d5aa3747438f" +checksum = "059f538b55efd2309c9794130bc149c6a553db90e9d99c2030785c82f0bd7df9" dependencies = [ "either", - "itertools 0.14.0", + "itertools 0.11.0", "rayon", ] @@ -5039,9 +4985,9 @@ checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ "bitflags 2.9.1", ] @@ -5059,9 +5005,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.5.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ "getrandom 0.2.16", "libredox", @@ -5154,9 +5100,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.22" +version = "0.12.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" dependencies = [ "async-compression", "base64 0.22.1", @@ -5167,7 +5113,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.12", + "h2 0.4.10", "http 1.3.1", "http-body 1.0.1", "http-body-util", @@ -5180,7 +5126,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.31", + "rustls 0.23.28", "rustls-native-certs 0.8.1", "rustls-pki-types", "serde", @@ -5198,7 +5144,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.2", + "webpki-roots 1.0.1", ] [[package]] @@ -5251,9 +5197,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.26" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -5291,15 +5237,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -5316,16 +5262,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.4", + "rustls-webpki 0.103.3", "subtle", "zeroize", ] @@ -5351,7 +5297,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.3.0", + "security-framework 3.2.0", ] [[package]] @@ -5394,9 +5340,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" dependencies = [ "aws-lc-rs", "ring", @@ -5406,9 +5352,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "rustyline" @@ -5542,9 +5488,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.3.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ "bitflags 2.9.1", "core-foundation 0.10.1", @@ -5648,9 +5594,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "indexmap", "itoa", @@ -5784,9 +5730,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] @@ -5821,7 +5767,7 @@ dependencies = [ "indexmap", "log", "nix 0.29.0", - "rand 0.9.2", + "rand 0.9.1", "rayon", "regex", "shell-quote", @@ -5856,16 +5802,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "socket2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - [[package]] name = "spinners" version = "4.1.1" @@ -5895,12 +5831,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stop-words" version = "0.8.1" @@ -5942,11 +5872,11 @@ checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum" -version = "0.27.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" dependencies = [ - "strum_macros 0.27.2", + "strum_macros 0.27.1", ] [[package]] @@ -5977,13 +5907,14 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.27.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", + "rustversion", "syn 2.0.104", ] @@ -6138,7 +6069,7 @@ dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", - "rustix 1.0.8", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -6168,7 +6099,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ - "rustix 1.0.8", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -6316,25 +6247,23 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokenizers" -version = "0.21.4" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a620b996116a59e184c2fa2dfd8251ea34a36d0a514758c6f966386bd2e03476" +checksum = "3169b3195f925496c895caee7978a335d49218488ef22375267fba5a46a40bd7" dependencies = [ - "ahash", "aho-corasick", - "compact_str", - "dary_heap", "derive_builder", "esaxx-rs", - "getrandom 0.3.3", + "getrandom 0.2.16", "indicatif", - "itertools 0.14.0", + "itertools 0.13.0", + "lazy_static", "log", "macro_rules_attribute", "monostate", "onig", "paste", - "rand 0.9.2", + "rand 0.8.5", "rayon", "rayon-cond", "regex", @@ -6350,22 +6279,20 @@ dependencies = [ [[package]] name = "tokio" -version = "1.47.1" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2 0.6.0", + "socket2", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6395,7 +6322,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.31", + "rustls 0.23.28", "tokio", ] @@ -6424,9 +6351,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", @@ -6468,7 +6395,7 @@ dependencies = [ "serde_spanned", "toml_datetime", "toml_write", - "winnow 0.7.12", + "winnow 0.7.11", ] [[package]] @@ -6644,10 +6571,11 @@ dependencies = [ [[package]] name = "tree_magic_mini" -version = "3.2.0" +version = "3.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f943391d896cdfe8eec03a04d7110332d445be7df856db382dd96a730667562c" +checksum = "aac5e8971f245c3389a5a76e648bfc80803ae066a1243a75db0064d7c1129d63" dependencies = [ + "fnv", "memchr", "nom", "once_cell", @@ -6685,7 +6613,7 @@ dependencies = [ "http 1.3.1", "httparse", "log", - "rand 0.9.2", + "rand 0.9.1", "sha1", "thiserror 2.0.12", "utf-8", @@ -6854,7 +6782,7 @@ checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" dependencies = [ "getrandom 0.3.3", "js-sys", - "rand 0.9.2", + "rand 0.9.1", "serde", "wasm-bindgen", ] @@ -7048,34 +6976,34 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.11" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" +checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" dependencies = [ "cc", "downcast-rs", - "rustix 1.0.8", + "rustix 0.38.44", "smallvec", "wayland-sys", ] [[package]] name = "wayland-client" -version = "0.31.11" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" +checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" dependencies = [ "bitflags 2.9.1", - "rustix 1.0.8", + "rustix 0.38.44", "wayland-backend", "wayland-scanner", ] [[package]] name = "wayland-protocols" -version = "0.32.9" +version = "0.32.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" +checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" dependencies = [ "bitflags 2.9.1", "wayland-backend", @@ -7085,9 +7013,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.9" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" +checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" dependencies = [ "bitflags 2.9.1", "wayland-backend", @@ -7098,20 +7026,20 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.7" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" +checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" dependencies = [ "proc-macro2", - "quick-xml 0.37.5", + "quick-xml", "quote", ] [[package]] name = "wayland-sys" -version = "0.31.7" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" +checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" dependencies = [ "pkg-config", ] @@ -7147,9 +7075,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" dependencies = [ "rustls-pki-types", ] @@ -7174,7 +7102,7 @@ checksum = "24d643ce3fd3e5b54854602a080f34fb10ab75e0b813ee32d00ca2b44fa74762" dependencies = [ "either", "env_home", - "rustix 1.0.8", + "rustix 1.0.7", "winsafe", ] @@ -7186,11 +7114,11 @@ checksum = "0b9aa3ad29c3d08283ac6b769e3ec15ad1ddb88af7d2e9bc402c574973b937e7" [[package]] name = "whoami" -version = "1.6.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" dependencies = [ - "libredox", + "redox_syscall", "wasite", "web-sys", ] @@ -7473,7 +7401,7 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.2", ] [[package]] @@ -7509,11 +7437,10 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" dependencies = [ - "windows-link", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -7682,9 +7609,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] @@ -7885,9 +7812,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke 0.8.0", "zerofrom", diff --git a/build-config/buildspec-linux.yml b/build-config/buildspec-linux.yml index fb50d66f5b..8c20235acf 100644 --- a/build-config/buildspec-linux.yml +++ b/build-config/buildspec-linux.yml @@ -44,4 +44,3 @@ artifacts: # Signatures - ./*.asc - ./*.sig - diff --git a/build-config/buildspec-macos.yml b/build-config/buildspec-macos.yml index 0fbe335ae2..bb9bb58d75 100644 --- a/build-config/buildspec-macos.yml +++ b/build-config/buildspec-macos.yml @@ -38,4 +38,3 @@ artifacts: - ./*.zip # Hashes - ./*.sha256 - diff --git a/crates/chat-cli/src/cli/agent/mod.rs b/crates/chat-cli/src/cli/agent/mod.rs index a11c0cb7e2..f2ff3954aa 100644 --- a/crates/chat-cli/src/cli/agent/mod.rs +++ b/crates/chat-cli/src/cli/agent/mod.rs @@ -728,6 +728,7 @@ impl Agents { "use_aws" => "trust read-only commands".dark_grey(), "report_issue" => "trusted".dark_green().bold(), "thinking" => "trusted (prerelease)".dark_green().bold(), + "todo_list" => "trusted".dark_green().bold(), _ if self.trust_all_tools => "trusted".dark_grey().bold(), _ => "not trusted".dark_grey(), }; diff --git a/crates/chat-cli/src/cli/chat/cli/mod.rs b/crates/chat-cli/src/cli/chat/cli/mod.rs index 4805426d06..12bd0aa51b 100644 --- a/crates/chat-cli/src/cli/chat/cli/mod.rs +++ b/crates/chat-cli/src/cli/chat/cli/mod.rs @@ -10,6 +10,7 @@ pub mod persist; pub mod profile; pub mod prompts; pub mod subscribe; +pub mod todos; pub mod tools; pub mod usage; @@ -25,6 +26,7 @@ use model::ModelArgs; use persist::PersistSubcommand; use profile::AgentSubcommand; use prompts::PromptsArgs; +use todos::TodoSubcommand; use tools::ToolsArgs; use crate::cli::chat::cli::subscribe::SubscribeArgs; @@ -85,6 +87,9 @@ pub enum SlashCommand { Persist(PersistSubcommand), // #[command(flatten)] // Root(RootSubcommand), + /// View, manage, and resume to-do lists + #[command(subcommand)] + Todos(TodoSubcommand), } impl SlashCommand { @@ -146,6 +151,7 @@ impl SlashCommand { // skip_printing_tools: true, // }) // }, + Self::Todos(subcommand) => subcommand.execute(os, session).await, } } @@ -171,6 +177,7 @@ impl SlashCommand { PersistSubcommand::Save { .. } => "save", PersistSubcommand::Load { .. } => "load", }, + Self::Todos(_) => "todos", } } diff --git a/crates/chat-cli/src/cli/chat/cli/todos.rs b/crates/chat-cli/src/cli/chat/cli/todos.rs new file mode 100644 index 0000000000..eb107e8110 --- /dev/null +++ b/crates/chat-cli/src/cli/chat/cli/todos.rs @@ -0,0 +1,202 @@ +use clap::Subcommand; +use crossterm::execute; +use crossterm::style::{ + self, + Stylize, +}; +use dialoguer::FuzzySelect; +use eyre::Result; + +use crate::cli::chat::tools::todo::{ + TodoListState, + delete_todo, + get_all_todos, +}; +use crate::cli::chat::{ + ChatError, + ChatSession, + ChatState, +}; +use crate::os::Os; + +/// Defines subcommands that allow users to view and manage todo lists +#[derive(Debug, PartialEq, Subcommand)] +pub enum TodoSubcommand { + /// Delete all completed to-do lists + ClearFinished, + + /// Resume a selected to-do list + Resume, + + /// View a to-do list + View, + + /// Delete a to-do list + Delete { + #[arg(long, short)] + all: bool, + }, +} + +/// Used for displaying completed and in-progress todo lists +pub struct TodoDisplayEntry { + pub num_completed: usize, + pub num_tasks: usize, + pub description: String, + pub id: String, +} + +impl std::fmt::Display for TodoDisplayEntry { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.num_completed == self.num_tasks { + write!(f, "{} {}", "✓".green().bold(), self.description.clone(),) + } else { + write!( + f, + "{} {} ({}/{})", + "✗".red().bold(), + self.description.clone(), + self.num_completed, + self.num_tasks + ) + } + } +} + +impl TodoSubcommand { + pub async fn execute(self, os: &mut Os, session: &mut ChatSession) -> Result { + match self { + Self::ClearFinished => { + let (todos, errors) = match get_all_todos(os).await { + Ok(res) => res, + Err(e) => return Err(ChatError::Custom(format!("Could not get to-do lists: {e}").into())), + }; + let mut cleared_one = false; + + for todo_status in todos.iter() { + if todo_status.completed.iter().all(|b| *b) { + match delete_todo(os, &todo_status.id).await { + Ok(_) => cleared_one = true, + Err(e) => { + return Err(ChatError::Custom(format!("Could not delete to-do list: {e}").into())); + }, + }; + } + } + if cleared_one { + execute!( + session.stderr, + style::Print("✔ Cleared finished to-do lists!\n".green()) + )?; + } else { + execute!(session.stderr, style::Print("No finished to-do lists to clear!\n"))?; + } + if !errors.is_empty() { + execute!( + session.stderr, + style::Print(format!("* Failed to get {} todo list(s)\n", errors.len()).dark_grey()) + )?; + } + }, + Self::Resume => match Self::get_descriptions_and_statuses(os).await { + Ok(entries) => { + if entries.is_empty() { + execute!(session.stderr, style::Print("No to-do lists to resume!\n"),)?; + } else if let Some(index) = fuzzy_select_todos(&entries, "Select a to-do list to resume:") { + if index < entries.len() { + execute!( + session.stderr, + style::Print(format!( + "{} {}", + "⟳ Resuming:".magenta(), + entries[index].description.clone() + )) + )?; + return session.resume_todo_request(os, &entries[index].id).await; + } + } + }, + Err(e) => return Err(ChatError::Custom(format!("Could not show to-do lists: {e}").into())), + }, + Self::View => match Self::get_descriptions_and_statuses(os).await { + Ok(entries) => { + if entries.is_empty() { + execute!(session.stderr, style::Print("No to-do lists to view!\n"))?; + } else if let Some(index) = fuzzy_select_todos(&entries, "Select a to-do list to view:") { + if index < entries.len() { + let list = TodoListState::load(os, &entries[index].id).await.map_err(|e| { + ChatError::Custom(format!("Could not load current to-do list: {e}").into()) + })?; + execute!( + session.stderr, + style::Print(format!( + "{} {}\n\n", + "Viewing:".magenta(), + entries[index].description.clone() + )) + )?; + if list.display_list(&mut session.stderr).is_err() { + return Err(ChatError::Custom("Could not display the selected to-do list".into())); + } + execute!(session.stderr, style::Print("\n"),)?; + } + } + }, + Err(e) => return Err(ChatError::Custom(format!("Could not show to-do lists: {e}").into())), + }, + Self::Delete { all } => match Self::get_descriptions_and_statuses(os).await { + Ok(entries) => { + if entries.is_empty() { + execute!(session.stderr, style::Print("No to-do lists to delete!\n"))?; + } else if all { + for entry in entries { + delete_todo(os, &entry.id) + .await + .map_err(|_e| ChatError::Custom("Could not delete all to-do lists".into()))?; + } + execute!(session.stderr, style::Print("✔ Deleted all to-do lists!\n".green()),)?; + } else if let Some(index) = fuzzy_select_todos(&entries, "Select a to-do list to delete:") { + if index < entries.len() { + delete_todo(os, &entries[index].id).await.map_err(|e| { + ChatError::Custom(format!("Could not delete the selected to-do list: {e}").into()) + })?; + execute!( + session.stderr, + style::Print("✔ Deleted to-do list: ".green()), + style::Print(format!("{}\n", entries[index].description.clone().dark_grey())) + )?; + } + } + }, + Err(e) => return Err(ChatError::Custom(format!("Could not show to-do lists: {e}").into())), + }, + } + Ok(ChatState::PromptUser { + skip_printing_tools: true, + }) + } + + /// Convert all to-do list state entries to displayable entries + async fn get_descriptions_and_statuses(os: &Os) -> Result> { + let mut out = Vec::new(); + let (todos, _) = get_all_todos(os).await?; + for todo in todos.iter() { + out.push(TodoDisplayEntry { + num_completed: todo.completed.iter().filter(|b| **b).count(), + num_tasks: todo.completed.len(), + description: todo.description.clone(), + id: todo.id.clone(), + }); + } + Ok(out) + } +} + +fn fuzzy_select_todos(entries: &[TodoDisplayEntry], prompt_str: &str) -> Option { + FuzzySelect::new() + .with_prompt(prompt_str) + .items(entries) + .report(false) + .interact_opt() + .unwrap_or(None) +} diff --git a/crates/chat-cli/src/cli/chat/conversation.rs b/crates/chat-cli/src/cli/chat/conversation.rs index ca7b87d2c4..8718696529 100644 --- a/crates/chat-cli/src/cli/chat/conversation.rs +++ b/crates/chat-cli/src/cli/chat/conversation.rs @@ -12,6 +12,7 @@ use crossterm::{ execute, style, }; +use eyre::Result; use serde::{ Deserialize, Serialize, @@ -489,12 +490,15 @@ impl ConversationState { 2) Bullet points for all significant tools executed and their results\n\ 3) Bullet points for any code or technical information shared\n\ 4) A section of key insights gained\n\n\ + 5) REQUIRED: the ID of the currently loaded todo list, if any\n\n\ FORMAT THE SUMMARY IN THIRD PERSON, NOT AS A DIRECT RESPONSE. Example format:\n\n\ ## CONVERSATION SUMMARY\n\ * Topic 1: Key information\n\ * Topic 2: Key information\n\n\ ## TOOLS EXECUTED\n\ * Tool X: Result Y\n\n\ + ## TODO ID\n\ + * \n\n\ Remember this is a DOCUMENT not a chat response. The custom instruction above modifies what to prioritize.\n\ FILTER OUT CHAT CONVENTIONS (greetings, offers to help, etc).", custom_prompt.as_ref() @@ -509,12 +513,15 @@ impl ConversationState { 2) Bullet points for all significant tools executed and their results\n\ 3) Bullet points for any code or technical information shared\n\ 4) A section of key insights gained\n\n\ + 5) REQUIRED: the ID of the currently loaded todo list, if any\n\n\ FORMAT THE SUMMARY IN THIRD PERSON, NOT AS A DIRECT RESPONSE. Example format:\n\n\ ## CONVERSATION SUMMARY\n\ * Topic 1: Key information\n\ * Topic 2: Key information\n\n\ ## TOOLS EXECUTED\n\ * Tool X: Result Y\n\n\ + ## TODO ID\n\ + * \n\n\ Remember this is a DOCUMENT not a chat response.\n\ FILTER OUT CHAT CONVENTIONS (greetings, offers to help, etc).".to_string() }, diff --git a/crates/chat-cli/src/cli/chat/mod.rs b/crates/chat-cli/src/cli/chat/mod.rs index 0d3b7b1d8c..e159d66641 100644 --- a/crates/chat-cli/src/cli/chat/mod.rs +++ b/crates/chat-cli/src/cli/chat/mod.rs @@ -131,6 +131,7 @@ use crate::api_client::{ }; use crate::auth::AuthError; use crate::auth::builder_id::is_idc_user; +use crate::cli::TodoListState; use crate::cli::agent::Agents; use crate::cli::chat::cli::SlashCommand; use crate::cli::chat::cli::model::find_model; @@ -138,6 +139,8 @@ use crate::cli::chat::cli::prompts::{ GetPromptError, PromptsSubcommand, }; +use crate::cli::chat::message::UserMessage; +use crate::cli::chat::tools::ToolOrigin; use crate::cli::chat::util::sanitize_unicode_tags; use crate::database::settings::Setting; use crate::mcp_client::Prompt; @@ -639,6 +642,11 @@ impl ChatSession { } }); + // Create for cleaner error handling for todo lists + // This is more of a convenience thing but is not required, so the Result + // is ignored + let _ = TodoListState::init_dir(os).await; + Ok(Self { stdout, stderr, @@ -2778,6 +2786,53 @@ impl ChatSession { tracing::warn!("Failed to send slash command telemetry: {}", e); } } + + /// Prompts Q to resume a to-do list with the given id by calling the load + /// command of the todo_list tool + pub async fn resume_todo_request(&mut self, os: &mut Os, id: &str) -> Result { + // Have to unpack each value separately since Reports can't be converted to + // ChatError + let todo_list = match TodoListState::load(os, id).await { + Ok(todo) => todo, + Err(e) => { + return Err(ChatError::Custom(format!("Error getting todo list: {e}").into())); + }, + }; + let contents = match serde_json::to_string(&todo_list) { + Ok(s) => s, + Err(e) => return Err(ChatError::Custom(format!("Error deserializing todo list: {e}").into())), + }; + let summary_content = format!( + "[SYSTEM NOTE: This is an automated request, not from the user]\n + Read the TODO list contents below and understand the task description, completed tasks, and provided context.\n + Call the `load` command of the todo_list tool with the given ID as an argument to display the TODO list to the user and officially resume execution of the TODO list tasks.\n + You do not need to display the tasks to the user yourself. You can begin completing the tasks after calling the `load` command.\n + TODO LIST CONTENTS: {}\n + ID: {}\n", + contents, + id + ); + + let summary_message = UserMessage::new_prompt(summary_content.clone(), None); + + // Only send the todo_list tool + let mut tools = self.conversation.tools.clone(); + tools.retain(|k, v| match k { + ToolOrigin::Native => { + v.retain(|tool| match tool { + api_client::model::Tool::ToolSpecification(tool_spec) => tool_spec.name == "todo_list", + }); + true + }, + ToolOrigin::McpServer(_) => false, + }); + + Ok(ChatState::HandleInput { + input: summary_message + .into_user_input_message(self.conversation.model.clone(), &tools) + .content, + }) + } } /// Replaces amzn_codewhisperer_client::types::SubscriptionStatus with a more descriptive type. @@ -2838,7 +2893,7 @@ async fn get_subscription_status_with_spinner( .await; } -async fn with_spinner(output: &mut impl std::io::Write, spinner_text: &str, f: F) -> Result +pub async fn with_spinner(output: &mut impl std::io::Write, spinner_text: &str, f: F) -> Result where F: FnOnce() -> Fut, Fut: std::future::Future>, diff --git a/crates/chat-cli/src/cli/chat/prompt.rs b/crates/chat-cli/src/cli/chat/prompt.rs index 291fe35ba3..fc0aef58da 100644 --- a/crates/chat-cli/src/cli/chat/prompt.rs +++ b/crates/chat-cli/src/cli/chat/prompt.rs @@ -83,6 +83,11 @@ pub const COMMANDS: &[&str] = &[ "/save", "/load", "/subscribe", + "/todos", + "/todos resume", + "/todos clear-finished", + "/todos view", + "/todos delete", ]; /// Complete commands that start with a slash diff --git a/crates/chat-cli/src/cli/chat/tool_manager.rs b/crates/chat-cli/src/cli/chat/tool_manager.rs index 95739a1068..f23aa6910d 100644 --- a/crates/chat-cli/src/cli/chat/tool_manager.rs +++ b/crates/chat-cli/src/cli/chat/tool_manager.rs @@ -79,6 +79,7 @@ use crate::cli::chat::tools::fs_write::FsWrite; use crate::cli::chat::tools::gh_issue::GhIssue; use crate::cli::chat::tools::knowledge::Knowledge; use crate::cli::chat::tools::thinking::Thinking; +use crate::cli::chat::tools::todo::TodoList; use crate::cli::chat::tools::use_aws::UseAws; use crate::cli::chat::tools::{ Tool, @@ -1066,6 +1067,7 @@ impl ToolManager { "report_issue" => Tool::GhIssue(serde_json::from_value::(value.args).map_err(map_err)?), "thinking" => Tool::Thinking(serde_json::from_value::(value.args).map_err(map_err)?), "knowledge" => Tool::Knowledge(serde_json::from_value::(value.args).map_err(map_err)?), + "todo_list" => Tool::Todo(serde_json::from_value::(value.args).map_err(map_err)?), // Note that this name is namespaced with server_name{DELIMITER}tool_name name => { // Note: tn_map also has tools that underwent no transformation. In otherwords, if diff --git a/crates/chat-cli/src/cli/chat/tools/mod.rs b/crates/chat-cli/src/cli/chat/tools/mod.rs index ea2aef2529..fef93b62a6 100644 --- a/crates/chat-cli/src/cli/chat/tools/mod.rs +++ b/crates/chat-cli/src/cli/chat/tools/mod.rs @@ -5,6 +5,7 @@ pub mod fs_write; pub mod gh_issue; pub mod knowledge; pub mod thinking; +pub mod todo; pub mod use_aws; use std::borrow::{ @@ -35,6 +36,7 @@ use serde::{ Serialize, }; use thinking::Thinking; +use todo::TodoList; use tracing::error; use use_aws::UseAws; @@ -79,6 +81,7 @@ pub enum Tool { GhIssue(GhIssue), Knowledge(Knowledge), Thinking(Thinking), + Todo(TodoList), } impl Tool { @@ -96,6 +99,7 @@ impl Tool { Tool::GhIssue(_) => "gh_issue", Tool::Knowledge(_) => "knowledge", Tool::Thinking(_) => "thinking (prerelease)", + Tool::Todo(_) => "todo_list", } .to_owned() } @@ -111,6 +115,7 @@ impl Tool { Tool::GhIssue(_) => PermissionEvalResult::Allow, Tool::Thinking(_) => PermissionEvalResult::Allow, Tool::Knowledge(knowledge) => knowledge.eval_perm(agent), + Tool::Todo(_) => PermissionEvalResult::Allow, } } @@ -130,6 +135,7 @@ impl Tool { Tool::GhIssue(gh_issue) => gh_issue.invoke(os, stdout).await, Tool::Knowledge(knowledge) => knowledge.invoke(os, stdout).await, Tool::Thinking(think) => think.invoke(stdout).await, + Tool::Todo(todo) => todo.invoke(os, stdout).await, } } @@ -144,6 +150,7 @@ impl Tool { Tool::GhIssue(gh_issue) => gh_issue.queue_description(output), Tool::Knowledge(knowledge) => knowledge.queue_description(os, output).await, Tool::Thinking(thinking) => thinking.queue_description(output), + Tool::Todo(_) => Ok(()), } } @@ -158,6 +165,7 @@ impl Tool { Tool::GhIssue(gh_issue) => gh_issue.validate(os).await, Tool::Knowledge(knowledge) => knowledge.validate(os).await, Tool::Thinking(think) => think.validate(os).await, + Tool::Todo(todo) => todo.validate(os).await, } } diff --git a/crates/chat-cli/src/cli/chat/tools/todo.rs b/crates/chat-cli/src/cli/chat/tools/todo.rs new file mode 100644 index 0000000000..f874e962d0 --- /dev/null +++ b/crates/chat-cli/src/cli/chat/tools/todo.rs @@ -0,0 +1,402 @@ +use std::collections::HashSet; +use std::io::Write; +use std::path::PathBuf; +use std::time::{ + SystemTime, + UNIX_EPOCH, +}; + +use crossterm::style::Stylize; +use crossterm::{ + queue, + style, +}; +use eyre::{ + OptionExt, + Report, + Result, + bail, + eyre, +}; +use serde::{ + Deserialize, + Serialize, +}; + +use super::InvokeOutput; +use crate::os::Os; + +// Local directory to store todo lists +const TODO_LIST_DIR: &str = ".amazonq/cli-todo-lists/"; + +/// Contains all state to be serialized and deserialized into a todo list +#[derive(Debug, Default, Serialize, Deserialize, Clone)] +pub struct TodoListState { + pub tasks: Vec, + pub completed: Vec, + pub description: String, + pub context: Vec, + pub modified_files: Vec, + pub id: String, +} + +impl TodoListState { + /// Creates a local directory to store todo lists + pub async fn init_dir(os: &Os) -> Result<()> { + os.fs.create_dir_all(os.env.current_dir()?.join(TODO_LIST_DIR)).await?; + Ok(()) + } + + /// Loads a TodoListState with the given id + pub async fn load(os: &Os, id: &str) -> Result { + let state_str = os + .fs + .read_to_string(id_to_path(os, id)?) + .await + .map_err(|e| eyre!("Could not load todo list: {e}"))?; + serde_json::from_str::(&state_str).map_err(|e| eyre!("Could not deserialize todo list: {e}")) + } + + /// Saves this TodoListState with the given id + pub async fn save(&self, os: &Os, id: &str) -> Result<()> { + let path = id_to_path(os, id)?; + Self::init_dir(os).await?; + if !os.fs.exists(&path) { + os.fs.create_new(&path).await?; + } + os.fs.write(path, serde_json::to_string(self)?).await?; + Ok(()) + } + + /// Displays the TodoListState as a to-do list + pub fn display_list(&self, output: &mut impl Write) -> Result<()> { + queue!(output, style::Print("TODO:\n".yellow()))?; + for (index, (task, completed)) in self.tasks.iter().zip(self.completed.iter()).enumerate() { + queue_next_without_newline(output, task.clone(), *completed)?; + if index < self.tasks.len() - 1 { + queue!(output, style::Print("\n"))?; + } + } + Ok(()) + } +} + +/// Displays a single empty or marked off to-do list task depending on +/// the completion status +fn queue_next_without_newline(output: &mut impl Write, task: String, completed: bool) -> Result<()> { + if completed { + queue!( + output, + style::SetAttribute(style::Attribute::Italic), + style::SetForegroundColor(style::Color::Green), + style::Print(" ■ "), + style::SetForegroundColor(style::Color::DarkGrey), + style::Print(task), + style::SetAttribute(style::Attribute::NoItalic), + )?; + } else { + queue!( + output, + style::SetForegroundColor(style::Color::Reset), + style::Print(format!(" ☐ {task}")), + )?; + } + Ok(()) +} + +/// Generates a new unique id be used for new to-do lists +pub fn generate_new_todo_id() -> String { + let timestamp = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_millis(); + + format!("{timestamp}") +} + +/// Converts a todo list id to an absolute path in the cwd +pub fn id_to_path(os: &Os, id: &str) -> Result { + Ok(os.env.current_dir()?.join(TODO_LIST_DIR).join(format!("{id}.json"))) +} + +/// Gets all todo lists from the local directory +pub async fn get_all_todos(os: &Os) -> Result<(Vec, Vec)> { + let todo_list_dir = os.env.current_dir()?.join(TODO_LIST_DIR); + let mut read_dir_output = os.fs.read_dir(todo_list_dir).await?; + + let mut todos = Vec::new(); + let mut errors = Vec::new(); + + while let Some(entry) = read_dir_output.next_entry().await? { + match TodoListState::load( + os, + &entry + .path() + .with_extension("") + .file_name() + .ok_or_eyre("Path is not a file")? + .to_string_lossy(), + ) + .await + { + Ok(todo) => todos.push(todo), + Err(e) => errors.push(e), + }; + } + + Ok((todos, errors)) +} + +/// Deletes a todo list +pub async fn delete_todo(os: &Os, id: &str) -> Result<()> { + os.fs.remove_file(id_to_path(os, id)?).await?; + Ok(()) +} + +/// Contains the command definitions that allow the model to create, +/// modify, and mark todo list tasks as complete +#[derive(Debug, Clone, Deserialize)] +#[serde(tag = "command", rename_all = "camelCase")] +pub enum TodoList { + // Creates a todo list + Create { + tasks: Vec, + todo_list_description: String, + }, + + // Completes tasks corresponding to the provided indices + // on the currently loaded todo list + Complete { + completed_indices: Vec, + context_update: String, + modified_files: Option>, + current_id: String, + }, + + // Loads a todo list with the given id + Load { + load_id: String, + }, + + // Inserts new tasks into the current todo list + Add { + new_tasks: Vec, + insert_indices: Vec, + new_description: Option, + current_id: String, + }, + + // Removes tasks from the current todo list + Remove { + remove_indices: Vec, + new_description: Option, + current_id: String, + }, +} + +impl TodoList { + pub async fn invoke(&self, os: &Os, output: &mut impl Write) -> Result { + let (state, id) = match self { + TodoList::Create { + tasks, + todo_list_description: task_description, + } => { + let new_id = generate_new_todo_id(); + + // Create a new todo list with the given tasks and save state + let state = TodoListState { + tasks: tasks.clone(), + completed: vec![false; tasks.len()], + description: task_description.clone(), + context: Vec::new(), + modified_files: Vec::new(), + id: new_id.clone(), + }; + state.save(os, &new_id).await?; + state.display_list(output)?; + (state, new_id) + }, + TodoList::Complete { + completed_indices, + context_update, + modified_files, + current_id: id, + } => { + let mut state = TodoListState::load(os, id).await?; + + for i in completed_indices.iter() { + state.completed[*i] = true; + } + + state.context.push(context_update.clone()); + + if let Some(files) = modified_files { + state.modified_files.extend_from_slice(files); + } + state.save(os, id).await?; + + // As tasks are being completed, display only the newly completed tasks + // and the next. Only display the whole list when all tasks are completed + let last_completed = completed_indices.iter().max().unwrap(); + if *last_completed == state.tasks.len() - 1 || state.completed.iter().all(|c| *c) { + state.display_list(output)?; + } else { + let mut display_list = TodoListState { + tasks: completed_indices.iter().map(|i| state.tasks[*i].clone()).collect(), + ..Default::default() + }; + for _ in 0..completed_indices.len() { + display_list.completed.push(true); + } + + // For next state, mark it true/false depending on actual completion state + // This only matters when the model skips around tasks + display_list.tasks.push(state.tasks[*last_completed + 1].clone()); + display_list.completed.push(state.completed[*last_completed + 1]); + + display_list.display_list(output)?; + } + (state, id.clone()) + }, + TodoList::Load { load_id: id } => { + let state = TodoListState::load(os, id).await?; + state.display_list(output)?; + (state, id.clone()) + }, + TodoList::Add { + new_tasks, + insert_indices, + new_description, + current_id: id, + } => { + let mut state = TodoListState::load(os, id).await?; + for (i, task) in insert_indices.iter().zip(new_tasks.iter()) { + state.tasks.insert(*i, task.clone()); + state.completed.insert(*i, false); + } + if let Some(description) = new_description { + state.description = description.clone(); + } + state.save(os, id).await?; + state.display_list(output)?; + (state, id.clone()) + }, + TodoList::Remove { + remove_indices, + new_description, + current_id: id, + } => { + let mut state = TodoListState::load(os, id).await?; + + // Remove entries in reverse order so indices aren't mismatched + let mut remove_indices = remove_indices.clone(); + remove_indices.sort(); + for i in remove_indices.iter().rev() { + state.tasks.remove(*i); + state.completed.remove(*i); + } + if let Some(description) = new_description { + state.description = description.clone(); + } + state.save(os, id).await?; + state.display_list(output)?; + (state, id.clone()) + }, + }; + + let invoke_output = format!("TODO LIST STATE: {}\n\n ID: {id}", serde_json::to_string(&state)?); + Ok(InvokeOutput { + output: super::OutputKind::Text(invoke_output), + }) + } + + pub async fn validate(&mut self, os: &Os) -> Result<()> { + match self { + TodoList::Create { + tasks, + todo_list_description: task_description, + } => { + if tasks.is_empty() { + bail!("No tasks were provided"); + } else if tasks.iter().any(|task| task.trim().is_empty()) { + bail!("Tasks cannot be empty"); + } else if task_description.is_empty() { + bail!("No task description was provided"); + } + }, + TodoList::Complete { + completed_indices, + context_update, + current_id, + .. + } => { + let state = TodoListState::load(os, current_id).await?; + if completed_indices.is_empty() { + bail!("At least one completed index must be provided"); + } else if context_update.is_empty() { + bail!("No context update was provided"); + } + for i in completed_indices.iter() { + if *i >= state.tasks.len() { + bail!("Index {i} is out of bounds for length {}, ", state.tasks.len()); + } + } + }, + TodoList::Load { load_id: id } => { + let state = TodoListState::load(os, id).await?; + if state.tasks.is_empty() { + bail!("Loaded todo list is empty"); + } + }, + TodoList::Add { + new_tasks, + insert_indices, + new_description, + current_id: id, + } => { + let state = TodoListState::load(os, id).await?; + if new_tasks.iter().any(|task| task.trim().is_empty()) { + bail!("New tasks cannot be empty"); + } else if has_duplicates(insert_indices) { + bail!("Insertion indices must be unique") + } else if new_tasks.len() != insert_indices.len() { + bail!("Must provide an index for every new task"); + } else if new_description.is_some() && new_description.as_ref().unwrap().trim().is_empty() { + bail!("New description cannot be empty"); + } + for i in insert_indices.iter() { + if *i > state.tasks.len() { + bail!("Index {i} is out of bounds for length {}, ", state.tasks.len()); + } + } + }, + TodoList::Remove { + remove_indices, + new_description, + current_id: id, + } => { + let state = TodoListState::load(os, id).await?; + if has_duplicates(remove_indices) { + bail!("Removal indices must be unique") + } else if new_description.is_some() && new_description.as_ref().unwrap().trim().is_empty() { + bail!("New description cannot be empty"); + } + for i in remove_indices.iter() { + if *i >= state.tasks.len() { + bail!("Index {i} is out of bounds for length {}, ", state.tasks.len()); + } + } + }, + } + Ok(()) + } +} + +/// Generated by Q +fn has_duplicates(vec: &[T]) -> bool +where + T: std::hash::Hash + Eq, +{ + let mut seen = HashSet::with_capacity(vec.len()); + vec.iter().any(|item| !seen.insert(item)) +} diff --git a/crates/chat-cli/src/cli/chat/tools/tool_index.json b/crates/chat-cli/src/cli/chat/tools/tool_index.json index 067e5df1ec..6905623c01 100644 --- a/crates/chat-cli/src/cli/chat/tools/tool_index.json +++ b/crates/chat-cli/src/cli/chat/tools/tool_index.json @@ -281,5 +281,88 @@ "command" ] } + }, + "todo_list": { + "name": "todo_list", + "description": "A tool for creating a TODO list and keeping track of tasks. This tool should be requested EVERY time the user gives you a task that will take multiple steps. A TODO list should be made BEFORE executing any steps. Steps should be marked off AS YOU COMPLETE THEM. DO NOT display your own tasks or todo list AT ANY POINT; this is done for you. Complete the tasks in the same order that you provide them. If the user tells you to skip a step, DO NOT mark it as completed.", + "input_schema": { + "type": "object", + "properties": { + "command": { + "type": "string", + "enum": [ + "create", + "complete", + "load", + "add", + "remove" + ], + "description": "The command to run. Allowed options are `add`, `complete`." + }, + "tasks": { + "description": "Required parameter of `create` command containing the list of DISTINCT tasks to be added to the TODO list.", + "type": "array", + "items": { + "type": "string" + } + }, + "todo_list_description": { + "description": "Required parameter of `create` command containing a BRIEF summary of the todo list being created. The summary should be detailed enough to refer to without knowing the problem context beforehand.", + "type": "string" + }, + "completed_indices": { + "description": "Required parameter of `complete` command containing the 0-INDEXED numbers of EVERY completed task. Each task should be marked as completed IMMEDIATELY after it is finished.", + "type": "array", + "items": { + "type": "integer" + } + }, + "context_update": { + "description": "Required parameter of `complete` command containing important task context. Use this command to track important information about the task AND information about files you have read.", + "type": "string" + }, + "modified_files": { + "description": "Optional parameter of `complete` command containing a list of paths of files that were modified during the task. This is useful for tracking file changes that are important to the task.", + "type": "array", + "items": { + "type": "string" + } + }, + "load_id": { + "description": "Required parameter of `load` command containing ID of todo list to load", + "type": "string" + }, + "current_id": { + "description": "Required parameter of `complete`, `add`, and `remove` commands containing the ID of the currently loaded todo list. The ID will ALWAYS be provided after every `todo_list` call after the serialized todo list state.", + "type": "string" + }, + "new_tasks": { + "description": "Required parameter of `add` command containing a list of new tasks to be added to the to-do list.", + "type": "array", + "items": { + "type": "string" + } + }, + "insert_indices": { + "description": "Required parameter of `add` command containing a list of 0-INDEXED positions to insert the new tasks. There MUST be an index for every new task being added.", + "type": "array", + "items": { + "type": "integer" + } + }, + "new_description": { + "description": "Optional parameter of `add` and `remove` containing a new todo list description. Use this when the updated set of tasks significantly change the goal or overall procedure of the todo list.", + "type": "string" + }, + "remove_indices": { + "description": "Required parameter of `remove` command containing a list of 0-INDEXED positions of tasks to remove.", + "type": "array", + "items": { + "type": "integer" + } + } + }, + "required": ["command"] + } } } \ No newline at end of file diff --git a/crates/chat-cli/src/cli/mod.rs b/crates/chat-cli/src/cli/mod.rs index 33238b9da3..803c35d5c5 100644 --- a/crates/chat-cli/src/cli/mod.rs +++ b/crates/chat-cli/src/cli/mod.rs @@ -18,6 +18,7 @@ use std::process::ExitCode; use agent::AgentArgs; use anstream::println; pub use chat::ConversationState; +pub use chat::tools::todo::TodoListState; use clap::{ ArgAction, CommandFactory,