diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cefba170..727a3d6e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: - uses: taiki-e/install-action@v2.75.27 with: tool: cargo-deny - - run: cargo deny check advisories licenses + - run: cargo deny check advisories bans licenses cargo-shear: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index 4523f9e1..2ffac853 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" [[package]] name = "alloc-stdlib" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" dependencies = [ "alloc-no-stdlib", ] @@ -99,15 +99,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "apl-cmf" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4aeb004831a1c57a04ff37d7fe39cda55d990006caf62b6fecf2ccbabbc5f6" +checksum = "3caf776592011d33f4d9d85834daf615de7c038549edbde4ad001c96e83d645d" dependencies = [ "apl-core", "cpex-core", @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "apl-core" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f3707f9a4a83c781082e2a57a6b2da539e2b2777f51de794cda71ee043da33" +checksum = "ae106c4bf2497c610b74ec7091f8facb8d82cd041a53ef6b4a7bbd3524c8ce50" dependencies = [ "async-trait", "cpex-orchestration", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "apl-cpex" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ba4e69907ed745e686aa61de4d02247dff80582a9fdefdf94323147e64ab31" +checksum = "8e40e33d304dcf1d6d57ea91fd58bc6d4bfc4d473ad2c48b503b13696f2782bf" dependencies = [ "apl-cmf", "apl-core", @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" dependencies = [ "rustversion", ] @@ -166,9 +166,9 @@ checksum = "03918c3dbd7701a85c6b9887732e2921175f26c350b4563841d0958c21d57e6d" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "async-compression" @@ -201,7 +201,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -212,15 +212,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad" dependencies = [ "aws-lc-sys", "zeroize", @@ -228,14 +228,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.41.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444" dependencies = [ "cc", "cmake", "dunce", "fs_extra", + "pkg-config", ] [[package]] @@ -292,17 +293,14 @@ dependencies = [ [[package]] name = "axum-otel-metrics" -version = "0.13.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b6d12cc3a75242e592c1631a1ec518ce585586b67c921547e751a81c548c55" +checksum = "d0d74d40b1ff9bd3e8f782aa6798d22ff6a7d1b53049e0e239f5332dab2dd83d" dependencies = [ "axum", - "futures-util", - "http", "http-body", "opentelemetry", "opentelemetry-semantic-conventions", - "opentelemetry_sdk", "pin-project-lite", "tower", ] @@ -358,9 +356,9 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "block-buffer" @@ -382,9 +380,9 @@ dependencies = [ [[package]] name = "brotli" -version = "8.0.2" +version = "8.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -393,9 +391,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.0" +version = "5.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -403,21 +401,21 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.2.62" +version = "1.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38" dependencies = [ "find-msvc-tools", "jobserver", @@ -439,9 +437,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chacha20" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cpufeatures 0.3.0", @@ -450,9 +448,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -493,7 +491,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -636,12 +634,11 @@ dependencies = [ "http", "hyper", "hyper-util", - "itertools", "jsonwebtoken", "lru_time_cache", "openport", "redis", - "reqwest 0.13.3", + "reqwest", "rmcp", "rmp-serde", "rustls", @@ -655,7 +652,7 @@ dependencies = [ "tokio-rustls", "tokio-util", "tower", - "tower-http", + "tower-http 0.7.0", "tracing", "typed-builder", "uuid", @@ -667,7 +664,7 @@ version = "0.1.0" dependencies = [ "goose", "http", - "reqwest 0.13.3", + "reqwest", "tokio", "uuid", ] @@ -729,9 +726,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpex" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71bfbe9f8a9d12584bf01ed8106306e2a63d2acadfe2894753279d573f47e6a" +checksum = "8f3b05e323dc449d9e61e7ec9e72e6b35634a8c4f650c52d37b9bddd8827840d" dependencies = [ "apl-cmf", "apl-core", @@ -741,15 +738,15 @@ dependencies = [ [[package]] name = "cpex-core" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48338f9308ecf4533018413e6f8f3f2f5eba1657228a9f455b1aadd616969ea4" +checksum = "de077ac4aacd2b33d89a8d430f24459f974e277688877a1e1f39eaf13d7f6cb6" dependencies = [ "arc-swap", "async-trait", "chrono", "cpex-orchestration", - "hashbrown 0.17.1", + "hashbrown", "serde", "serde_json", "serde_yaml", @@ -764,9 +761,9 @@ dependencies = [ [[package]] name = "cpex-orchestration" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c8eb4c4db2b9375d8e10220023cfeebf380328885123e67c8621c14b33138a" +checksum = "9808b666ceab61a32281ba8801063e3729bc8f9b28959974cbbfc147382cc8ae" dependencies = [ "futures", "tokio", @@ -825,18 +822,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crypto-bigint" @@ -895,7 +892,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -918,7 +915,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -929,7 +926,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -954,9 +951,6 @@ name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "powerfmt", -] [[package]] name = "digest" @@ -984,13 +978,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1060,9 +1054,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elliptic-curve" @@ -1096,18 +1090,19 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" dependencies = [ "log", + "regex", ] [[package]] name = "env_logger" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" dependencies = [ "anstream", "anstyle", @@ -1211,12 +1206,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "foldhash" version = "0.2.0" @@ -1234,9 +1223,9 @@ dependencies = [ [[package]] name = "fs-err" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" +checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a" dependencies = [ "autocfg", "tokio", @@ -1304,7 +1293,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1376,16 +1365,16 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasip2", - "wasip3", + "wasm-bindgen", ] [[package]] @@ -1405,9 +1394,9 @@ dependencies = [ "lazy_static", "log", "num-format", - "rand 0.9.4", + "rand 0.9.5", "regex", - "reqwest 0.13.3", + "reqwest", "serde", "serde_json", "simplelog", @@ -1451,9 +1440,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" dependencies = [ "atomic-waker", "bytes", @@ -1468,15 +1457,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash 0.1.5", -] - [[package]] name = "hashbrown" version = "0.17.1" @@ -1485,7 +1465,7 @@ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" dependencies = [ "allocator-api2", "equivalent", - "foldhash 0.2.0", + "foldhash", ] [[package]] @@ -1520,9 +1500,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -1530,9 +1510,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -1540,9 +1520,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" dependencies = [ "bytes", "futures-core", @@ -1571,9 +1551,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -1750,12 +1730,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "ident_case" version = "1.0.1" @@ -1790,9 +1764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.1", - "serde", - "serde_core", + "hashbrown", ] [[package]] @@ -1849,7 +1821,7 @@ dependencies = [ "quote", "rustc_version", "simd_cesu8", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1868,28 +1840,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -1907,7 +1878,7 @@ dependencies = [ "p256", "p384", "pem", - "rand 0.8.6", + "rand 0.8.5", "rsa", "serde", "serde_json", @@ -1926,12 +1897,6 @@ dependencies = [ "spin", ] -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" version = "0.2.186" @@ -1967,9 +1932,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "lru-slab" @@ -2000,9 +1965,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "mime" @@ -2032,9 +1997,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", @@ -2064,9 +2029,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", @@ -2083,7 +2048,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.6", + "rand 0.8.5", "smallvec", "zeroize", ] @@ -2115,11 +2080,10 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -2163,7 +2127,7 @@ dependencies = [ "chrono", "getrandom 0.2.17", "http", - "rand 0.8.6", + "rand 0.8.5", "serde", "serde_json", "serde_path_to_error", @@ -2201,11 +2165,11 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openport" -version = "0.1.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "365c699f76305b3e62588961a288be10f0819ef1391f25870a69b35a213577cc" +checksum = "5171c025cd260fb9f7af2d5e60cd7dd4b1d22c3c245f054f84fa62d5a8ba4c35" dependencies = [ - "rand 0.8.6", + "switchy_random", ] [[package]] @@ -2216,9 +2180,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "opentelemetry" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682" dependencies = [ "futures-core", "futures-sink", @@ -2230,22 +2194,22 @@ dependencies = [ [[package]] name = "opentelemetry-http" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331" dependencies = [ "async-trait", "bytes", "http", "opentelemetry", - "reqwest 0.12.28", + "reqwest", ] [[package]] name = "opentelemetry-otlp" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" +checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35" dependencies = [ "http", "opentelemetry", @@ -2253,18 +2217,18 @@ dependencies = [ "opentelemetry-proto", "opentelemetry_sdk", "prost", - "reqwest 0.12.28", + "reqwest", "thiserror 2.0.18", "tokio", "tonic", - "tracing", + "tonic-types", ] [[package]] name = "opentelemetry-proto" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -2275,22 +2239,23 @@ dependencies = [ [[package]] name = "opentelemetry-semantic-conventions" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846" +checksum = "c913ac17a6c451661ee255f4625d143e51647ae78ebd969b75e41c4442f4fe47" [[package]] name = "opentelemetry_sdk" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9" dependencies = [ "futures-channel", "futures-executor", "futures-util", "opentelemetry", "percent-encoding", - "rand 0.9.4", + "portable-atomic", + "rand 0.9.5", "thiserror 2.0.18", "tokio", "tokio-stream", @@ -2397,7 +2362,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2433,6 +2398,12 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + [[package]] name = "potential_utf" version = "0.1.5" @@ -2457,16 +2428,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] - [[package]] name = "primeorder" version = "0.13.6" @@ -2487,9 +2448,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ "bytes", "prost-derive", @@ -2497,15 +2458,24 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", +] + +[[package]] +name = "prost-types" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" +dependencies = [ + "prost", ] [[package]] @@ -2526,9 +2496,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", @@ -2546,15 +2516,16 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" dependencies = [ "aws-lc-rs", "bytes", - "getrandom 0.3.4", + "getrandom 0.4.3", "lru-slab", - "rand 0.9.4", + "rand 0.10.2", + "rand_pcg", "ring", "rustc-hash", "rustls", @@ -2568,23 +2539,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -2603,9 +2574,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -2614,9 +2585,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -2624,12 +2595,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ "chacha20", - "getrandom 0.4.2", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -2677,11 +2648,20 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "redis" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d32a1ac9123f0d84fda64bfc02a271d9868483162dd2d9099b5c362ece064c" +checksum = "2fa6f8e4b491d7a8ef3a9550a4d71969bd0064f46e32b8dbbcc7fc60dad94fed" dependencies = [ "arc-swap", "arcstr", @@ -2734,14 +2714,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" dependencies = [ "aho-corasick", "memchr", @@ -2751,9 +2731,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" dependencies = [ "aho-corasick", "memchr", @@ -2762,55 +2742,22 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" - -[[package]] -name = "reqwest" -version = "0.12.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64", "bytes", "cookie", "cookie_store", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2", @@ -2837,7 +2784,7 @@ dependencies = [ "tokio-rustls", "tokio-util", "tower", - "tower-http", + "tower-http 0.6.11", "tower-service", "url", "wasm-bindgen", @@ -2872,8 +2819,8 @@ dependencies = [ [[package]] name = "rmcp" -version = "1.7.0" -source = "git+https://github.com/contextforge-gateway-rs/mcp-rust-sdk?rev=0d0c3513ec84b3786db1ca62f13604b71f10da83#0d0c3513ec84b3786db1ca62f13604b71f10da83" +version = "2.2.0" +source = "git+https://github.com/contextforge-gateway-rs/mcp-rust-sdk?rev=3252f013c350fd77194caefc70abae69ef0f415a#3252f013c350fd77194caefc70abae69ef0f415a" dependencies = [ "async-trait", "base64", @@ -2886,8 +2833,8 @@ dependencies = [ "oauth2", "pastey", "pin-project-lite", - "rand 0.10.1", - "reqwest 0.13.3", + "rand 0.10.2", + "reqwest", "rmcp-macros", "schemars", "serde", @@ -2905,14 +2852,14 @@ dependencies = [ [[package]] name = "rmcp-macros" -version = "1.7.0" -source = "git+https://github.com/contextforge-gateway-rs/mcp-rust-sdk?rev=0d0c3513ec84b3786db1ca62f13604b71f10da83#0d0c3513ec84b3786db1ca62f13604b71f10da83" +version = "2.2.0" +source = "git+https://github.com/contextforge-gateway-rs/mcp-rust-sdk?rev=3252f013c350fd77194caefc70abae69ef0f415a#3252f013c350fd77194caefc70abae69ef0f415a" dependencies = [ "darling", "proc-macro2", "quote", "serde_json", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2956,9 +2903,9 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -2971,9 +2918,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" dependencies = [ "aws-lc-rs", "log", @@ -2987,9 +2934,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -2999,9 +2946,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "web-time", "zeroize", @@ -3048,9 +2995,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" @@ -3100,7 +3047,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3185,7 +3132,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3196,14 +3143,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "indexmap", "itoa", @@ -3251,9 +3198,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" dependencies = [ "cfg-if", "cpufeatures 0.2.17", @@ -3288,9 +3235,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -3320,9 +3267,9 @@ checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simd_cesu8" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" dependencies = [ "rustc_version", "simdutf8", @@ -3365,15 +3312,15 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", @@ -3381,9 +3328,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] @@ -3400,9 +3347,9 @@ dependencies = [ [[package]] name = "sse-stream" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3962b63f038885f15bce2c6e02c0e7925c072f1ac86bb60fd44c5c6b762fb72" +checksum = "39f24a9b78c40b90817bbcd1821c74ddfd74916aadd29403d001532a9195532d" dependencies = [ "bytes", "futures-util", @@ -3438,7 +3385,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3447,6 +3394,16 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "switchy_random" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a345fa201f9370da696e98f81ba4e9da17f052d49a90827e87e2fdc0b8e0a88a" +dependencies = [ + "log", + "rand 0.8.5", +] + [[package]] name = "symlink" version = "0.1.0" @@ -3466,9 +3423,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -3492,7 +3449,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3527,9 +3484,9 @@ dependencies = [ [[package]] name = "test-log" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f46bf474f0a4afebf92f076d54fd5e63423d9438b8c278a3d2ccb0f47f7cdb3" +checksum = "9b9c218384242b5c89b68303ab6f6fc53a312d923f0c14dc6bb860c6aeee40f1" dependencies = [ "env_logger", "test-log-macros", @@ -3538,22 +3495,22 @@ dependencies = [ [[package]] name = "test-log-core" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d4d41320b48bc4a211a9021678fcc0c99569b594ea31c93735b8e517102b4c" +checksum = "c26ef8b00e4d382e59f6a8ddb3cd790b3a5bb29f21a358a9a69ea2f29f13f27b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "test-log-macros" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9beb9249a81e430dffd42400a49019bcf548444f1968ff23080a625de0d4d320" +checksum = "944ad38adcbb71eaa682c56bceeb079e4ca82b4b3edc2a0fde5cb297b77dac8d" dependencies = [ - "syn 2.0.117", + "syn 2.0.118", "test-log-core", ] @@ -3583,7 +3540,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3594,23 +3551,23 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] [[package]] name = "tikv-jemalloc-sys" -version = "0.6.1+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +version = "0.7.1+5.3.1-0-g81034ce1f1373e37dc865038e1bc8eeecf559ce8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8aa5b2ab86a2cefa406d889139c162cbb230092f7d1d7cbc1716405d852a3b" +checksum = "1a2825c78386b4ae0314074867860ba9577875de945f05992c38815cbec327f0" dependencies = [ "cc", "libc", @@ -3618,9 +3575,9 @@ dependencies = [ [[package]] name = "tikv-jemallocator" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0359b4327f954e0567e69fb191cf1436617748813819c94b8cd4a431422d053a" +checksum = "249f09e49ab1609436f34c776e84231bead18d6a955f119f939bdc1d847561bd" dependencies = [ "libc", "tikv-jemalloc-sys", @@ -3628,12 +3585,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", @@ -3645,15 +3601,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" dependencies = [ "num-conv", "time-core", @@ -3671,9 +3627,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -3709,7 +3665,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3799,6 +3755,17 @@ dependencies = [ "tonic", ] +[[package]] +name = "tonic-types" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab1b02061f83d519bba3caa167f88f261ef05720ab8ebc954ade70de3348e8" +dependencies = [ + "prost", + "prost-types", + "tonic", +] + [[package]] name = "tower" version = "0.5.3" @@ -3823,6 +3790,29 @@ name = "tower-http" version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "async-compression", + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-http" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b11f75e912b0c2be01b63d8cf8057b8c3f97cf34abb3d431a3a4c8675498e233" dependencies = [ "async-compression", "base64", @@ -3894,7 +3884,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3920,9 +3910,9 @@ dependencies = [ [[package]] name = "tracing-opentelemetry" -version = "0.32.1" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc" +checksum = "adbc64cba7137545b8044cb1fe9814f7aacf3c6b5f9b45be8bb5db538befdb26" dependencies = [ "js-sys", "opentelemetry", @@ -3969,7 +3959,7 @@ dependencies = [ "http", "httparse", "log", - "rand 0.9.4", + "rand 0.9.5", "sha1", "thiserror 2.0.18", "utf-8", @@ -3992,14 +3982,14 @@ checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicase" @@ -4013,12 +4003,6 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -4064,11 +4048,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "ea5fab0d6c3c01ae70085a09cb03d4c7a1d6314e2b3e075392783396d724ca0a" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -4113,27 +4097,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -4144,9 +4119,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ "js-sys", "wasm-bindgen", @@ -4154,9 +4129,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4164,48 +4139,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" version = "0.5.0" @@ -4219,23 +4172,11 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -4253,9 +4194,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" dependencies = [ "rustls-pki-types", ] @@ -4296,7 +4237,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4307,7 +4248,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4351,16 +4292,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -4378,31 +4310,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -4411,190 +4326,54 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "writeable" version = "0.6.3" @@ -4603,15 +4382,15 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "xxhash-rust" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" +checksum = "4d93c89cdc2d3a63c3ec48ffe926931bdc069eafa8e4402fe6d8f790c9d1e576" [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -4626,28 +4405,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4667,28 +4446,28 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4721,14 +4500,14 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 6bb6879e..e9969d50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,10 @@ repository = "https://github.com/contextforge-gateway-rs/contextforge-gateway-rs [workspace.dependencies] +# Keep dependencies here only when at least two workspace members inherit them. contextforge-gateway-rs-cpex = { path = "./crates/contextforge-gateway-rs-cpex" } -contextforge-gateway-rs-lib = { path = "./crates/contextforge-gateway-rs-lib" } contextforge-gateway-rs-apis = { path = "./crates/contextforge-gateway-rs-apis"} -rmcp = { version = "1.7.0", features = [ +rmcp = { version = "2.2.0", features = [ "server", "client", "auth", @@ -31,22 +31,12 @@ rmcp = { version = "1.7.0", features = [ "reqwest", "transport-streamable-http-client-reqwest", "elicitation", -], git = "https://github.com/contextforge-gateway-rs/mcp-rust-sdk", rev = "0d0c3513ec84b3786db1ca62f13604b71f10da83" } +], git = "https://github.com/contextforge-gateway-rs/mcp-rust-sdk", rev = "3252f013c350fd77194caefc70abae69ef0f415a" } serde = {version= "1.0"} serde_json = "1.0" tracing = "0.1" -tracing-appender = "0.2.3" -tracing-opentelemetry = "0.32.1" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } tokio = { version = "1.48.0", features = ["full"] } -axum = "0.8" -axum-otel-metrics = "0.13" -tower-http = { version = "0.6.8", features = ["full"] } -tower = "0.5.3" http = "1.4.0" -futures = { version = "0.3", features = ["std", "alloc"] } -jsonwebtoken = {version= "10.3.0", features=["rust_crypto"]} -chrono = "0.4.44" redis = { version = "1.2.1", features = [ "default", "tokio-rustls-comp", @@ -55,16 +45,12 @@ redis = { version = "1.2.1", features = [ ] } clap = { version = "4.5.60", features = ["derive", "env"] } thiserror = "2.0.18" -url = "2.5.8" rmp-serde = "1.3.1" async-trait = "0.1.89" -arc-swap = "1.7" reqwest = "0.13" -itertools = "0.14" -typed-builder = "0.23.2" rustls = { version = "0.23", features = ["ring"] } -rustls-pki-types = "1.14.1" cpex = "0.2.0" +uuid = { version = "1.23.1", features = ["v4"] } [profile.release] codegen-units = 1 diff --git a/crates/contextforge-gateway-rs-apis/Cargo.toml b/crates/contextforge-gateway-rs-apis/Cargo.toml index 728a1ada..478c6410 100644 --- a/crates/contextforge-gateway-rs-apis/Cargo.toml +++ b/crates/contextforge-gateway-rs-apis/Cargo.toml @@ -12,8 +12,8 @@ keywords.workspace = true cpex.workspace = true serde= {workspace = true, features=["derive"]} serde_json.workspace = true -url = {workspace = true, features = ["serde"] } -schemars = {version= "1.2.1", features = ["url2","preserve_order"]} +url = { version = "2.5.8", features = ["serde"] } +schemars = { version = "1.2.1", features = ["url2", "preserve_order"] } [lints] workspace = true diff --git a/crates/contextforge-gateway-rs-cpex/Cargo.toml b/crates/contextforge-gateway-rs-cpex/Cargo.toml index 1f810e78..5b373ec6 100644 --- a/crates/contextforge-gateway-rs-cpex/Cargo.toml +++ b/crates/contextforge-gateway-rs-cpex/Cargo.toml @@ -10,7 +10,7 @@ keywords.workspace = true doctest = false [dependencies] -arc-swap.workspace = true +arc-swap = "1.7" async-trait.workspace = true contextforge-gateway-rs-apis.workspace = true cpex.workspace = true diff --git a/crates/contextforge-gateway-rs-cpex/src/cmf.rs b/crates/contextforge-gateway-rs-cpex/src/cmf.rs index e4c36fd3..b4de6f6e 100644 --- a/crates/contextforge-gateway-rs-cpex/src/cmf.rs +++ b/crates/contextforge-gateway-rs-cpex/src/cmf.rs @@ -1,5 +1,5 @@ use cpex::cpex_core::cmf::{ContentPart, Message, MessagePayload, Role, ToolCall, ToolResult}; -use rmcp::model::{CallToolRequestParams, CallToolResult, Content}; +use rmcp::model::{CallToolRequestParams, CallToolResult, ContentBlock}; use serde_json::{Map, Value}; pub(crate) fn tool_call_payload( @@ -88,7 +88,7 @@ pub(crate) fn tool_result_response(original: CallToolResult, payload: &MessagePa let text = payload.message.get_text_content(); if !text.is_empty() { - result.content.push(Content::text(text)); + result.content.push(ContentBlock::text(text)); } result @@ -96,7 +96,7 @@ pub(crate) fn tool_result_response(original: CallToolResult, payload: &MessagePa fn raw_success_tool_result(value: Value) -> CallToolResult { if let Value::String(text) = value { - CallToolResult::success(vec![Content::text(text)]) + CallToolResult::success(vec![ContentBlock::text(text)]) } else { CallToolResult::structured(value) } @@ -104,7 +104,7 @@ fn raw_success_tool_result(value: Value) -> CallToolResult { fn raw_error_tool_result(value: Value) -> CallToolResult { if let Value::String(text) = value { - CallToolResult::error(vec![Content::text(text)]) + CallToolResult::error(vec![ContentBlock::text(text)]) } else { CallToolResult::structured_error(value) } @@ -116,8 +116,8 @@ mod tests { #[test] fn tool_result_response_uses_cmf_error_flag_for_nested_mcp_result() { - let original = CallToolResult::success(vec![Content::text("original")]); - let nested = CallToolResult::success(vec![Content::text("changed")]); + let original = CallToolResult::success(vec![ContentBlock::text("original")]); + let nested = CallToolResult::success(vec![ContentBlock::text("changed")]); let mut payload = tool_result_payload("sum", &nested, "call-1"); let ContentPart::ToolResult { content } = &mut payload.message.content[0] else { panic!("expected tool result"); diff --git a/crates/contextforge-gateway-rs-cpex/src/handle.rs b/crates/contextforge-gateway-rs-cpex/src/handle.rs index ab74cc90..b63d6313 100644 --- a/crates/contextforge-gateway-rs-cpex/src/handle.rs +++ b/crates/contextforge-gateway-rs-cpex/src/handle.rs @@ -319,7 +319,7 @@ mod tests { registry::AnyHookHandler, }; use rmcp::model::{ - CallToolRequestParams, CallToolResult, Content, NumberOrString, ProgressNotificationParam, ProgressToken, + CallToolRequestParams, CallToolResult, ContentBlock, NumberOrString, ProgressNotificationParam, ProgressToken, }; use serde_json::{Value, json}; use tokio::sync::Mutex as TokioMutex; @@ -822,7 +822,7 @@ mod tests { let pre = runtime.before_tool_call(&sum_request(1, 2), "sum", "backend").await.expect("pre hook runs"); config_store.set_config(config_document(json!({ "plugins": [] }))).await; runtime.reload().await.expect("runtime reloads"); - let response = CallToolResult::success(vec![Content::text("3")]); + let response = CallToolResult::success(vec![ContentBlock::text("3")]); runtime.after_tool_call("sum", response, pre.state).await.expect("post hook runs"); let observations = observations.lock().expect("observations lock poisoned"); @@ -844,7 +844,7 @@ mod tests { let pre = runtime.before_tool_call(&sum_request(1, 2), "sum", "backend").await.expect("pre hook skips"); config_store.set_config(plugin_config(&[Arc::clone(&plugin)])).await; runtime.reload().await.expect("runtime reloads"); - let response = CallToolResult::success(vec![Content::text("3")]); + let response = CallToolResult::success(vec![ContentBlock::text("3")]); runtime.after_tool_call("sum", response, pre.state).await.expect("post hook skips"); assert_eq!(0, observations.lock().expect("observations lock poisoned").post_calls); diff --git a/crates/contextforge-gateway-rs-lib/Cargo.toml b/crates/contextforge-gateway-rs-lib/Cargo.toml index ae89df03..f12a3230 100644 --- a/crates/contextforge-gateway-rs-lib/Cargo.toml +++ b/crates/contextforge-gateway-rs-lib/Cargo.toml @@ -17,29 +17,28 @@ serde_json.workspace = true tracing.workspace = true tokio.workspace = true tokio-util = "0.7" -axum.workspace = true -axum-otel-metrics.workspace = true -tower-http.workspace = true -tower.workspace = true +axum = "0.8" +axum-otel-metrics = "0.14" +tower-http = { version = "0.7.0", features = ["full"] } +tower = "0.5.3" http.workspace = true -futures.workspace = true -jsonwebtoken.workspace = true -chrono.workspace = true +futures = { version = "0.3", features = ["std", "alloc"] } +jsonwebtoken = { version = "10.3.0", features = ["rust_crypto"] } +chrono = "0.4.44" redis.workspace = true clap.workspace = true thiserror.workspace = true rmp-serde.workspace = true async-trait.workspace = true reqwest.workspace = true -itertools.workspace = true -uuid = { version = "1.23", features = ["v4"] } +uuid.workspace = true lru_time_cache = "0.11.11" hyper-util = "0.1.20" -hyper = { version = "1.4.0" } +hyper = "1.4.0" rustls.workspace = true -rustls-pki-types = { version = "1.14.1", features = ["std","alloc"] } +rustls-pki-types = { version = "1.14.1", features = ["std", "alloc"] } tokio-rustls = "0.26.4" -typed-builder.workspace = true +typed-builder = "0.23.2" secret-string = "0.0.2" @@ -50,10 +49,9 @@ with_tools = [] [dev-dependencies] cpex.workspace = true -openport = { version = "0.1.1", features = ["rand"] } +openport = { version = "0.4.0", features = ["rand"] } test-log = "0.2.20" axum-server = { version = "0.8.0", features = ["tls-rustls"] } -futures.workspace = true [lints] workspace = true diff --git a/crates/contextforge-gateway-rs-lib/src/gateway/backend_client.rs b/crates/contextforge-gateway-rs-lib/src/gateway/backend_client.rs index da894250..b73d6be8 100644 --- a/crates/contextforge-gateway-rs-lib/src/gateway/backend_client.rs +++ b/crates/contextforge-gateway-rs-lib/src/gateway/backend_client.rs @@ -4,13 +4,13 @@ use contextforge_gateway_rs_cpex::{GatewayPluginRuntimeHandle, RuntimeHookState} use rmcp::{ ClientHandler, Peer, RoleClient, RoleServer, model::{ - CallToolRequestParams, CallToolResult, ClientRequest, InitializeRequestParams, Meta, ProgressNotificationParam, + CallToolRequestParams, CallToolResult, ClientRequest, InitializeRequestParams, ProgressNotificationParam, ProgressToken, Request, ResourceUpdatedNotificationParam, ServerResult, }, serde::{Serialize, de::DeserializeOwned}, - service::{NotificationContext, PeerRequestOptions, ServiceError}, + service::{NotificationContext, PeerRequestOptions, RequestHandle, ServiceError}, }; -use tokio::sync::Mutex; +use tokio::sync::{Mutex, RwLock}; use tokio_util::sync::CancellationToken; use tracing::{debug, warn}; @@ -22,13 +22,13 @@ pub(crate) struct GatewayBackendClient { namespace_identifiers: bool, initialize_request: InitializeRequestParams, plugin_runtime: Option, - in_flight_calls: Arc>>>, + in_flight_calls: Arc>>>, resource_subscriptions: Arc>>>, } #[derive(Debug)] struct InFlightToolCall { - progress_token: Option, + downstream_progress_token: ProgressToken, tool_name: String, post_state: Option, downstream: Peer, @@ -51,36 +51,42 @@ impl GatewayBackendClient { } } - pub(crate) async fn track_tool_call( + /// Starts a backend tool call while preventing an immediate progress + /// notification from overtaking publication of its token mapping. + #[expect(clippy::too_many_arguments, reason = "tracking requires the request and its downstream call metadata")] + pub(crate) async fn start_tool_call( &self, + peer: &Peer, + request: CallToolRequestParams, + downstream_progress_token: Option, tool_name: String, downstream: Peer, - progress_token: Option, post_state: Option, - ) { - debug!("track_tool_call {tool_name} {progress_token:?} {post_state:?}"); - let call = Arc::new(InFlightToolCall { progress_token, tool_name, post_state, downstream }); - let mut calls = self.in_flight_calls.lock().await; + ) -> Result, ServiceError> { + debug!("track_tool_call {tool_name} {downstream_progress_token:?} {post_state:?}"); + let Some(downstream_progress_token) = downstream_progress_token else { + return start_backend_tool_call(peer, request).await; + }; - if let Some(token) = &call.progress_token { - calls.entry(token.clone()).or_insert_with(|| Arc::clone(&call)); - } - drop(calls); + // RMCP publishes the request before returning its generated progress + // token. Holding the write guard across that enqueue makes progress + // lookups wait until the generated-to-downstream mapping is visible. + let mut calls = self.in_flight_calls.write().await; + let handle = start_backend_tool_call(peer, request).await?; + let backend_progress_token = handle.progress_token.clone(); + let call = Arc::new(InFlightToolCall { downstream_progress_token, tool_name, post_state, downstream }); + calls.insert(backend_progress_token, call); + Ok(handle) } - pub(crate) async fn stop_tracking_tool_call(&self, progress_token: Option) { - debug!("stop_tracking_tool_call {progress_token:?}"); - - let mut calls = self.in_flight_calls.lock().await; - - if let Some(token) = &progress_token { - calls.remove(token); - } - drop(calls); + pub(crate) async fn stop_tracking_tool_call(&self, backend_progress_token: &ProgressToken) { + debug!("stop_tracking_tool_call {backend_progress_token:?}"); + let mut calls = self.in_flight_calls.write().await; + calls.remove(backend_progress_token); } async fn progress_call(&self, progress_token: &ProgressToken) -> Option> { - let calls = self.in_flight_calls.lock().await; + let calls = self.in_flight_calls.read().await; calls.get(progress_token).cloned() } @@ -131,7 +137,7 @@ impl ClientHandler for GatewayBackendClient { self.initialize_request.clone() } - async fn on_progress(&self, progress: ProgressNotificationParam, _context: NotificationContext) { + async fn on_progress(&self, mut progress: ProgressNotificationParam, _context: NotificationContext) { let Some(call) = self.progress_call(&progress.progress_token).await else { debug!( "call_tool: dropping backend progress notification with unknown token {:?}", @@ -139,6 +145,7 @@ impl ClientHandler for GatewayBackendClient { ); return; }; + progress.progress_token.clone_from(&call.downstream_progress_token); debug!("Processing Progress Notification {progress:?} {call:?}"); let Some(progress) = self.stream_event_post_hook(&call, progress).await else { return; @@ -169,23 +176,24 @@ fn resource_uri_for_downstream(backend_name: &str, uri: String, namespace_identi if namespace_identifiers { prefixed_name(backend_name, &uri) } else { uri } } -/// Calls the tool on the backend, keeping the downstream progress token on -/// the request (`Peer::call_tool` would stamp an auto-generated token over it -/// at serialization) and relaying a downstream cancellation to the backend. -pub(crate) async fn call_backend_tool( +/// Starts a backend tool call and exposes RMCP's generated progress token so +/// notifications can be mapped back to the downstream token. +pub(crate) async fn start_backend_tool_call( peer: &Peer, request: CallToolRequestParams, - progress_token: Option, +) -> Result, ServiceError> { + peer.send_cancellable_request( + ClientRequest::CallToolRequest(Request::new(request)), + PeerRequestOptions::no_options(), + ) + .await +} + +/// Awaits a started backend tool call while relaying downstream cancellation. +pub(crate) async fn call_backend_tool( + mut handle: RequestHandle, cancellation: CancellationToken, ) -> Result { - let mut options = PeerRequestOptions::no_options(); - if let Some(progress_token) = progress_token { - let mut meta = Meta::new(); - meta.set_progress_token(progress_token); - options.meta = Some(meta); - } - let mut handle = - peer.send_cancellable_request(ClientRequest::CallToolRequest(Request::new(request)), options).await?; let response = tokio::select! { response = &mut handle.rx => Some(response), () = cancellation.cancelled() => None, diff --git a/crates/contextforge-gateway-rs-lib/src/gateway/mcp_gateway.rs b/crates/contextforge-gateway-rs-lib/src/gateway/mcp_gateway.rs index 8bc81e56..377ff22d 100644 --- a/crates/contextforge-gateway-rs-lib/src/gateway/mcp_gateway.rs +++ b/crates/contextforge-gateway-rs-lib/src/gateway/mcp_gateway.rs @@ -2,14 +2,13 @@ use std::{collections::HashMap, sync::Arc}; use contextforge_gateway_rs_apis::user_store::VirtualHost; use contextforge_gateway_rs_cpex::{GatewayPluginRuntimeHandle, ToolPreCallResult}; -use itertools::Itertools; use rmcp::{ ErrorData, RoleClient, RoleServer, ServerHandler, ServiceExt, model::{ - CallToolRequestParams, CallToolResult, CompleteRequestParams, CompleteResult, ErrorCode, - GetPromptRequestParams, GetPromptResult, Implementation, InitializeRequestParams, InitializeResult, + CallToolRequestParams, CallToolResponse, CompleteRequestParams, CompleteResult, ErrorCode, + GetPromptRequestParams, GetPromptResponse, Implementation, InitializeRequestParams, InitializeResult, ListPromptsResult, ListResourceTemplatesResult, ListResourcesResult, ListToolsResult, PaginatedRequestParams, - Prompt, ReadResourceRequestParams, ReadResourceResult, Reference, Resource, ResourceTemplate, + Prompt, ReadResourceRequestParams, ReadResourceResponse, Reference, Resource, ResourceTemplate, ServerCapabilities, SubscribeRequestParams, Tool, UnsubscribeRequestParams, }, service::{RequestContext, RunningService}, @@ -261,14 +260,14 @@ where ) .await; - Ok(ListToolsResult { meta: None, tools: merge_tools(responses, virtual_host), next_cursor: None }) + Ok(ListToolsResult::with_all_items(merge_tools(responses, virtual_host))) } async fn call_tool( &self, request: CallToolRequestParams, cx: RequestContext, - ) -> Result { + ) -> Result { let mcp_call_validator = AuthorizedCallValidator::new("call_tool", &cx); let (virtual_host, session_id, claims) = mcp_call_validator.validate()?; let session_manager = SessionManager::new(virtual_host, session_id, claims.sub.as_str(), &self.transports); @@ -297,12 +296,21 @@ where pre_result.arguments.apply_to_request(&mut routed_request, &tool_name); let progress_token = cx.meta.get_progress_token(); - service + let handle = service .service() - .track_tool_call(tool_name.clone(), cx.peer.clone(), progress_token.clone(), post_state.clone()) - .await; - let response = call_backend_tool(service.peer(), routed_request, progress_token.clone(), cx.ct.clone()).await; - service.service().stop_tracking_tool_call(progress_token.clone()).await; + .start_tool_call( + service.peer(), + routed_request, + progress_token, + tool_name.clone(), + cx.peer.clone(), + post_state.clone(), + ) + .await + .map_err(|error| backend_forward_error("call_tool", &service_name, &error))?; + let backend_progress_token = handle.progress_token.clone(); + let response = call_backend_tool(handle, cx.ct.clone()).await; + service.service().stop_tracking_tool_call(&backend_progress_token).await; let response = response.map_err(|error| backend_forward_error("call_tool", &service_name, &error))?; let response = match (&self.plugin_runtime, post_state) { @@ -312,7 +320,7 @@ where _ => response, }; info!("call_tool: backend {service_name} completed"); - Ok(response) + Ok(response.into()) } async fn list_resources( @@ -338,18 +346,14 @@ where ) .await; - Ok(ListResourcesResult { - meta: None, - resources: merge_resources(responses, namespace_identifiers), - next_cursor: None, - }) + Ok(ListResourcesResult::with_all_items(merge_resources(responses, namespace_identifiers))) } async fn read_resource( &self, request: ReadResourceRequestParams, cx: RequestContext, - ) -> Result { + ) -> Result { let mcp_call_validator = AuthorizedCallValidator::new("read_resource", &cx); let (virtual_host, session_id, claims) = mcp_call_validator.validate()?; let session_manager = SessionManager::new(virtual_host, session_id, claims.sub.as_str(), &self.transports); @@ -369,7 +373,7 @@ where .await .map_err(|error| backend_forward_error("read_resource", &service_name, &error))?; info!("read_resource: backend {service_name} returned {} contents", response.contents.len()); - Ok(response) + Ok(response.into()) } async fn list_resource_templates( @@ -395,11 +399,7 @@ where ) .await; - Ok(ListResourceTemplatesResult { - meta: None, - resource_templates: merge_resource_templates(responses, namespace_identifiers), - next_cursor: None, - }) + Ok(ListResourceTemplatesResult::with_all_items(merge_resource_templates(responses, namespace_identifiers))) } async fn subscribe( @@ -482,18 +482,14 @@ where ) .await; - Ok(ListPromptsResult { - meta: None, - prompts: merge_prompts(responses, namespace_identifiers), - next_cursor: None, - }) + Ok(ListPromptsResult::with_all_items(merge_prompts(responses, namespace_identifiers))) } async fn get_prompt( &self, request: GetPromptRequestParams, cx: RequestContext, - ) -> Result { + ) -> Result { let mcp_call_validator = AuthorizedCallValidator::new("get_prompt", &cx); let (virtual_host, session_id, claims) = mcp_call_validator.validate()?; let session_manager = SessionManager::new(virtual_host, session_id, claims.sub.as_str(), &self.transports); @@ -513,7 +509,7 @@ where .await .map_err(|error| backend_forward_error("get_prompt", &service_name, &error))?; info!("get_prompt: backend {service_name} returned {} messages", response.messages.len()); - Ok(response) + Ok(response.into()) } async fn complete( @@ -528,6 +524,7 @@ where let identifier = match &request.r#ref { Reference::Prompt(prompt) => prompt.name.as_str(), Reference::Resource(resource) => resource.uri.as_str(), + _ => return Err(ErrorData::invalid_params("Unsupported completion reference", None)), }; let (service_name, service, routed_identifier) = route_identifier_to_backend( @@ -542,6 +539,7 @@ where match &mut routed_request.r#ref { Reference::Prompt(prompt) => prompt.name = routed_identifier, Reference::Resource(resource) => resource.uri = routed_identifier, + _ => return Err(ErrorData::invalid_params("Unsupported completion reference", None)), } let response = service .complete(routed_request) @@ -744,7 +742,7 @@ fn log_list_backend_response( } fn merge_tools(tools: Vec<(String, ListToolsResult)>, virtual_host: &VirtualHost) -> Vec { - tools + let mut tools = tools .into_iter() .flat_map(|(backend_name, result)| { result @@ -756,12 +754,13 @@ fn merge_tools(tools: Vec<(String, ListToolsResult)>, virtual_host: &VirtualHost }) .collect::>() }) - .sorted_by(|t, o| t.name.cmp(&o.name)) - .collect::>() + .collect::>(); + tools.sort_unstable_by(|tool, other| tool.name.cmp(&other.name)); + tools } fn merge_resources(resources: Vec<(String, ListResourcesResult)>, namespace_identifiers: bool) -> Vec { - resources + let mut resources = resources .into_iter() .flat_map(|(backend_name, result)| { result @@ -776,15 +775,16 @@ fn merge_resources(resources: Vec<(String, ListResourcesResult)>, namespace_iden }) .collect::>() }) - .sorted_by(|t, o| t.name.cmp(&o.name)) - .collect::>() + .collect::>(); + resources.sort_unstable_by(|resource, other| resource.name.cmp(&other.name)); + resources } fn merge_resource_templates( templates: Vec<(String, ListResourceTemplatesResult)>, namespace_identifiers: bool, ) -> Vec { - templates + let mut templates = templates .into_iter() .flat_map(|(backend_name, result)| { result.resource_templates.into_iter().map(move |mut template| { @@ -795,12 +795,13 @@ fn merge_resource_templates( template }) }) - .sorted_by(|template, other| template.name.cmp(&other.name)) - .collect::>() + .collect::>(); + templates.sort_unstable_by(|template, other| template.name.cmp(&other.name)); + templates } fn merge_prompts(prompts: Vec<(String, ListPromptsResult)>, namespace_identifiers: bool) -> Vec { - prompts + let mut prompts = prompts .into_iter() .flat_map(|(backend_name, result)| { result.prompts.into_iter().map(move |mut prompt| { @@ -810,15 +811,15 @@ fn merge_prompts(prompts: Vec<(String, ListPromptsResult)>, namespace_identifier prompt }) }) - .sorted_by(|prompt, other| prompt.name.cmp(&other.name)) - .collect::>() + .collect::>(); + prompts.sort_unstable_by(|prompt, other| prompt.name.cmp(&other.name)); + prompts } #[cfg(test)] mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; - use rmcp::model::{AnnotateAble, RawResource, RawResourceTemplate}; #[test] fn test_splitting() { @@ -870,46 +871,31 @@ mod tests { let tools = merge_tools( vec![( "backend-id".to_owned(), - ListToolsResult { - tools: vec![Tool::new("test_simple_text", "", serde_json::Map::new())], - next_cursor: None, - meta: None, - }, + ListToolsResult::with_all_items(vec![Tool::new("test_simple_text", "", serde_json::Map::new())]), )], &virtual_host, ); let prompts = merge_prompts( vec![( "backend-id".to_owned(), - ListPromptsResult { - prompts: vec![Prompt::new("test_prompt", None::, None)], - next_cursor: None, - meta: None, - }, + ListPromptsResult::with_all_items(vec![Prompt::new("test_prompt", None::, None)]), )], false, ); let resources = merge_resources( vec![( "backend-id".to_owned(), - ListResourcesResult { - resources: vec![RawResource::new("test://resource", "test_resource").no_annotation()], - next_cursor: None, - meta: None, - }, + ListResourcesResult::with_all_items(vec![Resource::new("test://resource", "test_resource")]), )], false, ); let templates = merge_resource_templates( vec![( "backend-id".to_owned(), - ListResourceTemplatesResult { - resource_templates: vec![ - RawResourceTemplate::new("test://template/{id}/data", "test_template").no_annotation(), - ], - next_cursor: None, - meta: None, - }, + ListResourceTemplatesResult::with_all_items(vec![ResourceTemplate::new( + "test://template/{id}/data", + "test_template", + )]), )], false, ); diff --git a/crates/contextforge-gateway-rs-lib/tests/gateway_plugins.rs b/crates/contextforge-gateway-rs-lib/tests/gateway_plugins.rs index 2368939d..1e85287a 100644 --- a/crates/contextforge-gateway-rs-lib/tests/gateway_plugins.rs +++ b/crates/contextforge-gateway-rs-lib/tests/gateway_plugins.rs @@ -9,7 +9,7 @@ use rmcp::{ ClientHandler, model::{ CallToolRequestParams, CallToolResult, ClientCapabilities, ClientRequest, ErrorCode, Implementation, - InitializeRequestParams, Meta, NumberOrString, ProgressNotificationParam, ProgressToken, Request, ServerResult, + InitializeRequestParams, ProgressNotificationParam, Request, ServerResult, }, service::{NotificationContext, PeerRequestOptions, RequestHandle, RoleClient, RunningService}, }; @@ -57,8 +57,7 @@ async fn send_progress_sum( let client = RecordingClient::default(); let progress = Arc::clone(&client.progress); let service = gateway.connect_with_handler(user, client).await; - let token = ProgressToken(NumberOrString::String("package-progress".into())); - let handle = send_progress_call(&service, "progress_sum", token).await; + let handle = send_progress_call(&service, "progress_sum").await; let ServerResult::CallToolResult(result) = handle.await_response().await.expect("progress_sum call succeeds") else { @@ -67,18 +66,18 @@ async fn send_progress_sum( (result, progress) } -/// Sends a `tools/call` carrying `progress_token` and returns the in-flight -/// request handle without awaiting it. +/// Starts a `tools/call` and returns the in-flight request handle without +/// awaiting it. async fn send_progress_call( service: &RunningService, tool_name: &str, - progress_token: ProgressToken, ) -> RequestHandle { let request = CallToolRequestParams::new(tool_name.to_owned()); - let mut options = PeerRequestOptions::no_options(); - options.meta = Some(Meta::with_progress_token(progress_token)); service - .send_cancellable_request(ClientRequest::CallToolRequest(Request::new(request)), options) + .send_cancellable_request( + ClientRequest::CallToolRequest(Request::new(request)), + PeerRequestOptions::no_options(), + ) .await .expect("progress request is sent") } @@ -112,7 +111,7 @@ fn raw_mcp_request( request } -fn raw_tool_call(tool_name: &str, request_id: i64, progress_token: i64) -> Value { +fn raw_tool_call(tool_name: &str, request_id: i64, progress_token: &str) -> Value { serde_json::json!({ "method": "tools/call", "params": { @@ -140,7 +139,7 @@ fn sse_data_values(body: &str) -> Vec { if body.is_empty() { Vec::new() } else { vec![serde_json::from_str(body).expect("JSON response body")] } } -fn assert_raw_progress_stream(body: &str, response_id: i64, progress_token: i64) { +fn assert_raw_progress_stream(body: &str, response_id: i64, progress_token: &str) { let messages = sse_data_values(body); let progress = messages .iter() @@ -150,7 +149,7 @@ fn assert_raw_progress_stream(body: &str, response_id: i64, progress_token: i64) assert!( progress .iter() - .all(|message| message.pointer("/params/progressToken").and_then(Value::as_i64) == Some(progress_token)), + .all(|message| message.pointer("/params/progressToken").and_then(Value::as_str) == Some(progress_token)), "progress events with foreign tokens in body: {body}" ); let result = messages @@ -234,8 +233,11 @@ async fn concurrent_progress_calls_forward_each_token_without_plugins() { let service = gateway.connect_with_handler("admin@example.com", client).await; let tool_name = "progress_sum"; - let first = send_progress_call(&service, tool_name, ProgressToken(NumberOrString::Number(1))).await; - let second = send_progress_call(&service, tool_name, ProgressToken(NumberOrString::Number(2))).await; + let first = send_progress_call(&service, tool_name).await; + let first_progress_token = first.progress_token.clone(); + let second = send_progress_call(&service, tool_name).await; + let second_progress_token = second.progress_token.clone(); + assert_ne!(first_progress_token, second_progress_token); let (first, second) = tokio::time::timeout(std::time::Duration::from_secs(3), async { tokio::join!(first.await_response(), second.await_response()) @@ -254,14 +256,10 @@ async fn concurrent_progress_calls_forward_each_token_without_plugins() { wait_for_event_count(&progress, 8).await; let progress = progress.lock().expect("progress lock poisoned"); - let first_count = progress - .iter() - .filter(|notification| notification.progress_token == ProgressToken(NumberOrString::Number(1))) - .count(); - let second_count = progress - .iter() - .filter(|notification| notification.progress_token == ProgressToken(NumberOrString::Number(2))) - .count(); + let first_count = + progress.iter().filter(|notification| notification.progress_token == first_progress_token).count(); + let second_count = + progress.iter().filter(|notification| notification.progress_token == second_progress_token).count(); assert_eq!(4, first_count); assert_eq!(4, second_count); } @@ -273,14 +271,24 @@ async fn raw_streamable_http_concurrent_progress_calls_complete_without_plugins( let session_id = start_raw_mcp_session(&client, &gateway, "admin@example.com").await; let tool_name = "progress_sum"; - let first = - raw_mcp_request(&client, &gateway, "admin@example.com", Some(&session_id), &raw_tool_call(tool_name, 2, 1)); - let second = - raw_mcp_request(&client, &gateway, "admin@example.com", Some(&session_id), &raw_tool_call(tool_name, 3, 2)); + let first = raw_mcp_request( + &client, + &gateway, + "admin@example.com", + Some(&session_id), + &raw_tool_call(tool_name, 2, "downstream-first"), + ); + let second = raw_mcp_request( + &client, + &gateway, + "admin@example.com", + Some(&session_id), + &raw_tool_call(tool_name, 3, "downstream-second"), + ); let (first_body, second_body) = read_concurrent_raw_progress_streams(first, second).await; - assert_raw_progress_stream(&first_body, 2, 1); - assert_raw_progress_stream(&second_body, 3, 2); + assert_raw_progress_stream(&first_body, 2, "downstream-first"); + assert_raw_progress_stream(&second_body, 3, "downstream-second"); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -291,7 +299,7 @@ async fn backend_generated_progress_tokens_are_dropped() { let service = gateway.connect_with_handler("admin@example.com", client).await; let tool_name = "progress_counter_tokens"; - let handle = send_progress_call(&service, tool_name, ProgressToken(NumberOrString::Number(10))).await; + let handle = send_progress_call(&service, tool_name).await; let ServerResult::CallToolResult(result) = handle.await_response().await.expect("progress_counter_tokens call succeeds") diff --git a/crates/contextforge-gateway-rs-lib/tests/gateway_prompts.rs b/crates/contextforge-gateway-rs-lib/tests/gateway_prompts.rs index ca4c3335..a34b35d9 100644 --- a/crates/contextforge-gateway-rs-lib/tests/gateway_prompts.rs +++ b/crates/contextforge-gateway-rs-lib/tests/gateway_prompts.rs @@ -1,7 +1,7 @@ mod support; use contextforge_gateway_rs_lib::{Config, Result, UpstreamConnectionMode}; -use rmcp::model::{GetPromptRequestParams, PromptMessageContent}; +use rmcp::model::GetPromptRequestParams; use serde_json::json; use tracing::{info, warn}; @@ -103,7 +103,7 @@ async fn assert_get_prompt(gateway_url: String, client: reqwest::Client, prompt_ let Some(message) = result.messages.first() else { return Err("Expected prompt message".into()); }; - let PromptMessageContent::Text { text } = &message.content else { + let Some(text) = message.content.as_text().map(|content| &content.text) else { return Err("Expected text prompt message".into()); }; diff --git a/crates/contextforge-gateway-rs-lib/tests/support/mock_counter.rs b/crates/contextforge-gateway-rs-lib/tests/support/mock_counter.rs index ff24089f..3d921fad 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/mock_counter.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/mock_counter.rs @@ -76,48 +76,48 @@ impl Counter { } fn _create_resource_text(&self, uri: &str, name: &str) -> Resource { - RawResource::new(uri, name.to_owned()).no_annotation() + Resource::new(uri, name) } #[tool(description = "Increment the counter by 1")] async fn increment(&self) -> Result { let mut counter = self.counter.lock().await; *counter += 1; - Ok(CallToolResult::success(vec![Content::text(counter.to_string())])) + Ok(CallToolResult::success(vec![ContentBlock::text(counter.to_string())])) } #[tool(description = "Decrement the counter by 1")] async fn decrement(&self) -> Result { let mut counter = self.counter.lock().await; *counter -= 1; - Ok(CallToolResult::success(vec![Content::text(counter.to_string())])) + Ok(CallToolResult::success(vec![ContentBlock::text(counter.to_string())])) } #[tool(description = "Get the current counter value")] async fn get_value(&self) -> Result { let counter = self.counter.lock().await; - Ok(CallToolResult::success(vec![Content::text(counter.to_string())])) + Ok(CallToolResult::success(vec![ContentBlock::text(counter.to_string())])) } #[tool(description = "Long running task example")] async fn long_task(&self) -> Result { tokio::time::sleep(std::time::Duration::from_secs(10)).await; - Ok(CallToolResult::success(vec![Content::text("Long task completed")])) + Ok(CallToolResult::success(vec![ContentBlock::text("Long task completed")])) } #[tool(description = "Say hello to the client")] fn say_hello(&self) -> Result { - Ok(CallToolResult::success(vec![Content::text("hello")])) + Ok(CallToolResult::success(vec![ContentBlock::text("hello")])) } #[tool(description = "Repeat what you say")] fn echo(&self, Parameters(object): Parameters) -> Result { - Ok(CallToolResult::success(vec![Content::text(serde_json::Value::Object(object).to_string())])) + Ok(CallToolResult::success(vec![ContentBlock::text(serde_json::Value::Object(object).to_string())])) } #[tool(description = "Calculate the sum of two numbers")] fn sum(&self, Parameters(StructRequest { a, b }): Parameters) -> Result { - Ok(CallToolResult::success(vec![Content::text((a + b).to_string())])) + Ok(CallToolResult::success(vec![ContentBlock::text((a + b).to_string())])) } /// Returns the `Mcp-Session-Id` of the current session (streamable HTTP only). @@ -130,8 +130,10 @@ impl Counter { .map(|v| v.to_str().unwrap_or("(non-ascii)").to_owned()); match session_id { - Some(id) => Ok(CallToolResult::success(vec![Content::text(id)])), - None => Ok(CallToolResult::success(vec![Content::text("no session (not running over streamable HTTP?)")])), + Some(id) => Ok(CallToolResult::success(vec![ContentBlock::text(id)])), + None => { + Ok(CallToolResult::success(vec![ContentBlock::text("no session (not running over streamable HTTP?)")])) + }, } } } @@ -149,7 +151,7 @@ impl Counter { _ctx: RequestContext, ) -> Result, McpError> { let prompt = format!("This is an example prompt with your message here: '{}'", args.message); - Ok(vec![PromptMessage::new_text(PromptMessageRole::User, prompt)]) + Ok(vec![PromptMessage::new_text(Role::User, prompt)]) } /// Analyze the current counter value and suggest next steps @@ -165,11 +167,11 @@ impl Counter { let messages = vec![ PromptMessage::new_text( - PromptMessageRole::Assistant, + Role::Assistant, "I'll analyze the counter situation and suggest the best approach.", ), PromptMessage::new_text( - PromptMessageRole::User, + Role::User, format!( "Current counter value: {}\nGoal value: {}\nDifference: {}\nStrategy preference: {}\n\nPlease analyze the situation and suggest the best approach to reach the goal.", current_value, args.goal, difference, strategy @@ -204,30 +206,26 @@ impl ServerHandler for Counter { _request: Option, _: RequestContext, ) -> Result { - Ok(ListResourcesResult { - resources: vec![ - self._create_resource_text("str:////Users/to/some/path/", "cwd"), - self._create_resource_text("memo://insights", "memo-name"), - ], - next_cursor: None, - meta: None, - }) + Ok(ListResourcesResult::with_all_items(vec![ + self._create_resource_text("str:////Users/to/some/path/", "cwd"), + self._create_resource_text("memo://insights", "memo-name"), + ])) } async fn read_resource( &self, request: ReadResourceRequestParams, _: RequestContext, - ) -> Result { + ) -> Result { let uri = &request.uri; match uri.as_str() { "str:////Users/to/some/path/" => { let cwd = "/Users/to/some/path/"; - Ok(ReadResourceResult::new(vec![ResourceContents::text(cwd, uri.clone())])) + Ok(ReadResourceResult::new(vec![ResourceContents::text(cwd, uri.clone())]).into()) }, "memo://insights" => { let memo = "Business Intelligence Memo\n\nAnalysis has revealed 5 key insights ..."; - Ok(ReadResourceResult::new(vec![ResourceContents::text(memo, uri.clone())])) + Ok(ReadResourceResult::new(vec![ResourceContents::text(memo, uri.clone())]).into()) }, _ => Err(McpError::resource_not_found( "resource_not_found", @@ -301,26 +299,14 @@ impl ServerHandler for Counter { _: RequestContext, ) -> Result { let resource_templates = vec![ - RawResourceTemplate { - uri_template: "str:////{path}".into(), - name: "filesystem".into(), - title: None, - description: Some("Read a file by absolute path".into()), - mime_type: Some("text/plain".into()), - icons: None, - } - .no_annotation(), - RawResourceTemplate { - uri_template: "memo://{id}".into(), - name: "memo".into(), - title: None, - description: Some("Read a memo by id".into()), - mime_type: Some("text/plain".into()), - icons: None, - } - .no_annotation(), + ResourceTemplate::new("str:////{path}", "filesystem") + .with_description("Read a file by absolute path") + .with_mime_type("text/plain"), + ResourceTemplate::new("memo://{id}", "memo") + .with_description("Read a memo by id") + .with_mime_type("text/plain"), ]; - Ok(ListResourceTemplatesResult { next_cursor: None, resource_templates, meta: None }) + Ok(ListResourceTemplatesResult::with_all_items(resource_templates)) } async fn initialize( diff --git a/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs b/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs index 67d5681e..ddc02109 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs @@ -12,7 +12,7 @@ use cpex::cpex_core::{ hooks::{Extensions, HookHandler, PluginResult, TypedHandlerAdapter, types::cmf_hook_names}, plugin::{Plugin, PluginConfig}, }; -use rmcp::model::{CallToolResult, Content, ProgressNotificationParam}; +use rmcp::model::{CallToolResult, ContentBlock, ProgressNotificationParam}; use serde_json::{Value, json}; use super::tool::text; @@ -192,9 +192,9 @@ impl HookHandler for TestPlugin { if !is_tool_result_content(&content.content) { return PluginResult::allow(); } - content.content = serde_json::to_value(CallToolResult::success(vec![Content::text(format!( - "post:{result_text}" - ))])) + content.content = serde_json::to_value(CallToolResult::success(vec![ContentBlock::text( + format!("post:{result_text}"), + )])) .expect("tool result serializes"); } PluginResult::modify_payload(modified) diff --git a/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs b/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs index 93c9731a..0417bb86 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs @@ -15,8 +15,9 @@ use http::{HeaderMap, HeaderValue}; use rmcp::{ ErrorData, RoleClient, RoleServer, ServerHandler, ServiceExt, model::{ - CallToolRequestParams, CallToolResult, Content, ErrorCode, Implementation, InitializeRequestParams, - InitializeResult, NumberOrString, ProgressNotificationParam, ProgressToken, ServerCapabilities, + CallToolRequestParams, CallToolResponse, CallToolResult, ContentBlock, ErrorCode, Implementation, + InitializeRequestParams, InitializeResult, NumberOrString, ProgressNotificationParam, ProgressToken, + ServerCapabilities, }, service::{RequestContext, Service}, transport::{ @@ -66,14 +67,14 @@ impl ServerHandler for TestBackend { &self, request: CallToolRequestParams, cx: RequestContext, - ) -> Result { + ) -> Result { self.state .calls .lock() .expect("backend calls lock poisoned") .push(BackendObservation { tool_name: request.name.to_string(), args: request.arguments.clone() }); - match request.name.as_ref() { + let result: Result = match request.name.as_ref() { "sum" => { let args = request .arguments @@ -87,7 +88,7 @@ impl ServerHandler for TestBackend { .get("b") .and_then(Value::as_i64) .ok_or_else(|| ErrorData::invalid_params("sum requires numeric b", None))?; - Ok(CallToolResult::success(vec![Content::text((a + b).to_string())])) + Ok(CallToolResult::success(vec![ContentBlock::text((a + b).to_string())])) }, "progress_sum" => { if let Some(progress_token) = cx.meta.get_progress_token() { @@ -105,14 +106,14 @@ impl ServerHandler for TestBackend { tokio::time::sleep(Duration::from_millis(10)).await; } } - Ok(CallToolResult::success(vec![Content::text("completed 4 packages")])) + Ok(CallToolResult::success(vec![ContentBlock::text("completed 4 packages")])) }, "progress_counter_tokens" => { for package in 1..=4i32 { cx.peer .notify_progress( ProgressNotificationParam::new( - ProgressToken(NumberOrString::Number(i64::from(package))), + ProgressToken(NumberOrString::String(format!("unexpected-backend-{package}").into())), f64::from(package), ) .with_total(4.0) @@ -124,7 +125,7 @@ impl ServerHandler for TestBackend { })?; tokio::time::sleep(Duration::from_millis(10)).await; } - Ok(CallToolResult::success(vec![Content::text("completed 4 packages")])) + Ok(CallToolResult::success(vec![ContentBlock::text("completed 4 packages")])) }, "wait_for_cancellation" => { cx.ct.cancelled().await; @@ -133,14 +134,15 @@ impl ServerHandler for TestBackend { .lock() .expect("backend cancellations lock poisoned") .push(request.name.to_string()); - Ok(CallToolResult::success(vec![Content::text("cancelled")])) + Ok(CallToolResult::success(vec![ContentBlock::text("cancelled")])) }, _ => Err(ErrorData { code: ErrorCode::METHOD_NOT_FOUND, message: format!("unknown tool {}", request.name).into(), data: None, }), - } + }; + result.map(Into::into) } } diff --git a/crates/contextforge-gateway-rs/Cargo.toml b/crates/contextforge-gateway-rs/Cargo.toml index 9950202c..c264892e 100644 --- a/crates/contextforge-gateway-rs/Cargo.toml +++ b/crates/contextforge-gateway-rs/Cargo.toml @@ -9,23 +9,23 @@ keywords.workspace = true [dependencies] contextforge-gateway-rs-cpex.workspace = true -contextforge-gateway-rs-lib.workspace = true +contextforge-gateway-rs-lib = { path = "../contextforge-gateway-rs-lib" } cpex-payload-marker = { git = "https://github.com/contextforge-gateway-rs/cpex-plugins-rs", rev = "ab47801daccfbba44ea07b033034a347e7b5afdd", optional = true } cpex-text-prefixer = { git = "https://github.com/contextforge-gateway-rs/cpex-plugins-rs", rev = "ab47801daccfbba44ea07b033034a347e7b5afdd", optional = true } cpex-tool-namespace = { git = "https://github.com/contextforge-gateway-rs/cpex-plugins-rs", rev = "ab47801daccfbba44ea07b033034a347e7b5afdd", optional = true } clap.workspace = true tracing.workspace = true -tracing-appender.workspace = true -tracing-opentelemetry.workspace = true -tracing-subscriber.workspace = true +tracing-appender = "0.2.3" +tracing-opentelemetry = "0.33.0" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } tokio.workspace = true -opentelemetry = "0.31" -opentelemetry-otlp = { version = "0.31", features = ["grpc-tonic", "http-proto", "reqwest-blocking-client", "metrics"] } -opentelemetry_sdk = { version = "0.31", features = ["rt-tokio", "metrics"] } +opentelemetry = "0.32" +opentelemetry-otlp = { version = "0.32", features = ["grpc-tonic", "http-proto", "reqwest-blocking-client", "metrics"] } +opentelemetry_sdk = { version = "0.32", features = ["rt-tokio", "metrics"] } tonic = "0.14" num_cpus = "1.17.0" rmcp.workspace = true -tikv-jemallocator = "0.6.1" +tikv-jemallocator = "0.7.0" rustls.workspace = true [features] diff --git a/crates/contextforge-load-test/Cargo.toml b/crates/contextforge-load-test/Cargo.toml index 4b78a9da..f704f1ad 100644 --- a/crates/contextforge-load-test/Cargo.toml +++ b/crates/contextforge-load-test/Cargo.toml @@ -16,7 +16,7 @@ goose = { git = "https://github.com/tag1consulting/goose" } tokio.workspace = true http.workspace = true reqwest.workspace = true -uuid = { version = "1.23.1", features = ["v4"] } +uuid.workspace = true [lints] diff --git a/deny.toml b/deny.toml index 6a051f1a..893d9a07 100644 --- a/deny.toml +++ b/deny.toml @@ -305,6 +305,11 @@ skip-tree = [ #{ crate = "ansi_term@0.11.0", depth = 20 }, ] +[bans.workspace-dependencies] +duplicates = "deny" +include-path-dependencies = true +unused = "deny" + # This section is considered when running `cargo deny check sources`. # More documentation about the 'sources' section can be found here: # https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html diff --git a/docs/book/src/request-flow.md b/docs/book/src/request-flow.md index 21e40c2f..71382fda 100644 --- a/docs/book/src/request-flow.md +++ b/docs/book/src/request-flow.md @@ -162,9 +162,13 @@ Current routed method families: | `complete` | Apply the same conditional routing to the prompt name or resource URI in `ref`, then return the selected backend's completion result. | `GatewayBackendClient` handles backend progress notifications for `call_tool`. -If a progress token matches an in-flight downstream tool call, it optionally -runs the stream-event post hook and forwards the progress notification back to -the downstream client. +RMCP assigns a new progress token to each backend request, so the gateway maps +that backend token to the corresponding downstream token. Request enqueue and +mapping publication are serialized against progress lookup so an immediate +backend notification cannot overtake registration. When a notification matches +an in-flight backend token, the gateway restores the downstream token, optionally +runs the stream-event post hook, and forwards the notification to the downstream +client. `call_backend_tool` also watches the downstream cancellation token. If the downstream call is cancelled before the backend responds, the gateway sends a