diff --git a/.rustfmt.toml b/.rustfmt.toml index 16b844983b..22e59e7d2b 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,6 +1 @@ -unstable_features = true struct_lit_width = 60 -imports_granularity = "Module" -group_imports = "StdExternalCrate" -wrap_comments = true -comment_width = 80 diff --git a/Cargo.lock b/Cargo.lock index 858a9386fb..f0afc23790 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,9 +93,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arboard" @@ -186,7 +186,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -208,18 +208,18 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -251,9 +251,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-config" -version = "1.8.18" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33f815b73a3899c03b380d543532e5865f230dce9678d108dc10732a8682275" +checksum = "1b180a3c8b55960db3426d8964b8745e652466a1a49fe1a2eda828046d30b5e4" dependencies = [ "aws-credential-types", "aws-runtime", @@ -271,7 +271,7 @@ dependencies = [ "bytes", "fastrand", "hex", - "http 1.4.2", + "http 1.5.0", "sha1", "time", "tokio", @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.14" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f20799b373a1be121fe3005fba0c2090af9411573878f224df44b42727fcaf7" +checksum = "e93964ffdaf57857f544be3666a5f57570bb699e934700f11b49708f61bb556e" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -317,9 +317,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.7.5" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c9b9de216a988dd54b754a82a7660cfe14cee4f6782ae4524470972fa0ccb39" +checksum = "c9007227e10b5fed2f3e0a2beff489211e2b5604c400b7a9d5d81ca9d64c24bb" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -333,7 +333,7 @@ dependencies = [ "bytes", "bytes-utils", "fastrand", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "percent-encoding", "pin-project-lite", @@ -343,9 +343,9 @@ dependencies = [ [[package]] name = "aws-sdk-bedrockruntime" -version = "1.135.0" +version = "1.138.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74b780f2f36912bae71b4f4f8ed9a0a88832b4681a1add3caf5ca25dbc8ab2d" +checksum = "8b802a89d3fab0f871a61779d28dc77b363f48dbe9efbef69ba67b6a071b64e0" dependencies = [ "arc-swap", "aws-credential-types", @@ -358,12 +358,13 @@ dependencies = [ "aws-smithy-observability", "aws-smithy-runtime", "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", "aws-types", "bytes", "fastrand", "http 0.2.12", - "http 1.4.2", + "http 1.5.0", "http-body-util", "regex-lite", "tracing", @@ -371,9 +372,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.101.0" +version = "1.105.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b647baea49ff551960b904f905681e9b4765a6c4ea08631e89dc52d8bd3f5896" +checksum = "6ffd0fbe7873cb548a7aa60f9573c268fff94155397fd4f14dc9f1ecaaab8516" dependencies = [ "arc-swap", "aws-credential-types", @@ -384,21 +385,22 @@ dependencies = [ "aws-smithy-observability", "aws-smithy-runtime", "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", "aws-types", "bytes", "fastrand", "http 0.2.12", - "http 1.4.2", + "http 1.5.0", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-ssooidc" -version = "1.103.0" +version = "1.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ae401c65ff288aa7873117fe535cd32b7b1bb0bc43751d28901a1d5f20636b9" +checksum = "175763eb222a46377df7aa257a3bca980ab3e96703fefc8f4d0b8da6ad2e254c" dependencies = [ "arc-swap", "aws-credential-types", @@ -409,21 +411,22 @@ dependencies = [ "aws-smithy-observability", "aws-smithy-runtime", "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", "aws-types", "bytes", "fastrand", "http 0.2.12", - "http 1.4.2", + "http 1.5.0", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-sts" -version = "1.106.0" +version = "1.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c80de7bb7d03e9ca8c9fd7b489f20f3948d3f3be91a7953591347d238115408" +checksum = "dd8b14781dfbff48984017d57167b6ea0b6471c6920ec52b44a2677c7feb3c13" dependencies = [ "arc-swap", "aws-credential-types", @@ -435,21 +438,22 @@ dependencies = [ "aws-smithy-query", "aws-smithy-runtime", "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", "aws-smithy-xml", "aws-types", "fastrand", "http 0.2.12", - "http 1.4.2", + "http 1.5.0", "regex-lite", "tracing", ] [[package]] name = "aws-sigv4" -version = "1.4.5" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae38512beae0ffee7010fc24e7a8a123c53efdfef42a61e80fda4882418dc71" +checksum = "723c2234ad7511ceef63eab016b7ba6ff7c55590fefb96fa8467af014a07309f" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", @@ -461,7 +465,7 @@ dependencies = [ "hex", "hmac 0.13.0", "http 0.2.12", - "http 1.4.2", + "http 1.5.0", "percent-encoding", "sha2 0.11.0", "time", @@ -470,9 +474,9 @@ dependencies = [ [[package]] name = "aws-smithy-async" -version = "1.2.14" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" +checksum = "f02e407fb3b54891734224b9ffac8a71fdd35f542500fa1af95754a6b2beb316" dependencies = [ "futures-util", "pin-project-lite", @@ -481,9 +485,9 @@ dependencies = [ [[package]] name = "aws-smithy-eventstream" -version = "0.60.21" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d8391e65fcea47c586a22e1a41f173b38615b112b2c6b7a44e80cec3e6b706" +checksum = "5a9381123ab62d20c13082b151f30f962a3b112b727345394536dfa39a482944" dependencies = [ "aws-smithy-types", "bytes", @@ -492,9 +496,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.63.6" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" +checksum = "37843d9add67c3aff5856f409c6dc315d3cdff60f9c0cb5b670dab1e9920306d" dependencies = [ "aws-smithy-eventstream", "aws-smithy-runtime-api", @@ -503,7 +507,7 @@ dependencies = [ "bytes-utils", "futures-core", "futures-util", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "http-body-util", "percent-encoding", @@ -514,9 +518,9 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.1.12" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a2f165a7feee6f263028b899d0a181987f4fa7179a6411a32a439fba7c5f769" +checksum = "635d23afda0a6ab48d666c4d447c4873e8d1e83518a2be2093122397e50b838e" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -536,9 +540,9 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.62.7" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "701a947f4797e52a911e114a898667c746c39feea467bbd1abd7b3721f702ffa" +checksum = "3dc65a121adb4b33729919fcfa14fa36fb33c1555a8f06bb0e2188dbfdc1d9ef" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-schema", @@ -547,28 +551,31 @@ dependencies = [ [[package]] name = "aws-smithy-observability" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06c2315d173edbf1920da8ba3a7189695827002e4c0fc961973ab1c54abca9c" +checksum = "8e86338c869539a581bf161247762a6e87f92c5c075060057b5ed6d06632ed0c" dependencies = [ "aws-smithy-runtime-api", ] [[package]] name = "aws-smithy-query" -version = "0.60.15" +version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a56d79744fb3edb5d722ef79d86081e121d3b9422cb209eb03aea6aa4f21ebd" +checksum = "512346c7212ab7436df2d77a16d976a468ae44a418835511d2a69269810aaf62" dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", + "aws-smithy-xml", "urlencoding", ] [[package]] name = "aws-smithy-runtime" -version = "1.11.3" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e6f5caf6fea86f8c2206541ab5857cfcda9013426cdbe8fa0098b9e2d32182" +checksum = "07505b34e8f4b3591a4fa69e9792b52289b95488dbbc68c3c0075b7bedb245e1" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -580,7 +587,7 @@ dependencies = [ "bytes", "fastrand", "http 0.2.12", - "http 1.4.2", + "http 1.5.0", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", @@ -592,16 +599,16 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.12.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9db177daa6ba8afb9ee1aefcf548c907abcf52065e394ee11a92780057fe0e8c" +checksum = "3b98f2e1fd67ec06618f9c291e5e495a468e60519e44c9c1979cd0521f3affdb" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api-macros", "aws-smithy-types", "bytes", "http 0.2.12", - "http 1.4.2", + "http 1.5.0", "pin-project-lite", "tokio", "tracing", @@ -610,37 +617,37 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api-macros" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7396fd9500589e62e460e987ecb671bad374934e55ec3b5f498cc7a8a8a7b7" +checksum = "221eaa237ddf1ca79b60d1372aad77e47f9c0ea5b3ce5099da8c61d027dc77b3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "aws-smithy-schema" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7442cb268338f0eb8278140a107c046756aa01093d8ef5e99628d34ae09c94f5" +checksum = "7d56e0a4e53127a632224e43633b0fe045fa9e1e3cfc68b9830f1115e103f910" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", - "http 1.4.2", + "http 1.5.0", ] [[package]] name = "aws-smithy-types" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b42fcf341259d85ca10fac9a2f6448a8ec691c6955a18e45bc3b71a85fab85" +checksum = "d6dc683efb34b9e755675b37fedbe0103141e5b6df7bdc9eb6967756a8c167d8" dependencies = [ "base64-simd", "bytes", "bytes-utils", "http 0.2.12", - "http 1.4.2", + "http 1.5.0", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", @@ -655,18 +662,21 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.60.15" +version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce02add1aa3677d022f8adf81dcbe3046a95f17a1b1e8979c145cd21d3d22b3" +checksum = "ce84f71c72fee2cbbadde6e7d082f5fb466e3a84733855295fa7aafd1b31b7d8" dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", "xmlparser", ] [[package]] name = "aws-types" -version = "1.3.16" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16bf10b03a3c01e6b3b7d47cd964e873ffe9e7d4e80fad16bd4c077cb068531" +checksum = "eec1cd5469f328c782dc3e33d4153cf118a54e33cbb3356d60d16f89883e1f94" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -686,7 +696,7 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "http-body-util", "itoa", @@ -710,7 +720,7 @@ checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ "bytes", "futures-core", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "http-body-util", "mime", @@ -758,6 +768,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b25655df2c3cdd83c5e5b293b88acd880332b2ddadd7c30ac43144fdc0033da9" + [[package]] name = "base64-simd" version = "0.8.0" @@ -783,6 +799,21 @@ dependencies = [ "serde", ] +[[package]] +name = "bisync" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5020822f6d6f23196ccaf55e228db36f9de1cf788052b37992e17cbc96ec41a7" +dependencies = [ + "bisync_macros", +] + +[[package]] +name = "bisync_macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d21f40d350a700f6aa107e45fb26448cf489d34794b2ba4522181dc9f1173af6" + [[package]] name = "bitflags" version = "1.3.2" @@ -827,9 +858,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.3" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" +checksum = "1f7dc094d718f2e1c1559ad110e27eeaae14a5465d3d56dd6dbd793079fbd530" dependencies = [ "memchr", "regex-automata", @@ -862,9 +893,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" dependencies = [ "serde", ] @@ -930,13 +961,13 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfb" -version = "0.7.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +checksum = "a347dcabdae9c31b0825fd6a8bed285ec9c2acb89c47827126d52fa4f59cece3" dependencies = [ - "byteorder", "fnv", "uuid", + "web-time", ] [[package]] @@ -984,9 +1015,9 @@ checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" [[package]] name = "clap" -version = "4.6.1" +version = "4.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7" dependencies = [ "clap_builder", "clap_derive", @@ -994,9 +1025,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" dependencies = [ "anstream", "anstyle", @@ -1006,23 +1037,23 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.6.5" +version = "4.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772" +checksum = "b1f84a88507dbd05c695f2cb5e8558e747179134005e9893882dec964190ed89" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.6.1" +version = "4.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -1076,7 +1107,7 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -1108,9 +1139,9 @@ checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" [[package]] name = "config" -version = "0.15.24" +version = "0.15.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d0237145f33580b89724f75d16950efd3e2c91b2d823917ecb69ec7f84f0" +checksum = "b85f248a4de22d204ceabc6299d89d2c70fbd7f09fea53c06c852369652d8139" dependencies = [ "async-trait", "convert_case 0.6.0", @@ -1128,9 +1159,9 @@ dependencies = [ [[package]] name = "console" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ "encode_unicode", "libc", @@ -1311,7 +1342,7 @@ dependencies = [ "proc-macro2", "quote", "strict", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1489,7 +1520,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1503,7 +1534,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1516,7 +1547,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1527,7 +1558,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1538,7 +1569,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1549,14 +1580,14 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core 0.23.0", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "dashmap" -version = "6.1.0" +version = "6.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1604,7 +1635,7 @@ checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1625,7 +1656,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1635,7 +1666,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1657,7 +1688,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.118", + "syn 2.0.119", "unicode-xid", ] @@ -1670,7 +1701,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1709,14 +1740,14 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "diesel" -version = "2.3.10" +version = "2.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29fe29a87fb84c631ffb3ba21798c4b1f3a964701ba78f0dce4bf8668562ec88" +checksum = "e54d1f576cd3a3460f212a4615fd12ce1b6303c095b79a44449ffbe627753dc1" dependencies = [ "chrono", "diesel_derives", @@ -1737,7 +1768,7 @@ dependencies = [ "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1757,7 +1788,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe2444076b48641147115697648dc743c2c00b61adade0f01ce67133c7babe8c" dependencies = [ - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1828,7 +1859,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1849,7 +1880,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1893,7 +1924,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1905,7 +1936,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1974,7 +2005,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2001,7 +2032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2031,7 +2062,7 @@ dependencies = [ "indexmap 2.14.0", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2054,7 +2085,7 @@ dependencies = [ "deunicode", "dummy", "either", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] @@ -2090,7 +2121,7 @@ checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2143,6 +2174,18 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + [[package]] name = "fixedbitset" version = "0.5.7" @@ -2258,7 +2301,7 @@ dependencies = [ "pretty_assertions", "regex", "reqwest 0.12.28", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", "serde_yml 0.0.13", @@ -2266,7 +2309,7 @@ dependencies = [ "strum", "strum_macros 0.28.0", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tokio-stream", "tonic", @@ -2298,13 +2341,13 @@ dependencies = [ "forge_domain", "is_ci", "pretty_assertions", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", "strum_macros 0.28.0", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", - "toml_edit 0.25.12+spec-1.1.0", + "toml_edit 0.25.13+spec-1.1.0", "tracing", "url", ] @@ -2332,7 +2375,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "base64 0.22.1", + "base64 0.23.0", "chrono", "convert_case 0.11.0", "derive-getters", @@ -2354,13 +2397,13 @@ dependencies = [ "nom", "pretty_assertions", "regex", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", "serde_yml 0.0.13", "strum", "strum_macros 0.28.0", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tokio-stream", "tracing", @@ -2392,7 +2435,7 @@ dependencies = [ "pin-utils", "reqwest 0.12.28", "rocket", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", ] @@ -2402,7 +2445,7 @@ version = "0.1.0" dependencies = [ "futures", "futures-core", - "http 1.4.2", + "http 1.5.0", "nom", "pin-project-lite", "reqwest 0.11.27", @@ -2422,7 +2465,7 @@ dependencies = [ "pretty_assertions", "sha2 0.11.0", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", ] @@ -2435,7 +2478,7 @@ dependencies = [ "aws-config", "aws-credential-types", "backon", - "base64 0.22.1", + "base64 0.23.0", "bstr", "bytes", "cacache", @@ -2457,20 +2500,20 @@ dependencies = [ "futures", "glob", "google-cloud-auth", - "http 1.4.2", + "http 1.5.0", "libsqlite3-sys", "oauth2", "open", "pretty_assertions", "reqwest 0.12.28", "rmcp", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", "serde_urlencoded", "serial_test", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tonic", "tracing", @@ -2483,11 +2526,11 @@ version = "0.1.0" dependencies = [ "pretty_assertions", "regex", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", "serde_json5", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] @@ -2536,7 +2579,7 @@ dependencies = [ "open", "pretty_assertions", "regex", - "rustls 0.23.41", + "rustls 0.23.43", "rustyline", "serde", "serde_json", @@ -2546,11 +2589,11 @@ dependencies = [ "strum_macros 0.28.0", "tempfile", "terminal_size", - "thiserror 2.0.18", + "thiserror 2.0.19", "tiny_http", "tokio", "tokio-stream", - "toml_edit 0.25.12+spec-1.1.0", + "toml_edit 0.25.13+spec-1.1.0", "tracing", "update-informer", "url", @@ -2590,7 +2633,7 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "backon", - "base64 0.22.1", + "base64 0.23.0", "bytes", "chrono", "derive_more", @@ -2623,13 +2666,13 @@ dependencies = [ "prost-types", "regex", "reqwest 0.12.28", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", "serial_test", "strum", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tokio-stream", "tonic", @@ -2665,7 +2708,7 @@ dependencies = [ "async-stream", "async-trait", "backon", - "base64 0.22.1", + "base64 0.23.0", "bstr", "bytes", "chrono", @@ -2688,7 +2731,7 @@ dependencies = [ "grep-searcher", "handlebars", "html2md", - "http 1.4.2", + "http 1.5.0", "humantime", "ignore", "infer", @@ -2706,7 +2749,7 @@ dependencies = [ "strum", "strum_macros 0.28.0", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tokio-stream", "tonic", @@ -2740,7 +2783,7 @@ dependencies = [ "forge_domain", "indicatif", "pretty_assertions", - "rand 0.10.1", + "rand 0.10.2", "terminal_size", "tokio", "unicode-width 0.2.2", @@ -2777,7 +2820,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -2792,7 +2835,7 @@ dependencies = [ "derive_more", "dirs", "forge_domain", - "http 1.4.2", + "http 1.5.0", "lazy_static", "machineid-rs", "posthog-rs", @@ -2850,9 +2893,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218" dependencies = [ "futures-channel", "futures-core", @@ -2865,9 +2908,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" dependencies = [ "futures-core", "futures-sink", @@ -2875,15 +2918,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" [[package]] name = "futures-executor" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458" dependencies = [ "futures-core", "futures-task", @@ -2892,19 +2935,19 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2920,15 +2963,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" [[package]] name = "futures-timer" @@ -2938,9 +2981,9 @@ checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" dependencies = [ "futures-channel", "futures-core", @@ -3053,7 +3096,7 @@ checksum = "3b8281789edecfe1c6dab6312577f5ec0f7f8b860cad70156b8fc70ebedc786d" dependencies = [ "heck", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -3064,9 +3107,9 @@ checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "gix" -version = "0.85.0" +version = "0.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8b2e38ebfc4484dfef8580ddcaf8abb7285e6f3eb6413ff6775d104ae96ca6" +checksum = "bb3790fd8981cba7949f1ba924ef865d902df731627bc5998d14164063892fce" dependencies = [ "gix-actor", "gix-archive", @@ -3116,19 +3159,20 @@ dependencies = [ "gix-worktree", "gix-worktree-state", "gix-worktree-stream", + "gix-zlib", "nonempty", "parking_lot", "regex", "signal-hook 0.4.4", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-actor" -version = "0.41.1" +version = "0.41.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc998b8f746dda8565450d08a63b792ced9165d8c27a1ed3f02799ec6a7820f" +checksum = "33f9308ad6fd35b2a865cbe4117ac61b2be59e4a9ef1621c7a9794f7c8e52c5b" dependencies = [ "bstr", "gix-date", @@ -3137,9 +3181,9 @@ dependencies = [ [[package]] name = "gix-archive" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1303ed647e048d2bbecb9fd3a627d753e73f883a20ad5c039b30c7cbc85e217f" +checksum = "6760ef6ef4edfa6449918977d59518ff209676f47e89bdce87a36a50be35e834" dependencies = [ "bstr", "gix-date", @@ -3150,35 +3194,35 @@ dependencies = [ [[package]] name = "gix-attributes" -version = "0.33.2" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39b40888d0ed415c0744a6cdc61eebf0304c9d26ab726725b718443c322e5ba4" +checksum = "c31c593692ebdc1e38858d9a2b56f6a594c501e24a38971fe6685571f5a07be0" dependencies = [ "bstr", + "gix-features", "gix-glob", "gix-path", "gix-quote", "gix-trace", - "kstring", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", "unicode-bom", ] [[package]] name = "gix-bitmap" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ebef0c26ad305747649e727bbcd56a7b7910754eb7cea88f6dff6f93c51283" +checksum = "7cd1d118d0f5d88b96e6f6e13b566475fef4797ead4a02c26fed36c1375066f7" dependencies = [ "gix-error", ] [[package]] name = "gix-blame" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf49c828ad8a8a674d52caaf0b61fdee1f20cc46c15439ca3d875ef3b6f64bdc" +checksum = "b06d20ff0e88ada2dd852b3852727b664ec9baefdf653d1d4e722e858c52cd17" dependencies = [ "gix-commitgraph", "gix-date", @@ -3191,14 +3235,14 @@ dependencies = [ "gix-traverse", "gix-worktree", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-chunk" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9faee47943b638e58ddd5e275a4906ad3e4b6c8584f1d41bd18ab9032ec52afb" +checksum = "b2a871e5cab12ba568845714473505deefffb3c04eb47f4708ce344cd459c1cc" dependencies = [ "gix-error", ] @@ -3218,9 +3262,9 @@ dependencies = [ [[package]] name = "gix-commitgraph" -version = "0.37.1" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f675d0df484a7f6a47e64bd6f311af489d947c0323b0564f36d14f3d7762abb" +checksum = "a2cd7f054ae2727223fe46dd39c012f066b12f532962d336d29ee193261787da" dependencies = [ "bstr", "gix-chunk", @@ -3232,9 +3276,9 @@ dependencies = [ [[package]] name = "gix-config" -version = "0.58.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a29bf266c4cdaf759e535c24ad4ce655b987aeb6911075643403cc7cc5ade583" +checksum = "103d11bef95c467577ecfa8b7b86a22e65af3507b2c9bfa3809a4afbae7df301" dependencies = [ "bstr", "gix-config-value", @@ -3243,29 +3287,30 @@ dependencies = [ "gix-path", "gix-ref", "gix-sec", + "gix-utils", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", "unicode-bom", ] [[package]] name = "gix-config-value" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed42168329552f6c2e5df09665c104199d45d84bedb53683738a49b57fe1baab" +checksum = "9f813e312a3f7f327187823cd4c754a3e4d948c98907d11e8f37554a2b6b8059" dependencies = [ "bitflags 2.11.0", "bstr", "gix-path", "libc", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-credentials" -version = "0.38.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40cd22f0dd71988be12d6e78b1709de2370e1957c5f107ff31e56caeba3745d" +checksum = "73b637f873d5f9aa67e672c1b23741a18e046d33028017adede32f4b4087a2e7" dependencies = [ "bstr", "gix-command", @@ -3276,14 +3321,14 @@ dependencies = [ "gix-sec", "gix-trace", "gix-url", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-date" -version = "0.15.5" +version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d63f9e28b59ddeb1a1eb9e5cf986a9222b5d484947445edbc20473939cc7fd0" +checksum = "7e47b9e8cdc688296609b706428de570f88b1e0eed7156dde7b4a89d26fa4567" dependencies = [ "bstr", "gix-error", @@ -3293,9 +3338,9 @@ dependencies = [ [[package]] name = "gix-diff" -version = "0.65.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92c6d56c94edf92d78203a1cd416f770e35e10b6955ede6b9d7d0c22ff88a5f3" +checksum = "fee7d89a3c507491cdfc57a1d1e0e300214720b4f7709ebc253e422f99822bfc" dependencies = [ "bstr", "gix-attributes", @@ -3312,14 +3357,14 @@ dependencies = [ "gix-trace", "gix-traverse", "gix-worktree", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-dir" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20098fba2b9c6e29361ccb4c0379d42dfb81fc7f86f7ab11f2dff4528c0bf01f" +checksum = "f24bc78f283946ac64757c8a61ffa71f0230aa1e8d98cbb0771db479871dd5b6" dependencies = [ "bstr", "gix-discover", @@ -3332,14 +3377,14 @@ dependencies = [ "gix-trace", "gix-utils", "gix-worktree", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-discover" -version = "0.53.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d624d5b23b10c1d85337645227abe353ac95ab8ff66a7bdd5ce689b2db33a722" +checksum = "b9f517766fa1101dfe2606c1a19a8ffa699099030995a9194445446dfe261bdf" dependencies = [ "bstr", "dunce", @@ -3347,23 +3392,23 @@ dependencies = [ "gix-path", "gix-ref", "gix-sec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-error" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57831e199be480af90dcd7e459abed8a174c09ec9a6e2cc8f7ca6c54598b06b" +checksum = "4a9292309fd944e71b2a3c96d3c03a6feb8852db646febdde7cbb9f79cb5f329" dependencies = [ "bstr", ] [[package]] name = "gix-features" -version = "0.48.1" +version = "0.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1849ae154d38bc403185be14fa871e38e3c93ee606875d94e207fdb9fba52dbc" +checksum = "20aa09e83a48dc02c5f5f08578aa79d3ab1bab4618b8c362f88684645a02bdcc" dependencies = [ "bytes", "bytesize", @@ -3376,16 +3421,14 @@ dependencies = [ "once_cell", "parking_lot", "prodash", - "thiserror 2.0.18", "walkdir", - "zlib-rs", ] [[package]] name = "gix-filter" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6644fb2ef97928c278675b239f366b457103d7e436f811d27331a8daf212759c" +checksum = "5e7b5dbf524d97e839f642930c76d7f011c0791e7d11d8148989ac5af7c76aa8" dependencies = [ "bstr", "encoding_rs", @@ -3399,28 +3442,27 @@ dependencies = [ "gix-trace", "gix-utils", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-fs" -version = "0.21.2" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cdff46db8798e47e2f727d84b9379aac5add3dd3d9d0b07bb4d7d5d640771fe" +checksum = "865cf13fcaf5455220546cb9607c416bd1be9a6caafd143655a362fdeab64e80" dependencies = [ "bstr", - "fastrand", "gix-features", "gix-path", "gix-utils", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-glob" -version = "0.26.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1fcb8ef5b16bcf874abe9b68d8abb3c0493c876d367ab824151f30a0f3f3756" +checksum = "421e92a711554fa5827d1b0599d3389acdd0f6729e97a8c5a57d79af1e50bf36" dependencies = [ "bitflags 2.11.0", "bstr", @@ -3430,21 +3472,21 @@ dependencies = [ [[package]] name = "gix-hash" -version = "0.25.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0926d3819c837750b4e03c7754901e73f68b8c9b690753a6372a1bed4eedce" +checksum = "13adaa73415fd6c902310923f68d0b98e8cecf14b33ea58c02cc387cee56f54e" dependencies = [ "faster-hex", "gix-features", "sha1-checked", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-hashtable" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e261d54091f0d1c729bc83f54548c071bdec60a697de1e58e88bdfd7a99d24e" +checksum = "78fccd6fea3bcf0b39c076bae60ae49b08daaf538b950202101a981f9d3c01d3" dependencies = [ "gix-hash", "hashbrown 0.17.1", @@ -3453,9 +3495,9 @@ dependencies = [ [[package]] name = "gix-ignore" -version = "0.21.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d491bab9bf2c9f341dc754f425c31d5d3f63aca615312167b82e1deeaca97d8d" +checksum = "12cff8e8aa125e39377456073e63df3334d9e5741372ddcc226198015076dda2" dependencies = [ "bstr", "gix-glob", @@ -3466,19 +3508,19 @@ dependencies = [ [[package]] name = "gix-imara-diff" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b305d85504de270ad3525d726a6b69cc59ee7b2269b014387651107ab9f0755b" +checksum = "1a791e6620676a875f362f3156ed213e73ca099a09bf992c18812abe65cc37b1" dependencies = [ "bstr", - "hashbrown 0.17.1", + "hashbrown 0.16.1", ] [[package]] name = "gix-index" -version = "0.53.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36d45f82ec5a4d7542ea595e9ad16e03e26c8cb4f221e5bc9fcdcf469f63a681" +checksum = "5009c4e7e9f9b4cfaaab1153e49133eb04d79c015b5702d6c3d2ab94271a89c6" dependencies = [ "bitflags 2.11.0", "bstr", @@ -3499,25 +3541,25 @@ dependencies = [ "memmap2", "rustix 1.1.4", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-lock" -version = "23.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3bc074e5723027b482dcd9ab99d95804a53742f6de812d0172fbba4a186c1" +checksum = "d4c69157820343bf1c6e4b88b9808e920900de02e18aaf5862b30ada43814848" dependencies = [ "gix-tempfile", "gix-utils", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-mailmap" -version = "0.33.1" +version = "0.33.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195fd20808055824531be2fd0d34136d900e5fbca3ffb0a3c07e8beeefb9c828" +checksum = "a824767d38b81475059cb01f5020a13fb96e7ed6bbf9851c7112b46ada78db48" dependencies = [ "bstr", "gix-actor", @@ -3527,9 +3569,9 @@ dependencies = [ [[package]] name = "gix-negotiate" -version = "0.33.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d6081882a5f575ace9f53924a7c85f69bbd0f96071b982df12f258ab338cc9" +checksum = "2fa5aa789990f124e4f559b142cecfb60662cb4ae17006684ea9d668f4f07689" dependencies = [ "bitflags 2.11.0", "gix-commitgraph", @@ -3541,9 +3583,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.62.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "019b38afc3eac1e41f9fe09a327664b313ba4a120fa5f40e3678795d0e42783e" +checksum = "0e48c235e7f886eb819fc878af75be889333dd3c38bee02ed7af48ae2cf596c4" dependencies = [ "bstr", "gix-actor", @@ -3555,14 +3597,14 @@ dependencies = [ "gix-validate", "itoa", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-odb" -version = "0.82.0" +version = "0.83.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fadc59f6fa0f9dd445eceee61060a2b59ca557f48da9fc677f567db535b782a" +checksum = "8dd494ffb5037e62b8220109e894d2861ff2150a2cacbfccdba57ae1ebab2b96" dependencies = [ "arc-swap", "gix-features", @@ -3573,17 +3615,18 @@ dependencies = [ "gix-pack", "gix-path", "gix-quote", + "gix-zlib", "memmap2", "parking_lot", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-pack" -version = "0.72.0" +version = "0.73.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3e7f1726cd2c0cd1cf1fc20be8a8e623f0b163f1f8d6fc836cfb9bc8cd758b" +checksum = "6d5446127b269706e85998065267ddd2ccc3550179da6780b22fe496175ccb20" dependencies = [ "clru", "gix-chunk", @@ -3593,41 +3636,42 @@ dependencies = [ "gix-hashtable", "gix-object", "gix-path", + "gix-zlib", "memmap2", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", "uluru", ] [[package]] name = "gix-packetline" -version = "0.21.5" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b217dd0ee0c4021ecf169a4a519b1b4f80d15e3f3765f3dc466223dc0ac891d7" +checksum = "3766025c72319c4accdd854a18e6f0dd176c8eb0f3bc8a60a7765be2b50cabf2" dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-path" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa6ac14cd14939ea94a496ce7460daa6511c09f5b84757e9cfc6f9c8d0f93a6" +checksum = "1ed3e8d7a82e886e17a72e03d4ba0c13db6f2219b6cd4e2900b4cae426ec20c9" dependencies = [ "bstr", "gix-trace", "gix-validate", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-pathspec" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3050783b41ee11511e1e8fb35623df81806194f4030395f14f48ea37c2798c9f" +checksum = "49f6fa5f8007f008187c3f60b4373209ca83d1cc947f35ede03e16cd15a4d137" dependencies = [ "bitflags 2.11.0", "bstr", @@ -3635,28 +3679,29 @@ dependencies = [ "gix-config-value", "gix-glob", "gix-path", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-prompt" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee604d7746080ae7e1023bf47204bcc2c5f307bfbe2306a3c90b1bfd1a2c6d8" +checksum = "5cb1f1eb92d6f4c9d4c105a6ca912cff637fbd5cacbcbafa5deccd88bfaa3565" dependencies = [ "gix-command", "gix-config-value", "parking_lot", "rustix 1.1.4", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-protocol" -version = "0.63.0" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978468bae4ea2df20c72db3b20d0bdb548a0c1090b85a83643b553e6e0e041f2" +checksum = "dede40e89c1e90f548415f50636bb051f6d9c60f68b8b710bc07825722d19588" dependencies = [ + "bisync", "bstr", "gix-date", "gix-features", @@ -3665,9 +3710,8 @@ dependencies = [ "gix-shallow", "gix-transport", "gix-utils", - "maybe-async", "nonempty", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] @@ -3683,9 +3727,9 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.65.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bbfbce1dfd7d7f8469ddef6d3518376aff664348f153cbe0fc3e58ef993d24e" +checksum = "eeb0c90a8f6202ceaaa22996cbf837c943ccb2d8af9ff3490f0758305e6b7883" dependencies = [ "gix-actor", "gix-features", @@ -3698,14 +3742,14 @@ dependencies = [ "gix-utils", "gix-validate", "memmap2", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-refspec" -version = "0.43.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc36a4fb1a1540b59cf2da498783080743fa274b02a3f19ca444fc4015a9d4f" +checksum = "7406282cc0259b51f6aee299ca3d31279a020530363152a2e6c96e8a7f7bbc83" dependencies = [ "bstr", "gix-error", @@ -3714,14 +3758,14 @@ dependencies = [ "gix-revision", "gix-validate", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-revision" -version = "0.47.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "885075c3c21eb9c06e0be3b3728ba5932c04e1c1011dcee7c81801980e3e986f" +checksum = "e55e09d4a1ecf2beecc8c09cafcad37979e805b31f588b0e957e191df5783681" dependencies = [ "bitflags 2.11.0", "bstr", @@ -3738,9 +3782,9 @@ dependencies = [ [[package]] name = "gix-revwalk" -version = "0.33.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f11fe7ca2585193d3d70bbe0be175a2008d883a704cc7a55e454e113e689455" +checksum = "36c113c0a53294dc6280ffc06cbcc4f50f820397e97d6a00b429a44b8db26e29" dependencies = [ "gix-commitgraph", "gix-date", @@ -3749,14 +3793,14 @@ dependencies = [ "gix-hashtable", "gix-object", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-sec" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8519976e4c7e486270740a5400369f37940779b80bd1377d94cfa1125d01b3" +checksum = "af4fe6c152c1d50aea36f299825702cd37e303307832fec1d0fdd5844e47ce2f" dependencies = [ "bitflags 2.11.0", "gix-path", @@ -3766,22 +3810,22 @@ dependencies = [ [[package]] name = "gix-shallow" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a292fc2fe548c5dfa575479d16b445b0ddf1dd2f56f1fec6aed386f82553cd97" +checksum = "1ecc9f4b40537043e4bbd7d3d1760e74fb8e7b07a546166b558acaa73ad97f4a" dependencies = [ "bstr", "gix-hash", "gix-lock", "nonempty", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-status" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aec3293f75db1212f99217832cbc70c30faeb95cefc97c7f1a17fd3bcf13a72e" +checksum = "5f83b1c74e69b90411fbfe89ccebc47aa49457ce4eb9b942b1311258fc863d22" dependencies = [ "bstr", "filetime", @@ -3796,15 +3840,17 @@ dependencies = [ "gix-path", "gix-pathspec", "gix-worktree", + "hashbrown 0.16.1", "portable-atomic", - "thiserror 2.0.18", + "thiserror 2.0.19", + "windows-sys 0.61.2", ] [[package]] name = "gix-submodule" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f9f594f7cbda0b38ba6b633b3e9a7b7901acdc5d27bc186a16633800cd1ac8" +checksum = "5fd98077a56d08886112e6b08dc94076d03539f4bc0b9d7880e4be2b8a640d8c" dependencies = [ "bstr", "gix-config", @@ -3812,16 +3858,16 @@ dependencies = [ "gix-pathspec", "gix-refspec", "gix-url", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-tempfile" -version = "23.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "691ea1e31435c7e7d4d04705ec9d1c0d9482c46b2acf512bc723939d8f0af7fb" +checksum = "b675b920bd5a61d17ad542772f03ec34c60feb8ff683e1560c03ae967363731e" dependencies = [ - "dashmap 6.1.0", + "dashmap 6.2.1", "gix-fs", "libc", "parking_lot", @@ -3832,31 +3878,32 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44dc45eae785c0eb14173e0f152e6e224dcf4d45b6a6999a3aed22af541ad678" +checksum = "be3eb81d9dc914335923e50d52829c551feefd6a72d176c4130c546b67a60814" [[package]] name = "gix-transport" -version = "0.57.2" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186874f7ad1fb2f9a2f2aa9c2dabc7f9dd087bef74c1a0eee2b4a9cf0248fcb3" +checksum = "b7c1bcf30081eb8ab04540a5795c67a2fcb22cb2e976e8b1a4ea657b1ed61469" dependencies = [ "bstr", "gix-command", "gix-features", "gix-packetline", + "gix-path", "gix-quote", "gix-sec", "gix-url", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-traverse" -version = "0.59.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5062cca8f2977565bbaf666ec31dbdb9bc9d9293beb65f9bec52e6c1121b62a1" +checksum = "008c5cd879e46e86b5c2469e633611978b18775d53d05668d691bc13088bd409" dependencies = [ "bitflags 2.11.0", "gix-commitgraph", @@ -3866,49 +3913,52 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-url" -version = "0.36.1" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bb01ec69d55e82ccb7a19e264501ead4e6aac38463a8cebfdd81e22bb67ab2" +checksum = "42d10e53b8eae21ee601687f47bbbd6cb2ed7162cb4c1cafdd422fb7ec64cbee" dependencies = [ "bstr", "gix-path", + "gix-utils", "percent-encoding", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-utils" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c50966184123caf580ffa64e28031a878597f1c7fceb8fe19566c38eb1b771" +checksum = "b1795bd2a970ca8b2185318c2abb97d955c71992f1cf28de73ad3b593a9f3ce8" dependencies = [ "bstr", "fastrand", + "getrandom 0.4.2", "unicode-normalization", ] [[package]] name = "gix-validate" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc6fc771c4063ba7cd2f47b91fb6076251c6a823b64b7fe7b8874b0fe4afae3" +checksum = "9a034e84d1e04e1b1f20f51f12491da230b6ac8b925d0c8e1b89bcd87a7c5ccc" dependencies = [ "bstr", ] [[package]] name = "gix-worktree" -version = "0.54.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92399ed66f259592050c6ed9dc80105e095a2f8e87e6b83d98aa2e21d8e27036" +checksum = "31eb8e675122e83585e461fe28f68ff8c5ed55b49017b697e7e76423ff973424" dependencies = [ "bstr", "gix-attributes", + "gix-features", "gix-fs", "gix-glob", "gix-hash", @@ -3921,9 +3971,9 @@ dependencies = [ [[package]] name = "gix-worktree-state" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f926b6a249bdb0086b307c704b7abd9d643e08f98040efe6467f00bb6d2ef5" +checksum = "bc47372fc12b9fbea51b257bcc8d4970326cf5c7e42135bbfb5d72871bb30bd4" dependencies = [ "bstr", "gix-features", @@ -3934,14 +3984,14 @@ dependencies = [ "gix-path", "gix-worktree", "io-close", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] name = "gix-worktree-stream" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f3a878c89a05470ad98c644b0015777c530da24854dd29e41fe4f41176840f" +checksum = "3b088c8724e7be120c4798dd86925cf05332c9d356a463542578600c50c7a549" dependencies = [ "gix-attributes", "gix-error", @@ -3955,11 +4005,21 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "gix-zlib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e8813f5579b3075ff9c90f7c59cd2b62b4ebb639361f0911648b22d7446cc7c" +dependencies = [ + "thiserror 2.0.19", + "zlib-rs", +] + [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "globset" @@ -3988,9 +4048,9 @@ dependencies = [ [[package]] name = "google-cloud-auth" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a300d4011cb53573eafe2419630d303ced54aab6c194a6d9e4156de375800372" +checksum = "a3494870d06f3cbbb3561ada6f234982549e3a2fb31e719ef258e6eadb9ae09a" dependencies = [ "async-trait", "aws-lc-rs", @@ -4000,16 +4060,16 @@ dependencies = [ "google-cloud-gax", "hex", "hmac 0.13.0", - "http 1.4.2", + "http 1.5.0", "jsonwebtoken", "reqwest 0.13.4", "rustc_version", - "rustls 0.23.41", + "rustls 0.23.43", "rustls-pki-types", "serde", "serde_json", "sha2 0.11.0", - "thiserror 2.0.18", + "thiserror 2.0.19", "time", "tokio", "url", @@ -4017,28 +4077,28 @@ dependencies = [ [[package]] name = "google-cloud-gax" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f60f45dd97ff91cedfcb6b2b9f860d3d84739386c3557027687c52cc0e698fd" +checksum = "3103a4a9013f1aed573ca56e19a9680b0211643a99ea85caf524b397d6be8be3" dependencies = [ "bytes", "futures", "google-cloud-rpc", "google-cloud-wkt", - "http 1.4.2", + "http 1.5.0", "pin-project", - "rand 0.10.1", + "rand 0.10.2", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", ] [[package]] name = "google-cloud-rpc" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b177796075b7bfc02bf2e405db665ee850a924fa44cedfc5282b473c5ab203" +checksum = "e2162c08a89118130979ba261080e960e44cdcb2d6e2ab8ca9b1da245285d353" dependencies = [ "bytes", "google-cloud-wkt", @@ -4049,16 +4109,16 @@ dependencies = [ [[package]] name = "google-cloud-wkt" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e0186e2221bf82c5296500251b4650b111172c324984159a0de9f6bcaa18a5" +checksum = "46df1fcc3ab69164af3f4199ed21f45b5dbc56d9f03211eb4fa20116d442364b" dependencies = [ "base64 0.22.1", "bytes", "serde", "serde_json", "serde_with", - "thiserror 2.0.18", + "thiserror 2.0.19", "time", "url", ] @@ -4070,7 +4130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3563a3eb8bacf11a0a6d93de7885f2cca224dddff0114e4eb8053ca0f1918acd" dependencies = [ "serde", - "thiserror 2.0.18", + "thiserror 2.0.19", "yaml-rust2 0.10.4", ] @@ -4098,9 +4158,9 @@ dependencies = [ [[package]] name = "grep-searcher" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac63295322dc48ebb20a25348147905d816318888e64f531bfc2a2bc0577dc34" +checksum = "72348823a0eafc4bc2e9051064f28b5b42cc100b571b3a35d67918d711efcbc6" dependencies = [ "bstr", "encoding_rs", @@ -4141,7 +4201,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.4.2", + "http 1.5.0", "indexmap 2.14.0", "slab", "tokio", @@ -4173,7 +4233,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] @@ -4292,7 +4352,7 @@ dependencies = [ "once_cell", "rand 0.9.4", "ring", - "thiserror 2.0.18", + "thiserror 2.0.19", "tinyvec", "tokio", "tracing", @@ -4315,7 +4375,7 @@ dependencies = [ "rand 0.9.4", "resolv-conf", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tracing", ] @@ -4349,12 +4409,9 @@ dependencies = [ [[package]] name = "html-escape" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" -dependencies = [ - "utf8-width", -] +checksum = "46c1ff2d1cbf39efe5af0900ced8a069b5e61557a17544eb0c4a50239937389e" [[package]] name = "html2md" @@ -4381,7 +4438,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -4397,9 +4454,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -4423,7 +4480,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.4.2", + "http 1.5.0", ] [[package]] @@ -4434,7 +4491,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "pin-project-lite", ] @@ -4459,9 +4516,9 @@ checksum = "eaec953f16e5bcf6b8a3cb3aa959b17e5577dbd2693e94554c462c08be22624b" [[package]] name = "humantime" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" [[package]] name = "hybrid-array" @@ -4507,7 +4564,7 @@ dependencies = [ "futures-channel", "futures-core", "h2 0.4.13", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "httparse", "httpdate", @@ -4539,10 +4596,10 @@ version = "0.27.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2b52f86d1d4bc0d6b4e6826d960b1b333217e07d36b882dca570a5e1c48895b" dependencies = [ - "http 1.4.2", + "http 1.5.0", "hyper 1.9.0", "hyper-util", - "rustls 0.23.41", + "rustls 0.23.43", "tokio", "tokio-rustls 0.26.4", "tower-service", @@ -4585,7 +4642,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "hyper 1.9.0", "ipnet", @@ -4739,9 +4796,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b915661dd01db3f05050265b2477bcc6527b3792388e2749b41623cc592be67d" +checksum = "7f8a7b8211e695a1d0cd91cace480d4d0bd57667ab10277cc412c5f7f4884f83" dependencies = [ "crossbeam-deque", "globset", @@ -4811,9 +4868,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.18.4" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" dependencies = [ "console", "portable-atomic", @@ -4824,9 +4881,9 @@ dependencies = [ [[package]] name = "infer" -version = "0.19.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +checksum = "f4200d433cbd5178df7797c9c2e75b348b728e39631cf14520d1e2fc424201f4" dependencies = [ "cfb", ] @@ -4906,7 +4963,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -4969,7 +5026,7 @@ checksum = "05f86e4f0326c61ae6c00b04d9009aaeda644d0b5bdfbf6c67247f492f42b3f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -5042,7 +5099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -5093,15 +5150,6 @@ dependencies = [ "signature", ] -[[package]] -name = "kstring" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" -dependencies = [ - "static_assertions", -] - [[package]] name = "lazy-regex" version = "3.6.0" @@ -5122,7 +5170,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -5139,9 +5187,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libredox" @@ -5309,17 +5357,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" -[[package]] -name = "maybe-async" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "746873a384ad60adc5db74471dfaba74bd278afbdcfd81db93fafcdfc8b5ca0c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - [[package]] name = "md-5" version = "0.10.6" @@ -5338,9 +5375,9 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -5364,7 +5401,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -5387,7 +5424,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -5458,7 +5495,7 @@ dependencies = [ "bytes", "colored", "futures-core", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -5509,7 +5546,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http 1.4.2", + "http 1.5.0", "httparse", "memchr", "mime", @@ -5633,7 +5670,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5739,7 +5776,7 @@ dependencies = [ "base64 0.22.1", "chrono", "getrandom 0.2.17", - "http 1.4.2", + "http 1.5.0", "rand 0.8.5", "reqwest 0.12.28", "serde", @@ -5989,13 +6026,12 @@ dependencies = [ [[package]] name = "open" -version = "5.3.5" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" +checksum = "a0b3d059e795d52b8a72fef45658620edd4d9c359b338564aa14391ffa511ed5" dependencies = [ "is-wsl", "libc", - "pathdiff", ] [[package]] @@ -6020,7 +6056,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -6140,7 +6176,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -6179,7 +6215,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -6258,7 +6294,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -6328,13 +6364,14 @@ dependencies = [ [[package]] name = "posthog-rs" -version = "0.14.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00308c626c1e38b2984094a0ac73c081529b14f04d26a025ac719aa5de27eb1" +checksum = "5dc5d94870b23655fceae57574d6741475b114be5a018b25d22dd2aa076fbe13" dependencies = [ "backtrace", "chrono", "derive_builder", + "findshlibs", "flate2", "os_info", "regex", @@ -6395,7 +6432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -6417,14 +6454,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -6437,7 +6474,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "version_check", "yansi", ] @@ -6494,7 +6531,7 @@ dependencies = [ "pulldown-cmark", "pulldown-cmark-to-cmark", "regex", - "syn 2.0.118", + "syn 2.0.119", "tempfile", ] @@ -6508,7 +6545,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -6573,9 +6610,9 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.41", + "rustls 0.23.43", "socket2 0.6.3", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tracing", "web-time", @@ -6594,10 +6631,10 @@ dependencies = [ "rand 0.9.4", "ring", "rustc-hash", - "rustls 0.23.41", + "rustls 0.23.43", "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror 2.0.19", "tinyvec", "tracing", "web-time", @@ -6619,9 +6656,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -6682,9 +6719,9 @@ 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", @@ -6792,7 +6829,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] @@ -6812,7 +6849,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -6829,9 +6866,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.4" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -6841,9 +6878,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" dependencies = [ "aho-corasick", "memchr", @@ -6917,7 +6954,7 @@ dependencies = [ "futures-util", "h2 0.4.13", "hickory-resolver", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -6929,7 +6966,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.41", + "rustls 0.23.43", "rustls-pki-types", "serde", "serde_json", @@ -6960,7 +6997,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -6971,7 +7008,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.41", + "rustls 0.23.43", "rustls-pki-types", "rustls-platform-verifier", "serde", @@ -7021,18 +7058,18 @@ dependencies = [ "base64 0.22.1", "chrono", "futures", - "http 1.4.2", + "http 1.5.0", "oauth2", "pastey", "pin-project-lite", "process-wrap", "reqwest 0.13.4", "rmcp-macros", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", "sse-stream", - "thiserror 2.0.18", + "thiserror 2.0.19", "tokio", "tokio-stream", "tokio-util", @@ -7050,7 +7087,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -7102,7 +7139,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.118", + "syn 2.0.119", "unicode-xid", "version_check", ] @@ -7155,7 +7192,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a1f2315036ef6b1fbacd1972e8ee7688030b0a2121edfc2a6550febd41574d" dependencies = [ "hashbrown 0.16.1", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] @@ -7212,7 +7249,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -7229,9 +7266,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.41" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "aws-lc-rs", "log", @@ -7285,14 +7322,14 @@ dependencies = [ "jni 0.21.1", "log", "once_cell", - "rustls 0.23.41", + "rustls 0.23.43", "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki 0.103.11", "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -7397,9 +7434,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" dependencies = [ "chrono", "dyn-clone", @@ -7411,14 +7448,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" +checksum = "d98c67716b46af2f0b8cf752abc930f6f9aecfbf671ecfb531db8a31dbe4e2ba" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -7474,9 +7511,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -7496,40 +7533,40 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] name = "serde_derive_internals" -version = "0.29.1" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -7602,7 +7639,7 @@ dependencies = [ "indexmap 1.9.3", "indexmap 2.14.0", "schemars 0.9.0", - "schemars 1.2.1", + "schemars 1.2.2", "serde_core", "serde_json", "serde_with_macros", @@ -7618,7 +7655,7 @@ dependencies = [ "darling 0.23.0", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -7648,9 +7685,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.5.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "699f4197115b8a7e7ff19c9a315a4bd6fffec26cc4626ef45ecaea389e081c6d" +checksum = "a6df5ed973ad8d834e09f824f9e9f449af6b9a3745f78dec7cc752770bd3bf11" dependencies = [ "futures-executor", "futures-util", @@ -7662,13 +7699,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.5.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c" +checksum = "a22144e767da4ddd8416dbf383700542ffd8a5dc493dfecedfe1fe3ad03c98ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -7927,12 +7964,6 @@ dependencies = [ "loom", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "streamdown-ansi" version = "0.1.4" @@ -7966,7 +7997,7 @@ checksum = "f4b0eaa964712369925867b0f17b0a27e54625df4c79bbc4d6a38390d523d863" dependencies = [ "regex", "serde", - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] @@ -8068,7 +8099,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -8080,7 +8111,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -8108,9 +8139,20 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -8140,7 +8182,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -8159,7 +8201,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.19", "walkdir", "yaml-rust", ] @@ -8230,7 +8272,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8256,7 +8298,7 @@ dependencies = [ "lazy-regex", "minimad", "serde", - "thiserror 2.0.18", + "thiserror 2.0.19", "unicode-width 0.1.14", ] @@ -8293,7 +8335,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8307,11 +8349,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.19", ] [[package]] @@ -8322,18 +8364,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.3", ] [[package]] @@ -8438,9 +8480,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.3" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -8461,7 +8503,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -8490,15 +8532,15 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.41", + "rustls 0.23.43", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ "futures-core", "pin-project-lite", @@ -8507,13 +8549,14 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", + "libc", "pin-project-lite", "tokio", ] @@ -8599,9 +8642,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.12+spec-1.1.0" +version = "0.25.13+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" dependencies = [ "indexmap 2.14.0", "serde_core", @@ -8629,9 +8672,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tonic" @@ -8644,7 +8687,7 @@ dependencies = [ "base64 0.22.1", "bytes", "h2 0.4.13", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -8673,7 +8716,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -8698,7 +8741,7 @@ dependencies = [ "prost-build", "prost-types", "quote", - "syn 2.0.118", + "syn 2.0.119", "tempfile", "tonic-build", ] @@ -8733,7 +8776,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 1.4.2", + "http 1.5.0", "http-body 1.0.1", "http-body-util", "iri-string", @@ -8776,7 +8819,7 @@ checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c" dependencies = [ "crossbeam-channel", "symlink", - "thiserror 2.0.18", + "thiserror 2.0.19", "time", "tracing-subscriber", ] @@ -8789,7 +8832,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -9001,7 +9044,7 @@ dependencies = [ "flate2", "log", "percent-encoding", - "rustls 0.23.41", + "rustls 0.23.43", "rustls-pki-types", "serde", "serde_json", @@ -9017,7 +9060,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" dependencies = [ "base64 0.22.1", - "http 1.4.2", + "http 1.5.0", "httparse", "log", ] @@ -9047,12 +9090,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" - [[package]] name = "utf8-zero" version = "0.8.1" @@ -9073,13 +9110,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.4" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" dependencies = [ "getrandom 0.4.2", "js-sys", - "rand 0.10.1", + "rand 0.10.2", "serde_core", "wasm-bindgen", ] @@ -9226,7 +9263,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wasm-bindgen-shared", ] @@ -9395,7 +9432,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -9479,7 +9516,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -9501,7 +9538,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -9849,7 +9886,7 @@ dependencies = [ "heck", "indexmap 2.14.0", "prettyplease", - "syn 2.0.118", + "syn 2.0.119", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -9865,7 +9902,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -10032,7 +10069,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "synstructure", ] @@ -10053,7 +10090,7 @@ checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -10073,7 +10110,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "synstructure", ] @@ -10113,7 +10150,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0dfc1ed19e..01a81a0070 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ aws-smithy-types = "1.4.3" aws-smithy-runtime-api = "1.11.3" aws-smithy-async = { version = "1.2.11", features = ["rt-tokio"] } aws-smithy-runtime = { version = "1.10", features = ["connector-hyper-0-14-x", "tls-rustls"] } -base64 = "0.22.1" +base64 = "0.23.0" bstr = "1.12.1" bytes = "1.11.1" chrono = { version = "0.4.44", features = ["serde"] } @@ -52,14 +52,14 @@ http = "1.2.0" ignore = "0.4.23" is_ci = "1.2.0" indexmap = "2.13.0" -infer = "0.19.0" +infer = "0.22.0" insta = { version = "1.47.2", features = ["json", "yaml"] } lazy_static = "1.4.0" machineid-rs = "1.2.4" mockito = "1.7.2" nom = "8.0.0" nu-ansi-term = "0.50.1" -posthog-rs = "0.14.0" +posthog-rs = "0.21.0" pretty_assertions = "1.4.1" proc-macro2 = "1.0" quote = "1.0" @@ -82,7 +82,7 @@ similar = { version = "3.0", features = ["inline"] } strip-ansi-escapes = "0.2.1" strum = "0.28.0" strum_macros = "0.28.0" -syn = { version = "2.0.117", features = ["derive", "parsing"] } +syn = { version = "3.0.0", features = ["derive", "parsing"] } sysinfo = "0.38.3" tempfile = "3.27.0" termimad = "0.34.1" @@ -134,7 +134,7 @@ num-format = "0.4" humantime = "2.1.0" dashmap = "7.0.0-rc2" async-openai = { version = "0.41.0", default-features = false, features = ["response-types"] } # Using only types, not the API client - reduces dependencies -gix = "0.85" +gix = "0.86" google-cloud-auth = "1.8.0" # Google Cloud authentication with automatic token refresh # Internal crates diff --git a/README.md b/README.md index 2c39c6ea25..1e7e66626d 100644 --- a/README.md +++ b/README.md @@ -570,6 +570,41 @@ CEREBRAS_API_KEY= +
+Neuralwatt + +```bash +# .env +NEURALWATT_API_KEY= +``` + +
+ +
+OrcaRouter + +```bash +# .env +ORCAROUTER_API_KEY= +``` + +
+ +
+Meta + +```bash +# .env +META_API_KEY= +``` + +```yaml +# forge.yaml +model: muse-spark-1.1 +``` + +
+
IO Intelligence diff --git a/crates/forge_app/src/dto/anthropic/response.rs b/crates/forge_app/src/dto/anthropic/response.rs index d964b05953..6d3b89c759 100644 --- a/crates/forge_app/src/dto/anthropic/response.rs +++ b/crates/forge_app/src/dto/anthropic/response.rs @@ -84,6 +84,11 @@ fn get_context_length(model_id: &str) -> Option { return Some(1_000_000); } + // Claude Sonnet 5 and Opus 5 (1M context) + if model_id.starts_with("claude-sonnet-5") || model_id.starts_with("claude-opus-5") { + return Some(1_000_000); + } + // Current models (200K context) if model_id.starts_with("claude-sonnet-4-5-") || model_id.starts_with("claude-haiku-4-5-") @@ -200,6 +205,7 @@ pub enum StopReason { MaxTokens, StopSequence, ToolUse, + Refusal, } impl From for forge_domain::FinishReason { @@ -209,6 +215,7 @@ impl From for forge_domain::FinishReason { StopReason::MaxTokens => forge_domain::FinishReason::Length, StopReason::StopSequence => forge_domain::FinishReason::Stop, StopReason::ToolUse => forge_domain::FinishReason::ToolCalls, + StopReason::Refusal => forge_domain::FinishReason::ContentFilter, } } } @@ -839,4 +846,36 @@ mod tests { assert_eq!(actual.usage, None); } + + #[test] + fn test_message_delta_refusal_stop_reason() { + // Fable returns HTTP 200 with stop_reason "refusal" when safety + // classifiers decline a request. This must parse as a known event, + // not fall through to EventData::Unknown (which silently drops the + // finish reason and triggers an empty-completion retry loop). + let fixture = r#"{"type":"message_delta","delta":{"stop_reason":"refusal","stop_sequence":null},"usage":{"output_tokens":0}}"#; + + let actual = serde_json::from_str::(fixture).unwrap(); + + let expected = EventData::KnownEvent(Event::MessageDelta { + delta: MessageDelta { stop_reason: StopReason::Refusal, stop_sequence: None }, + usage: Usage { + input_tokens: None, + output_tokens: Some(0), + cache_creation_input_tokens: None, + cache_read_input_tokens: None, + }, + }); + assert_eq!(actual, expected); + } + + #[test] + fn test_refusal_maps_to_content_filter() { + let fixture = StopReason::Refusal; + + let actual = forge_domain::FinishReason::from(fixture); + + let expected = forge_domain::FinishReason::ContentFilter; + assert_eq!(actual, expected); + } } diff --git a/crates/forge_app/src/dto/openai/copilot_model.rs b/crates/forge_app/src/dto/openai/copilot_model.rs new file mode 100644 index 0000000000..5dc3f901e6 --- /dev/null +++ b/crates/forge_app/src/dto/openai/copilot_model.rs @@ -0,0 +1,407 @@ +use forge_domain::ModelId; +use serde::{Deserialize, Serialize}; + +/// Identifier of the synthetic GitHub Copilot "auto" model. +/// +/// Copilot's API has no `auto` model id; official clients implement "Auto" +/// by letting the request omit the model so the service selects a default. +/// Requests made with this id must not include a `model` field. +pub const COPILOT_AUTO_MODEL_ID: &str = "auto"; + +/// Creates the synthetic "auto" model entry for GitHub Copilot. +/// +/// Selecting this model omits the `model` field from chat requests so the +/// Copilot service chooses the model server-side. This mirrors the "Auto" +/// option in official clients and is the included option on free and +/// student plans where premium model requests are limited. +pub fn copilot_auto_model() -> forge_domain::Model { + forge_domain::Model { + id: ModelId::new(COPILOT_AUTO_MODEL_ID), + name: Some("Auto (server default)".to_string()), + description: Some( + "Lets GitHub Copilot choose the model. Does not consume premium requests on plans with limited premium quota." + .to_string(), + ), + context_length: None, + tools_supported: Some(true), + supports_parallel_tool_calls: None, + supports_reasoning: None, + input_modalities: vec![forge_domain::InputModality::Text], + } +} + +/// Response returned by the GitHub Copilot `/models` endpoint. +#[derive(Debug, Deserialize, Clone, Serialize)] +pub struct CopilotListModelResponse { + pub data: Vec, +} + +/// A model entry as returned by the GitHub Copilot `/models` endpoint. +/// +/// GitHub Copilot uses a schema that differs from the standard OpenAI +/// models response: capabilities, limits and access policy are nested +/// under dedicated objects. +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct CopilotModel { + pub id: ModelId, + pub name: Option, + /// Whether the model is shown in the model picker of official clients + #[serde(default)] + pub model_picker_enabled: bool, + /// Access policy for the model; models with a `disabled` state cannot + /// be used by the authenticated account + pub policy: Option, + pub capabilities: Option, + pub supported_endpoints: Option>, + pub vendor: Option, + pub preview: Option, +} + +/// Access policy attached to a Copilot model. +#[derive(Debug, Deserialize, Serialize, Clone, Default)] +pub struct CopilotPolicy { + pub state: Option, +} + +/// Capabilities of a Copilot model. +#[derive(Debug, Deserialize, Serialize, Clone, Default)] +pub struct CopilotCapabilities { + /// Model type, e.g. `chat` or `embeddings` + #[serde(rename = "type")] + pub model_type: Option, + pub limits: Option, + pub supports: Option, +} + +/// Token and vision limits of a Copilot model. +#[derive(Debug, Deserialize, Serialize, Clone, Default)] +pub struct CopilotLimits { + pub max_context_window_tokens: Option, + pub max_prompt_tokens: Option, + pub max_output_tokens: Option, + pub vision: Option, +} + +/// Vision-specific limits of a Copilot model. +#[derive(Debug, Deserialize, Serialize, Clone, Default)] +pub struct CopilotVisionLimits { + pub supported_media_types: Option>, +} + +/// Feature support flags of a Copilot model. +#[derive(Debug, Deserialize, Serialize, Clone, Default)] +pub struct CopilotSupports { + pub tool_calls: Option, + pub parallel_tool_calls: Option, + pub streaming: Option, + pub vision: Option, + pub adaptive_thinking: Option, + pub max_thinking_budget: Option, + pub min_thinking_budget: Option, + pub reasoning_effort: Option>, +} + +impl CopilotModel { + /// Returns true when the model can actually be used for chat by the + /// authenticated account. + /// + /// Filters out models that are policy-disabled for the current + /// subscription (requests to them fail with `model_not_supported`) as + /// well as non-chat models such as embeddings. + pub fn is_usable(&self) -> bool { + // Models explicitly disabled by policy cannot be used and return + // `model_not_supported` errors when requested + let policy_disabled = self + .policy + .as_ref() + .and_then(|p| p.state.as_deref()) + .is_some_and(|state| state == "disabled"); + if policy_disabled { + return false; + } + + let Some(capabilities) = self.capabilities.as_ref() else { + return false; + }; + + // Only chat models are usable for conversations (excludes embeddings) + if capabilities.model_type.as_deref() != Some("chat") { + return false; + } + + // Require known token limits and tool call information, mirroring the + // checks official clients perform before offering a model + let has_limits = capabilities.limits.as_ref().is_some_and(|limits| { + limits.max_output_tokens.is_some() && limits.max_prompt_tokens.is_some() + }); + let has_tool_info = capabilities + .supports + .as_ref() + .is_some_and(|supports| supports.tool_calls.is_some()); + + has_limits && has_tool_info + } +} + +impl From for forge_domain::Model { + fn from(value: CopilotModel) -> Self { + let supports = value + .capabilities + .as_ref() + .and_then(|c| c.supports.as_ref()); + let limits = value.capabilities.as_ref().and_then(|c| c.limits.as_ref()); + + let context_length = + limits.and_then(|l| l.max_context_window_tokens.or(l.max_prompt_tokens)); + + let tools_supported = supports.and_then(|s| s.tool_calls); + let supports_parallel_tool_calls = supports.and_then(|s| s.parallel_tool_calls); + + // A model supports reasoning when it advertises adaptive thinking, + // reasoning effort levels or a thinking budget + let supports_reasoning = supports.map(|s| { + s.adaptive_thinking.unwrap_or(false) + || s.reasoning_effort + .as_ref() + .is_some_and(|efforts| !efforts.is_empty()) + || s.max_thinking_budget.is_some() + }); + + let supports_image = supports.and_then(|s| s.vision).unwrap_or(false) + || limits + .and_then(|l| l.vision.as_ref()) + .and_then(|v| v.supported_media_types.as_ref()) + .is_some_and(|types| types.iter().any(|t| t.starts_with("image/"))); + + let mut input_modalities = vec![forge_domain::InputModality::Text]; + if supports_image { + input_modalities.push(forge_domain::InputModality::Image); + } + + forge_domain::Model { + id: value.id, + name: value.name, + description: None, + context_length, + tools_supported, + supports_parallel_tool_calls, + supports_reasoning, + input_modalities, + } + } +} + +#[cfg(test)] +mod tests { + use pretty_assertions::assert_eq; + + use super::*; + + fn fixture_chat_model() -> CopilotModel { + serde_json::from_value(serde_json::json!({ + "id": "claude-sonnet-4.6", + "name": "Claude Sonnet 4.6", + "model_picker_enabled": true, + "policy": { "state": "enabled" }, + "vendor": "Anthropic", + "preview": false, + "supported_endpoints": ["/chat/completions", "/v1/messages"], + "capabilities": { + "type": "chat", + "family": "claude-sonnet-4.6", + "limits": { + "max_context_window_tokens": 264000, + "max_output_tokens": 64000, + "max_prompt_tokens": 200000, + "vision": { + "max_prompt_image_size": 3145728, + "max_prompt_images": 5, + "supported_media_types": ["image/jpeg", "image/png"] + } + }, + "supports": { + "adaptive_thinking": true, + "max_thinking_budget": 32000, + "min_thinking_budget": 1024, + "parallel_tool_calls": true, + "reasoning_effort": ["low", "medium", "high", "max"], + "streaming": true, + "structured_outputs": true, + "tool_calls": true, + "vision": true + } + } + })) + .unwrap() + } + + fn fixture_disabled_model() -> CopilotModel { + serde_json::from_value(serde_json::json!({ + "id": "gpt-5.5", + "name": "GPT-5.5", + "model_picker_enabled": true, + "policy": { "state": "disabled" }, + "capabilities": { + "type": "chat", + "limits": { + "max_context_window_tokens": 272000, + "max_output_tokens": 128000, + "max_prompt_tokens": 144000 + }, + "supports": { "tool_calls": true, "streaming": true } + } + })) + .unwrap() + } + + fn fixture_embedding_model() -> CopilotModel { + serde_json::from_value(serde_json::json!({ + "id": "text-embedding-3-small", + "name": "Embedding V3 small", + "model_picker_enabled": false, + "capabilities": { + "type": "embeddings", + "limits": { "max_inputs": 256 }, + "supports": { "dimensions": true } + } + })) + .unwrap() + } + + #[test] + fn test_usable_chat_model() { + let fixture = fixture_chat_model(); + let actual = fixture.is_usable(); + let expected = true; + assert_eq!(actual, expected); + } + + #[test] + fn test_policy_disabled_model_is_not_usable() { + let fixture = fixture_disabled_model(); + let actual = fixture.is_usable(); + let expected = false; + assert_eq!(actual, expected); + } + + #[test] + fn test_embedding_model_is_not_usable() { + let fixture = fixture_embedding_model(); + let actual = fixture.is_usable(); + let expected = false; + assert_eq!(actual, expected); + } + + #[test] + fn test_model_without_policy_is_usable() { + let fixture = serde_json::from_value::(serde_json::json!({ + "id": "gpt-4o", + "name": "GPT-4o", + "model_picker_enabled": false, + "capabilities": { + "type": "chat", + "limits": { + "max_context_window_tokens": 128000, + "max_output_tokens": 16384, + "max_prompt_tokens": 64000 + }, + "supports": { "tool_calls": true, "parallel_tool_calls": true } + } + })) + .unwrap(); + + let actual = fixture.is_usable(); + let expected = true; + assert_eq!(actual, expected); + } + + #[test] + fn test_conversion_to_domain_model() { + let fixture = fixture_chat_model(); + + let actual: forge_domain::Model = fixture.into(); + + let expected = forge_domain::Model { + id: ModelId::new("claude-sonnet-4.6"), + name: Some("Claude Sonnet 4.6".to_string()), + description: None, + context_length: Some(264000), + tools_supported: Some(true), + supports_parallel_tool_calls: Some(true), + supports_reasoning: Some(true), + input_modalities: vec![ + forge_domain::InputModality::Text, + forge_domain::InputModality::Image, + ], + }; + + assert_eq!(actual, expected); + } + + #[test] + fn test_conversion_falls_back_to_max_prompt_tokens() { + let fixture = serde_json::from_value::(serde_json::json!({ + "id": "some-model", + "name": "Some Model", + "capabilities": { + "type": "chat", + "limits": { "max_prompt_tokens": 100000, "max_output_tokens": 4096 }, + "supports": { "tool_calls": true } + } + })) + .unwrap(); + + let actual: forge_domain::Model = fixture.into(); + + assert_eq!(actual.context_length, Some(100000)); + assert_eq!(actual.supports_reasoning, Some(false)); + assert_eq!( + actual.input_modalities, + vec![forge_domain::InputModality::Text] + ); + } + + #[test] + fn test_list_response_deserialization_ignores_unknown_fields() { + let fixture = serde_json::json!({ + "data": [ + { + "id": "claude-sonnet-4.6", + "name": "Claude Sonnet 4.6", + "object": "model", + "model_picker_category": "versatile", + "warning_message": "some warning", + "capabilities": { + "type": "chat", + "object": "model_capabilities", + "tokenizer": "o200k_base", + "limits": { "max_prompt_tokens": 200000, "max_output_tokens": 64000 }, + "supports": { "tool_calls": true } + } + } + ] + }); + + let actual = serde_json::from_value::(fixture).unwrap(); + + assert_eq!(actual.data.len(), 1); + assert_eq!(actual.data[0].id.as_str(), "claude-sonnet-4.6"); + assert_eq!(actual.data[0].is_usable(), true); + } + + #[test] + fn test_copilot_auto_model_id() { + let fixture = copilot_auto_model(); + let actual = fixture.id.as_str(); + let expected = COPILOT_AUTO_MODEL_ID; + assert_eq!(actual, expected); + } + + #[test] + fn test_copilot_auto_model_supports_tools() { + let fixture = copilot_auto_model(); + let actual = fixture.tools_supported; + let expected = Some(true); + assert_eq!(actual, expected); + } +} diff --git a/crates/forge_app/src/dto/openai/fixtures/orcarouter_api_response.json b/crates/forge_app/src/dto/openai/fixtures/orcarouter_api_response.json new file mode 100644 index 0000000000..99b21a76d6 --- /dev/null +++ b/crates/forge_app/src/dto/openai/fixtures/orcarouter_api_response.json @@ -0,0 +1,31 @@ +{ + "data": [ + { + "id": "openai/gpt-4o-mini", + "object": "model", + "created": 1626777600, + "owned_by": "OpenAI", + "supported_endpoint_types": ["openai", "openai-response"], + "name": "OpenAI: GPT-4o-mini", + "description": "GPT-4o mini is OpenAI's most advanced small model, supporting both text and image inputs with text outputs.", + "context_length": 128000, + "max_completion_tokens": 16384, + "architecture": { + "input_modalities": ["text", "image", "file"], + "output_modalities": ["text"] + }, + "top_provider": { + "context_length": 128000, + "max_completion_tokens": 16384 + }, + "pricing": { + "prompt": "0.0000001500", + "completion": "0.0000006000", + "prompt_per_million": "0.150000", + "completion_per_million": "0.600000" + } + } + ], + "object": "list", + "success": true +} diff --git a/crates/forge_app/src/dto/openai/mod.rs b/crates/forge_app/src/dto/openai/mod.rs index 2d708dfcb7..67d60efc01 100644 --- a/crates/forge_app/src/dto/openai/mod.rs +++ b/crates/forge_app/src/dto/openai/mod.rs @@ -1,3 +1,4 @@ +mod copilot_model; mod error; mod model; mod reasoning; @@ -6,6 +7,7 @@ mod response; mod tool_choice; mod transformers; +pub use copilot_model::*; pub use error::*; pub use model::*; pub use reasoning::*; diff --git a/crates/forge_app/src/dto/openai/model.rs b/crates/forge_app/src/dto/openai/model.rs index f0e33ab6fc..78d2001a8c 100644 --- a/crates/forge_app/src/dto/openai/model.rs +++ b/crates/forge_app/src/dto/openai/model.rs @@ -44,8 +44,11 @@ pub struct Model { #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Architecture { - pub modality: String, - pub tokenizer: String, + // Some OpenAI-compatible providers (e.g. OrcaRouter) return an + // `architecture` object carrying only the modality arrays, so every + // field must tolerate being absent. + pub modality: Option, + pub tokenizer: Option, pub instruct_type: Option, pub input_modalities: Option>, pub output_modalities: Option>, @@ -82,6 +85,7 @@ where pub struct TopProvider { pub context_length: Option, pub max_completion_tokens: Option, + #[serde(default)] pub is_moderated: bool, } @@ -241,6 +245,42 @@ mod tests { assert_eq!(pricing.request, None); } + #[tokio::test] + async fn test_orcarouter_api_response_format() { + // OrcaRouter returns an `architecture` object with only the modality + // arrays (no `modality`/`tokenizer`) and a `top_provider` without + // `is_moderated`; all of these must deserialize. + let fixture = load_fixture("orcarouter_api_response.json").await; + + let actual = serde_json::from_value::(fixture).unwrap(); + + assert_eq!(actual.data.len(), 1); + let model = &actual.data[0]; + assert_eq!(model.id.as_str(), "openai/gpt-4o-mini"); + assert_eq!(model.name, Some("OpenAI: GPT-4o-mini".to_string())); + assert_eq!(model.context_length, Some(128000)); + + let architecture = model.architecture.as_ref().unwrap(); + assert_eq!(architecture.modality, None); + assert_eq!(architecture.tokenizer, None); + assert_eq!( + architecture.input_modalities, + Some(vec![ + "text".to_string(), + "image".to_string(), + "file".to_string() + ]) + ); + + let top_provider = model.top_provider.as_ref().unwrap(); + assert_eq!(top_provider.context_length, Some(128000)); + assert_eq!(top_provider.is_moderated, false); + + let pricing = model.pricing.as_ref().unwrap(); + assert_eq!(pricing.prompt, Some(0.00000015)); + assert_eq!(pricing.completion, Some(0.0000006)); + } + #[tokio::test] async fn test_deserialize_model_with_invalid_string_pricing() { // Test that invalid string pricing formats fail gracefully diff --git a/crates/forge_app/src/dto/openai/transformers/pipeline.rs b/crates/forge_app/src/dto/openai/transformers/pipeline.rs index 59c92aa6ef..f8009763c5 100644 --- a/crates/forge_app/src/dto/openai/transformers/pipeline.rs +++ b/crates/forge_app/src/dto/openai/transformers/pipeline.rs @@ -1,5 +1,3 @@ -use std::str::FromStr; - use forge_domain::{DefaultTransformation, Provider, ProviderId, Transformer}; use url::Url; @@ -101,7 +99,6 @@ impl Transformer for ProviderPipeline<'_> { let trim_tool_call_ids = TrimToolCallIds.when(move |_| provider.id == ProviderId::OPENAI); - let kimi_coding = ProviderId::from_str("kimi_coding").unwrap(); let strict_schema = EnforceStrictToolSchema .pipe(EnforceStrictResponseFormatSchema) .when(move |_| { @@ -110,7 +107,8 @@ impl Transformer for ProviderPipeline<'_> { || provider.id == ProviderId::OPENCODE_ZEN || provider.id == ProviderId::OPENCODE_GO || provider.id == ProviderId::XAI - || provider.id == kimi_coding + || provider.id == ProviderId::KIMI_CODING + || provider.id == ProviderId::MOONSHOT }); let mut combined = zai_thinking diff --git a/crates/forge_app/src/transformers/model_specific_reasoning.rs b/crates/forge_app/src/transformers/model_specific_reasoning.rs index d003eb1719..43f25c7539 100644 --- a/crates/forge_app/src/transformers/model_specific_reasoning.rs +++ b/crates/forge_app/src/transformers/model_specific_reasoning.rs @@ -27,19 +27,21 @@ impl ModelSpecificReasoning { fn family(&self) -> AnthropicModelFamily { let id = self.model_id.to_lowercase(); - if id.contains("opus-4-8") + if id.contains("opus-5") + || id.contains("opus-4-8") || id.contains("48-opus") || id.contains("opus-4-7") || id.contains("47-opus") || id.contains("mythos") || id.contains("fable") { - // Opus 4.8 shares Opus 4.7's API contract: adaptive thinking only + // Opus 5 and Opus 4.8 share Opus 4.7's API contract: adaptive thinking only // (legacy `budget_tokens` returns 400) and non-default sampling // params (`temperature`/`top_p`/`top_k`) return 400. AnthropicModelFamily::AdaptiveOnly } else if id.contains("opus-4-6") || id.contains("46-opus") + || id.contains("sonnet-5") || id.contains("sonnet-4-6") || id.contains("46-sonnet") { @@ -187,6 +189,29 @@ mod tests { assert_eq!(actual, expected); } + #[test] + fn test_opus_5_drops_max_tokens_and_sampling_params() { + // Opus 5 shares the Opus 4.7/4.8 API contract: adaptive thinking only, + // legacy `budget_tokens` and non-default sampling params return 400. + let fixture = fixture_context_with_sampling().reasoning(ReasoningConfig { + enabled: Some(true), + max_tokens: Some(8000), + effort: Some(Effort::XHigh), + exclude: Some(true), + }); + + let actual = ModelSpecificReasoning::new("claude-opus-5").transform(fixture); + + let expected = Context::default().reasoning(ReasoningConfig { + enabled: Some(true), + max_tokens: None, + effort: Some(Effort::XHigh), + exclude: Some(true), + }); + + assert_eq!(actual, expected); + } + #[test] fn test_opus_4_8_strips_sampling_even_without_reasoning() { let fixture = fixture_context_with_sampling(); diff --git a/crates/forge_domain/src/error.rs b/crates/forge_domain/src/error.rs index 02d8f60529..31db4e4203 100644 --- a/crates/forge_domain/src/error.rs +++ b/crates/forge_domain/src/error.rs @@ -74,6 +74,13 @@ pub enum Error { #[error("Empty completion received - no content, tool calls, or valid finish reason")] EmptyCompletion, + #[error( + "The model refused to generate a response (safety/content filter). \ + Retrying the same request will produce the same refusal - rephrase \ + the request or switch to a different model." + )] + Refusal, + #[error(transparent)] Retryable(anyhow::Error), diff --git a/crates/forge_domain/src/provider.rs b/crates/forge_domain/src/provider.rs index 2038031c0e..72c914589f 100644 --- a/crates/forge_domain/src/provider.rs +++ b/crates/forge_domain/src/provider.rs @@ -82,6 +82,12 @@ impl ProviderId { pub const XIAOMI_MIMO: ProviderId = ProviderId(Cow::Borrowed("xiaomi_mimo")); pub const NVIDIA: ProviderId = ProviderId(Cow::Borrowed("nvidia")); pub const AMBIENT: ProviderId = ProviderId(Cow::Borrowed("ambient")); + pub const NEURALWATT: ProviderId = ProviderId(Cow::Borrowed("neuralwatt")); + pub const ORCA_ROUTER: ProviderId = ProviderId(Cow::Borrowed("orca_router")); + pub const META: ProviderId = ProviderId(Cow::Borrowed("meta")); + pub const KIMI_CODING: ProviderId = ProviderId(Cow::Borrowed("kimi_coding")); + pub const MOONSHOT: ProviderId = ProviderId(Cow::Borrowed("moonshot")); + pub const ALIBABA_TOKEN_PLAN: ProviderId = ProviderId(Cow::Borrowed("alibaba_token_plan")); /// Returns all built-in provider IDs /// @@ -123,6 +129,12 @@ impl ProviderId { ProviderId::XIAOMI_MIMO, ProviderId::NVIDIA, ProviderId::AMBIENT, + ProviderId::NEURALWATT, + ProviderId::ORCA_ROUTER, + ProviderId::META, + ProviderId::KIMI_CODING, + ProviderId::MOONSHOT, + ProviderId::ALIBABA_TOKEN_PLAN, ] } @@ -158,6 +170,9 @@ impl ProviderId { "xiaomi_mimo" => "XiaomiMimo".to_string(), "nvidia" => "NVIDIA".to_string(), "ambient" => "Ambient".to_string(), + "neuralwatt" => "Neuralwatt".to_string(), + "orca_router" => "OrcaRouter".to_string(), + "meta" => "Meta".to_string(), _ => { // For other providers, use UpperCamelCase conversion use convert_case::{Case, Casing}; @@ -214,6 +229,12 @@ impl std::str::FromStr for ProviderId { "xiaomi_mimo" => ProviderId::XIAOMI_MIMO, "nvidia" => ProviderId::NVIDIA, "ambient" => ProviderId::AMBIENT, + "neuralwatt" => ProviderId::NEURALWATT, + "orca_router" => ProviderId::ORCA_ROUTER, + "meta" => ProviderId::META, + "kimi_coding" => ProviderId::KIMI_CODING, + "moonshot" => ProviderId::MOONSHOT, + "alibaba_token_plan" => ProviderId::ALIBABA_TOKEN_PLAN, // For custom providers, use Cow::Owned to avoid memory leaks custom => ProviderId(Cow::Owned(custom.to_string())), }; @@ -591,6 +612,8 @@ mod tests { assert_eq!(ProviderId::GOOGLE_AI_STUDIO.to_string(), "GoogleAIStudio"); assert_eq!(ProviderId::NVIDIA.to_string(), "NVIDIA"); assert_eq!(ProviderId::AMBIENT.to_string(), "Ambient"); + assert_eq!(ProviderId::ORCA_ROUTER.to_string(), "OrcaRouter"); + assert_eq!(ProviderId::META.to_string(), "Meta"); } #[test] @@ -632,6 +655,8 @@ mod tests { assert!(built_in.contains(&ProviderId::GOOGLE_AI_STUDIO)); assert!(built_in.contains(&ProviderId::NVIDIA)); assert!(built_in.contains(&ProviderId::AMBIENT)); + assert!(built_in.contains(&ProviderId::ORCA_ROUTER)); + assert!(built_in.contains(&ProviderId::META)); } #[test] @@ -713,6 +738,107 @@ mod tests { assert!(built_in.contains(&ProviderId::AMBIENT)); } + #[test] + fn test_neuralwatt_from_str() { + let actual = ProviderId::from_str("neuralwatt").unwrap(); + let expected = ProviderId::NEURALWATT; + assert_eq!(actual, expected); + } + + #[test] + fn test_neuralwatt_display_name() { + assert_eq!(ProviderId::NEURALWATT.to_string(), "Neuralwatt"); + } + + #[test] + fn test_neuralwatt_in_built_in_providers() { + let built_in = ProviderId::built_in_providers(); + assert!(built_in.contains(&ProviderId::NEURALWATT)); + } + + #[test] + fn test_orca_router_from_str() { + let actual = ProviderId::from_str("orca_router").unwrap(); + let expected = ProviderId::ORCA_ROUTER; + assert_eq!(actual, expected); + } + + #[test] + fn test_orca_router_display_name() { + assert_eq!(ProviderId::ORCA_ROUTER.to_string(), "OrcaRouter"); + } + + #[test] + fn test_orca_router_in_built_in_providers() { + let built_in = ProviderId::built_in_providers(); + assert!(built_in.contains(&ProviderId::ORCA_ROUTER)); + } + + #[test] + fn test_meta_from_str() { + let actual = ProviderId::from_str("meta").unwrap(); + let expected = ProviderId::META; + assert_eq!(actual, expected); + } + + #[test] + fn test_meta_display_name() { + assert_eq!(ProviderId::META.to_string(), "Meta"); + } + + #[test] + fn test_meta_in_built_in_providers() { + let built_in = ProviderId::built_in_providers(); + assert!(built_in.contains(&ProviderId::META)); + } + + #[test] + fn test_moonshot_display_name() { + let actual = ProviderId::MOONSHOT.to_string(); + let expected = "Moonshot".to_string(); + assert_eq!(actual, expected); + } + + #[test] + fn test_moonshot_in_built_in_providers() { + let built_in = ProviderId::built_in_providers(); + assert!(built_in.contains(&ProviderId::MOONSHOT)); + } + + #[test] + fn test_moonshot_from_str_roundtrip() { + let actual = ProviderId::from_str("moonshot").unwrap(); + let expected = ProviderId::MOONSHOT; + assert_eq!(actual, expected); + } + + #[test] + fn test_kimi_coding_from_str_roundtrip() { + let actual = ProviderId::from_str("kimi_coding").unwrap(); + let expected = ProviderId::KIMI_CODING; + assert_eq!(actual, expected); + } + + #[test] + fn test_alibaba_token_plan_display_name() { + let actual = ProviderId::ALIBABA_TOKEN_PLAN.to_string(); + let expected = "AlibabaTokenPlan".to_string(); + assert_eq!(actual, expected); + } + + #[test] + fn test_alibaba_token_plan_in_built_in_providers() { + let built_in = ProviderId::built_in_providers(); + assert!(built_in.contains(&ProviderId::ALIBABA_TOKEN_PLAN)); + } + + #[test] + fn test_alibaba_token_plan_from_str_roundtrip() { + let actual = ProviderId::from_str("alibaba_token_plan").unwrap(); + let expected = ProviderId::ALIBABA_TOKEN_PLAN; + assert_eq!(actual, expected); + } + #[test] fn test_io_intelligence() { let fixture = "test_key"; diff --git a/crates/forge_domain/src/result_stream_ext.rs b/crates/forge_domain/src/result_stream_ext.rs index 9250ff0adc..46e08e7452 100644 --- a/crates/forge_domain/src/result_stream_ext.rs +++ b/crates/forge_domain/src/result_stream_ext.rs @@ -4,7 +4,7 @@ use tokio_stream::StreamExt; use crate::reasoning::{Reasoning, ReasoningFull}; use crate::{ ArcSender, ChatCompletionMessage, ChatCompletionMessageFull, ChatResponse, ChatResponseContent, - ToolCallFull, ToolCallPart, Usage, + FinishReason, ToolCallFull, ToolCallPart, Usage, }; /// Extension trait for ResultStream to provide additional functionality @@ -259,6 +259,14 @@ impl ResultStreamExt for crate::BoxStream = + Box::pin(tokio_stream::iter(messages)); + + let actual = fixture.into_full(false).await.unwrap_err(); + + let domain_error = actual.downcast_ref::().unwrap(); + assert!(matches!(domain_error, crate::Error::Refusal)); + } + + #[tokio::test] + async fn test_into_full_refusal_with_partial_content_is_error() { + // Mid-stream refusals can arrive after partial output. The partial + // text has already been streamed to the UI; the turn still must end + // with the refusal error rather than looping. + let messages = vec![ + Ok(ChatCompletionMessage::assistant(Content::part( + "I was about to say", + ))), + Ok(ChatCompletionMessage::assistant(Content::part("")) + .finish_reason(FinishReason::ContentFilter)), + ]; + let fixture: BoxStream = + Box::pin(tokio_stream::iter(messages)); + + let actual = fixture.into_full(false).await.unwrap_err(); + + let domain_error = actual.downcast_ref::().unwrap(); + assert!(matches!(domain_error, crate::Error::Refusal)); + } + #[tokio::test] async fn test_into_full_empty_completion_with_tool_calls_should_not_error() { // Fixture: Create a stream with empty content but with tool calls diff --git a/crates/forge_fs/Cargo.toml b/crates/forge_fs/Cargo.toml index e6e2bf7dab..4232e439cc 100644 --- a/crates/forge_fs/Cargo.toml +++ b/crates/forge_fs/Cargo.toml @@ -9,7 +9,7 @@ tokio.workspace = true anyhow.workspace = true sha2.workspace = true hex.workspace = true -infer = "0.19.0" # For binary file detection +infer = "0.22.0" # For binary file detection thiserror = "2.0" bstr.workspace = true diff --git a/crates/forge_infra/Cargo.toml b/crates/forge_infra/Cargo.toml index f907fa33db..82c6a7e164 100644 --- a/crates/forge_infra/Cargo.toml +++ b/crates/forge_infra/Cargo.toml @@ -54,7 +54,7 @@ aws-credential-types.workspace = true [dev-dependencies] tokio = { workspace = true, features = ["macros", "rt", "time", "test-util"] } -serial_test = "3.4" +serial_test = "4.0" fake = { version = "5.1.0", features = ["derive"] } pretty_assertions.workspace = true forge_domain = { path = "../forge_domain" } diff --git a/crates/forge_main/Cargo.toml b/crates/forge_main/Cargo.toml index ffc3fd859c..a27d7a3bd7 100644 --- a/crates/forge_main/Cargo.toml +++ b/crates/forge_main/Cargo.toml @@ -85,6 +85,6 @@ arboard = "3.4" tokio = { workspace = true, features = ["macros", "rt", "time", "test-util"] } insta.workspace = true pretty_assertions.workspace = true -serial_test = "3.4" +serial_test = "4.0" fake = { version = "5.1.0", features = ["derive"] } forge_domain = { path = "../forge_domain" } diff --git a/crates/forge_main/src/info.rs b/crates/forge_main/src/info.rs index b0815a8799..074e8e9711 100644 --- a/crates/forge_main/src/info.rs +++ b/crates/forge_main/src/info.rs @@ -75,7 +75,7 @@ impl Section { /// # Output Format /// /// ```text -/// +/// /// CONFIGURATION /// model gpt-4 /// provider openai diff --git a/crates/forge_repo/Cargo.toml b/crates/forge_repo/Cargo.toml index 788afb768f..964f92a021 100644 --- a/crates/forge_repo/Cargo.toml +++ b/crates/forge_repo/Cargo.toml @@ -68,7 +68,7 @@ tokio = { workspace = true, features = ["macros", "rt", "time", "test-util"] } tempfile = { workspace = true } pretty_assertions = { workspace = true } insta = { workspace = true } -serial_test = "3.4" +serial_test = "4.0" fake = { version = "5.1.0", features = ["derive"] } derive_setters.workspace = true mockito = { workspace = true } diff --git a/crates/forge_repo/src/provider/anthropic.rs b/crates/forge_repo/src/provider/anthropic.rs index 009568bcdb..9bcb906cb9 100644 --- a/crates/forge_repo/src/provider/anthropic.rs +++ b/crates/forge_repo/src/provider/anthropic.rs @@ -92,13 +92,15 @@ impl Anthropic { } /// Returns false when the model auto-enables interleaved thinking through -/// adaptive thinking (Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 4.6). When the model -/// is unknown (e.g., listing endpoints), the flag is included because it is -/// harmless on non-chat endpoints and necessary on older chat models. +/// adaptive thinking (Opus 5, Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 5, Sonnet +/// 4.6). When +/// the model is unknown (e.g., listing endpoints), the flag is included because +/// it is harmless on non-chat endpoints and necessary on older chat models. fn interleaved_thinking_required(model: Option<&ModelId>) -> bool { let Some(model) = model else { return true }; let id = model.as_str().to_lowercase(); - !(id.contains("opus-4-8") + !(id.contains("opus-5") + || id.contains("opus-4-8") || id.contains("opus-4-7") || id.contains("opus-4-6") || id.contains("sonnet-4-6") @@ -837,6 +839,7 @@ mod tests { ); for model_id in [ + "claude-opus-5", "claude-opus-4-8", "claude-opus-4-7", "claude-opus-4-6", diff --git a/crates/forge_repo/src/provider/openai.rs b/crates/forge_repo/src/provider/openai.rs index 103d302334..9f262e98ed 100644 --- a/crates/forge_repo/src/provider/openai.rs +++ b/crates/forge_repo/src/provider/openai.rs @@ -5,7 +5,10 @@ use forge_app::domain::{ ChatCompletionMessage, Context as ChatContext, Model, ModelId, ProviderId, ResultStream, Transformer, }; -use forge_app::dto::openai::{ListModelResponse, ProviderPipeline, Request, Response}; +use forge_app::dto::openai::{ + COPILOT_AUTO_MODEL_ID, CopilotListModelResponse, ListModelResponse, ProviderPipeline, Request, + Response, copilot_auto_model, +}; use forge_app::{EnvironmentInfra, HttpInfra}; use forge_domain::{ChatRepository, Provider}; use forge_infra::sanitize_headers; @@ -37,6 +40,21 @@ fn enhance_error(error: anyhow::Error, provider_id: &ProviderId) -> anyhow::Erro error } +/// Prepares a request for GitHub Copilot's synthetic "auto" model. +/// +/// Copilot's API has no `auto` model id; official clients implement "Auto" +/// by omitting the model so the service selects one server-side. Since the +/// served model is unknown, model-specific tuning must also be omitted or +/// the request fails (e.g. `invalid_reasoning_effort` when the service +/// selects a non-reasoning model). +fn prepare_copilot_auto_request(mut request: Request) -> Request { + request.model = None; + request.reasoning = None; + request.reasoning_effort = None; + request.thinking = None; + request +} + #[derive(Clone)] struct OpenAIProvider { provider: Provider, @@ -200,6 +218,11 @@ impl OpenAIProvider { let mut pipeline = ProviderPipeline::new(&self.provider, merge_system_messages); request = pipeline.transform(request); + if self.provider.id == ProviderId::GITHUB_COPILOT && model.as_str() == COPILOT_AUTO_MODEL_ID + { + request = prepare_copilot_auto_request(request); + } + let url = self.provider.url.clone(); let headers = create_headers(self.get_headers_with_request(&request)); @@ -247,6 +270,31 @@ impl OpenAIProvider { anyhow::bail!(error) } Ok(response) => { + // GitHub Copilot's /models endpoint uses a different schema + // (capabilities, limits, policy) than the standard OpenAI + // models response and includes models the account cannot + // actually use + if self.provider.id == ProviderId::GITHUB_COPILOT { + let data: CopilotListModelResponse = serde_json::from_str( + &response, + ) + .with_context(|| format_http_context(None, "GET", url)) + .with_context( + || "Failed to deserialize GitHub Copilot models response", + )?; + // Offer the synthetic "auto" model first; it lets the + // service pick the model and is the included option on + // plans with limited premium requests + let models = std::iter::once(copilot_auto_model()) + .chain( + data.data + .into_iter() + .filter(|model| model.is_usable()) + .map(Into::into), + ) + .collect(); + return Ok(models); + } let data: ListModelResponse = serde_json::from_str(&response) .with_context(|| format_http_context(None, "GET", url)) .with_context(|| "Failed to deserialize models response")?; @@ -831,6 +879,34 @@ mod tests { insta::assert_snapshot!(error_string); } + #[test] + fn test_prepare_copilot_auto_request_strips_model_and_tuning() { + let fixture = Request::default() + .model(forge_app::domain::ModelId::new("auto")) + .reasoning_effort("low".to_string()) + .messages(vec![Message { + role: Role::User, + content: Some(MessageContent::Text("Hello".to_string())), + name: None, + tool_call_id: None, + tool_calls: None, + reasoning_details: None, + reasoning_text: None, + reasoning_opaque: None, + reasoning_content: None, + extra_content: None, + }]); + + let actual = prepare_copilot_auto_request(fixture); + + assert_eq!(actual.model, None); + assert_eq!(actual.reasoning_effort, None); + assert!(actual.reasoning.is_none()); + assert!(actual.thinking.is_none()); + // Messages must be preserved + assert_eq!(actual.message_count(), 1); + } + #[test] fn test_get_headers_includes_custom_headers() { let mut provider = openai("test-key"); diff --git a/crates/forge_repo/src/provider/openai_responses/codex_transformer.rs b/crates/forge_repo/src/provider/openai_responses/codex_transformer.rs index b11e606d31..24af166215 100644 --- a/crates/forge_repo/src/provider/openai_responses/codex_transformer.rs +++ b/crates/forge_repo/src/provider/openai_responses/codex_transformer.rs @@ -148,11 +148,12 @@ mod tests { #[test] fn test_codex_transformer_preserves_other_fields() { - let fixture = fixture(); + let mut fixture = fixture(); + fixture.model = Some("gpt-5.6-luna".to_string()); let mut transformer = CodexTransformer; let actual = transformer.transform(fixture); - assert_eq!(actual.model.as_deref(), Some("gpt-5.1-codex")); + assert_eq!(actual.model.as_deref(), Some("gpt-5.6-luna")); assert_eq!(actual.stream, Some(true)); } } diff --git a/crates/forge_repo/src/provider/openai_responses/repository.rs b/crates/forge_repo/src/provider/openai_responses/repository.rs index 3c113efbfd..847e570c73 100644 --- a/crates/forge_repo/src/provider/openai_responses/repository.rs +++ b/crates/forge_repo/src/provider/openai_responses/repository.rs @@ -11,7 +11,7 @@ use forge_eventsource_stream::Eventsource; use forge_infra::sanitize_headers; use futures::StreamExt; use reqwest::StatusCode; -use reqwest::header::AUTHORIZATION; +use reqwest::header::{AUTHORIZATION, HeaderMap, HeaderValue}; use tracing::info; use url::Url; @@ -19,6 +19,8 @@ use crate::provider::FromDomain; use crate::provider::retry::into_retry; use crate::provider::utils::{create_headers, format_http_context, read_http_error_reason}; +const CODEX_RESPONSES_LITE_HEADER: &str = "x-openai-internal-codex-responses-lite"; + #[derive(Clone)] pub(super) struct OpenAIResponsesProvider { provider: Provider, @@ -156,7 +158,9 @@ impl OpenAIResponsesProvider { context: ChatContext, ) -> ResultStream { let conversation_id = context.conversation_id.as_ref().map(ToString::to_string); - let headers = create_headers(self.get_headers_for_conversation(conversation_id.as_deref())); + let mut headers = + create_headers(self.get_headers_for_conversation(conversation_id.as_deref())); + add_codex_responses_lite_headers(&mut headers, &self.provider, model); let mut request = oai::CreateResponse::from_domain(context)?; request.model = Some(model.as_str().to_string()); @@ -175,8 +179,14 @@ impl OpenAIResponsesProvider { "Connecting Upstream (Responses API)" ); - let json_bytes = serde_json::to_vec(&request) - .with_context(|| "Failed to serialize OpenAI Responses request")?; + let json_bytes = if is_codex_responses_lite(&self.provider, model) { + let request = CodexResponsesLiteRequest::try_from(request)?; + serde_json::to_vec(&request) + .with_context(|| "Failed to serialize Codex Responses Lite request")? + } else { + serde_json::to_vec(&request) + .with_context(|| "Failed to serialize OpenAI Responses request")? + }; // The Codex backend at chatgpt.com does not return // `Content-Type: text/event-stream`, which causes the @@ -408,6 +418,241 @@ fn responses_endpoint_from_api_base(api_base: &Url) -> Url { url } +fn is_codex_responses_lite(provider: &Provider, model: &ModelId) -> bool { + provider.id == forge_domain::ProviderId::CODEX && model.as_str() == "gpt-5.6-luna" +} + +fn add_codex_responses_lite_headers( + headers: &mut HeaderMap, + provider: &Provider, + model: &ModelId, +) { + if is_codex_responses_lite(provider, model) { + headers.insert( + CODEX_RESPONSES_LITE_HEADER, + HeaderValue::from_static("true"), + ); + headers.insert( + "user-agent", + HeaderValue::from_static("codex_cli_rs/0.144.0"), + ); + headers.insert("x-app-version", HeaderValue::from_static("0.144.0")); + headers.insert("originator", HeaderValue::from_static("codex_cli_rs")); + } +} + +/// Input item for the Codex Responses Lite wire format. +#[derive(Debug, Clone, PartialEq, serde::Serialize)] +#[serde(untagged)] +enum CodexResponsesLiteItem { + /// Developer item carrying the tool definitions that are normally sent in + /// the top-level `tools` field. + AdditionalTools { + #[serde(rename = "type")] + kind: &'static str, + role: &'static str, + tools: Vec, + }, + /// Developer message carrying the system instructions that are normally + /// sent in the top-level `instructions` field. + DeveloperMessage { + #[serde(rename = "type")] + kind: &'static str, + role: &'static str, + content: String, + }, + /// A regular Responses API input item, passed through unchanged. + Item(oai::InputItem), +} + +impl CodexResponsesLiteItem { + /// Creates the developer `additional_tools` input item. + fn additional_tools(tools: Vec) -> Self { + Self::AdditionalTools { kind: "additional_tools", role: "developer", tools } + } + + /// Creates the developer message input item carrying instructions. + fn developer_message(content: String) -> Self { + Self::DeveloperMessage { kind: "message", role: "developer", content } + } +} + +/// Reasoning configuration for the Codex Responses Lite wire format. +/// +/// Extends the standard Responses reasoning object with the `context` field +/// required by the Lite endpoint. +#[derive(Debug, Clone, PartialEq, serde::Serialize)] +struct CodexResponsesLiteReasoning { + #[serde(flatten)] + reasoning: oai::Reasoning, + context: &'static str, +} + +impl From for CodexResponsesLiteReasoning { + fn from(reasoning: oai::Reasoning) -> Self { + Self { reasoning, context: "all_turns" } + } +} + +/// Request wire format for the Codex Responses Lite endpoint. +/// +/// Differs from the standard Responses request as follows: +/// - Tools are moved out of the top-level `tools` field into a leading +/// `additional_tools` developer input item. +/// - Top-level `instructions` are blanked out and re-sent as a developer +/// message input item (when non-empty). +/// - `parallel_tool_calls` is forced to `false`. +/// - `reasoning.context` is set to `"all_turns"` when reasoning is present. +/// +/// All remaining fields mirror `oai::CreateResponse` and are passed through +/// unchanged. +#[derive(Debug, Clone, PartialEq, serde::Serialize)] +struct CodexResponsesLiteRequest { + input: Vec, + /// Always serialized as the empty string. The Lite endpoint requires the + /// top-level `instructions` key to be present but blank; the actual + /// instructions are re-sent as a developer message inside `input`. + instructions: &'static str, + /// Always `false`. The Lite endpoint does not support parallel tool + /// calls, so the original request value is intentionally discarded. + parallel_tool_calls: bool, + #[serde(skip_serializing_if = "Option::is_none")] + reasoning: Option, + #[serde(skip_serializing_if = "Option::is_none")] + background: Option, + #[serde(skip_serializing_if = "Option::is_none")] + conversation: Option, + #[serde(skip_serializing_if = "Option::is_none")] + include: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + max_output_tokens: Option, + #[serde(skip_serializing_if = "Option::is_none")] + max_tool_calls: Option, + #[serde(skip_serializing_if = "Option::is_none")] + metadata: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + model: Option, + #[serde(skip_serializing_if = "Option::is_none")] + previous_response_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] + prompt: Option, + #[serde(skip_serializing_if = "Option::is_none")] + prompt_cache_key: Option, + #[serde(skip_serializing_if = "Option::is_none")] + prompt_cache_retention: Option, + #[serde(skip_serializing_if = "Option::is_none")] + safety_identifier: Option, + #[serde(skip_serializing_if = "Option::is_none")] + service_tier: Option, + #[serde(skip_serializing_if = "Option::is_none")] + store: Option, + #[serde(skip_serializing_if = "Option::is_none")] + stream: Option, + #[serde(skip_serializing_if = "Option::is_none")] + stream_options: Option, + #[serde(skip_serializing_if = "Option::is_none")] + temperature: Option, + #[serde(skip_serializing_if = "Option::is_none")] + text: Option, + #[serde(skip_serializing_if = "Option::is_none")] + tool_choice: Option, + #[serde(skip_serializing_if = "Option::is_none")] + top_logprobs: Option, + #[serde(skip_serializing_if = "Option::is_none")] + top_p: Option, + #[serde(skip_serializing_if = "Option::is_none")] + truncation: Option, +} + +impl TryFrom for CodexResponsesLiteRequest { + type Error = anyhow::Error; + + /// Converts a standard Responses request into the Lite wire format. + /// + /// # Errors + /// + /// Returns an error if the request input is plain text instead of a list + /// of input items. + fn try_from(request: oai::CreateResponse) -> anyhow::Result { + // Exhaustive destructuring: adding a field to `CreateResponse` + // upstream becomes a compile error here, so no field can be silently + // dropped from the Lite request. + let oai::CreateResponse { + background, + conversation, + include, + input, + instructions, + max_output_tokens, + max_tool_calls, + metadata, + model, + parallel_tool_calls: _, + previous_response_id, + prompt, + prompt_cache_key, + prompt_cache_retention, + reasoning, + safety_identifier, + service_tier, + store, + stream, + stream_options, + temperature, + text, + tool_choice, + tools, + top_logprobs, + top_p, + truncation, + } = request; + + let items = match input { + oai::InputParam::Items(items) => items, + oai::InputParam::Text(_) => { + anyhow::bail!("Codex Responses Lite input must be an array") + } + }; + + let instructions = instructions.filter(|content| !content.is_empty()); + let input = std::iter::once(CodexResponsesLiteItem::additional_tools( + tools.unwrap_or_default(), + )) + .chain(instructions.map(CodexResponsesLiteItem::developer_message)) + .chain(items.into_iter().map(CodexResponsesLiteItem::Item)) + .collect(); + + Ok(Self { + input, + instructions: "", + parallel_tool_calls: false, + reasoning: reasoning.map(Into::into), + background, + conversation, + include, + max_output_tokens, + max_tool_calls, + metadata, + model, + previous_response_id, + prompt, + prompt_cache_key, + prompt_cache_retention, + safety_identifier, + service_tier, + store, + stream, + stream_options, + temperature, + text, + tool_choice, + top_logprobs, + top_p, + truncation, + }) + } +} + fn request_message_count(request: &oai::CreateResponse) -> usize { match &request.input { oai::InputParam::Text(_) => 1, @@ -1337,6 +1582,157 @@ mod tests { assert!(session_id.is_none()); } + #[test] + fn test_codex_luna_adds_responses_lite_header() { + let provider = Provider { + id: ProviderId::CODEX, + provider_type: forge_domain::ProviderType::Llm, + response: Some(ProviderResponse::OpenAI), + url: Url::parse("https://chatgpt.com/backend-api/codex/responses").unwrap(), + credential: make_credential(ProviderId::CODEX, "test-token"), + custom_headers: None, + auth_methods: vec![], + url_params: vec![], + models: None, + }; + let mut fixture = HeaderMap::new(); + + add_codex_responses_lite_headers(&mut fixture, &provider, &ModelId::from("gpt-5.6-luna")); + + let actual = fixture + .get(CODEX_RESPONSES_LITE_HEADER) + .and_then(|value| value.to_str().ok()); + let expected = Some("true"); + assert_eq!(actual, expected); + } + + #[test] + fn test_codex_non_luna_omits_responses_lite_header() { + let provider = Provider { + id: ProviderId::CODEX, + provider_type: forge_domain::ProviderType::Llm, + response: Some(ProviderResponse::OpenAI), + url: Url::parse("https://chatgpt.com/backend-api/codex/responses").unwrap(), + credential: make_credential(ProviderId::CODEX, "test-token"), + custom_headers: None, + auth_methods: vec![], + url_params: vec![], + models: None, + }; + let mut fixture = HeaderMap::new(); + + add_codex_responses_lite_headers(&mut fixture, &provider, &ModelId::from("gpt-5.6-sol")); + + let actual = fixture.contains_key(CODEX_RESPONSES_LITE_HEADER); + let expected = false; + assert_eq!(actual, expected); + } + + /// Test fixture for a standard Responses request with tools, + /// instructions and reasoning. + fn codex_lite_request_fixture() -> oai::CreateResponse { + oai::CreateResponse { + model: Some("gpt-5.6-luna".to_string()), + instructions: Some("be helpful".to_string()), + tools: Some(vec![oai::Tool::Function(oai::FunctionTool { + name: "shell".to_string(), + parameters: None, + strict: None, + description: None, + defer_loading: None, + })]), + input: oai::InputParam::Items(vec![oai::InputItem::Item(oai::Item::FunctionCall( + oai::FunctionToolCall { + id: Some("call_1".to_string()), + call_id: "call_id_1".to_string(), + name: "shell".to_string(), + arguments: "{}".to_string(), + namespace: None, + status: None, + }, + ))]), + reasoning: Some(oai::Reasoning { + effort: Some(oai::ReasoningEffort::Medium), + summary: None, + }), + parallel_tool_calls: Some(true), + ..Default::default() + } + } + + #[test] + fn test_codex_responses_lite_request_rewrites_request() { + let fixture = codex_lite_request_fixture(); + + let actual = + serde_json::to_value(CodexResponsesLiteRequest::try_from(fixture).unwrap()).unwrap(); + + let expected = serde_json::json!({ + "model": "gpt-5.6-luna", + "instructions": "", + "input": [ + { + "type": "additional_tools", + "role": "developer", + "tools": [{"type": "function", "name": "shell"}] + }, + { + "type": "message", + "role": "developer", + "content": "be helpful" + }, + { + "type": "function_call", + "id": "call_1", + "call_id": "call_id_1", + "name": "shell", + "arguments": "{}" + } + ], + "parallel_tool_calls": false, + "reasoning": {"effort": "medium", "context": "all_turns"} + }); + assert_eq!(actual, expected); + } + + #[test] + fn test_codex_responses_lite_request_without_tools_and_instructions() { + let fixture = oai::CreateResponse { + model: Some("gpt-5.6-luna".to_string()), + input: oai::InputParam::Items(vec![]), + ..Default::default() + }; + + let actual = + serde_json::to_value(CodexResponsesLiteRequest::try_from(fixture).unwrap()).unwrap(); + + let expected = serde_json::json!({ + "model": "gpt-5.6-luna", + "instructions": "", + "input": [ + { + "type": "additional_tools", + "role": "developer", + "tools": [] + } + ], + "parallel_tool_calls": false + }); + assert_eq!(actual, expected); + } + + #[test] + fn test_codex_responses_lite_request_rejects_text_input() { + let fixture = oai::CreateResponse { + input: oai::InputParam::Text("hi".to_string()), + ..Default::default() + }; + + let actual = CodexResponsesLiteRequest::try_from(fixture); + + assert!(actual.is_err()); + } + #[tokio::test] async fn test_openai_responses_repository_models_returns_empty() -> anyhow::Result<()> { let infra = Arc::new(MockHttpClient { client: reqwest::Client::new() }); diff --git a/crates/forge_repo/src/provider/provider.json b/crates/forge_repo/src/provider/provider.json index ac73677281..b0c6bf33d5 100644 --- a/crates/forge_repo/src/provider/provider.json +++ b/crates/forge_repo/src/provider/provider.json @@ -584,6 +584,36 @@ "supports_parallel_tool_calls": true, "supports_reasoning": true, "input_modalities": ["text", "image"] + }, + { + "id": "gpt-5.6-sol", + "name": "GPT-5.6 Sol", + "description": "Frontier model for complex professional work", + "context_length": 1050000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "gpt-5.6-terra", + "name": "GPT-5.6 Terra", + "description": "GPT-5.6 model that balances intelligence and cost", + "context_length": 1050000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "gpt-5.6-luna", + "name": "GPT-5.6 Luna", + "description": "GPT-5.6 model optimized for cost-sensitive workloads", + "context_length": 1050000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] } ], "auth_methods": ["api_key"] @@ -603,12 +633,103 @@ "url_param_vars": [], "response_type": "OpenAI", "url": "https://api.kimi.com/coding/v1/chat/completions", - "models": "https://api.kimi.com/coding/v1/models", + "models": [ + { + "id": "k3", + "name": "Kimi K3", + "description": "Moonshot AI Kimi K3 flagship model with 2.8T parameters, 1M-token context, native vision, always-on reasoning, and tool calling capabilities", + "context_length": 1048576, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-for-coding", + "name": "Kimi K2.7 Code", + "description": "Moonshot AI Kimi K2.7 Code model with 256K context, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-for-coding-highspeed", + "name": "Kimi K2.7 Code HighSpeed", + "description": "Moonshot AI Kimi K2.7 Code HighSpeed model (5-6x faster output) with 256K context, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + } + ], "auth_methods": ["api_key"], "custom_headers": { "User-Agent": "KimiCLI/1.0.0" } }, + { + "id": "moonshot", + "api_key_vars": "MOONSHOT_API_KEY", + "url_param_vars": [], + "response_type": "OpenAI", + "url": "https://api.moonshot.ai/v1/chat/completions", + "models": [ + { + "id": "kimi-k3", + "name": "Kimi K3", + "description": "Moonshot AI Kimi K3 flagship model with 2.8T parameters, 1M-token context, native vision, always-on reasoning, and tool calling capabilities", + "context_length": 1048576, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "description": "Moonshot AI Kimi K2.7 Code model with 256K context, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.6", + "name": "Kimi K2.6", + "description": "Moonshot AI Kimi K2.6 model with multimodal input, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "description": "Moonshot AI Kimi K2.5 model with multimodal input, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2-thinking", + "name": "Kimi K2 Thinking", + "description": "Moonshot AI Kimi K2 Thinking model with 256K context, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + } + ], + "auth_methods": ["api_key"] + }, { "id": "openai_responses_compatible", "api_key_vars": "OPENAI_API_KEY", @@ -644,6 +765,16 @@ "supports_reasoning": true, "input_modalities": ["text", "image"] }, + { + "id": "claude-opus-5", + "name": "Claude Opus 5", + "description": "Thoughtful and proactive model approaching frontier intelligence at half the price", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "claude-opus-4-8", "name": "Claude Opus 4.8", @@ -664,6 +795,16 @@ "supports_reasoning": true, "input_modalities": ["text", "image"] }, + { + "id": "claude-sonnet-5", + "name": "Claude Sonnet 5", + "description": "The best combination of speed and intelligence", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6", @@ -810,6 +951,196 @@ "models": "https://api.cerebras.ai/v1/models", "auth_methods": ["api_key"] }, + { + "id": "neuralwatt", + "api_key_vars": "NEURALWATT_API_KEY", + "url_param_vars": [], + "response_type": "OpenAI", + "url": "https://api.neuralwatt.com/v1/chat/completions", + "models": [ + { + "id": "qwen3.5-397b", + "name": "Qwen3.5 397B", + "description": "Qwen3.5 397B-A17B — quant-agnostic canonical name for the Qwen3.5 397B family.", + "context_length": 262128, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "qwen3.5-397b-fast", + "name": "Qwen3.5 397B Fast", + "description": "Qwen3.5 397B with thinking mode disabled for faster, lower-latency responses. Ideal for straightforward tasks where extended reasoning is unnecessary.", + "context_length": 262128, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": false, + "input_modalities": ["text"] + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "description": "Kimi K2.7 Code — quant-agnostic canonical name for the Kimi K2.7 Code family.", + "context_length": 262128, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.7-code-flex", + "name": "Kimi K2.7 Code Flex", + "description": "Kimi K2.7 Code on the flex tier — lower-cost serving with relaxed latency guarantees.", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.6", + "name": "Kimi K2.6", + "description": "Kimi K2.6 — quant-agnostic canonical name for the Kimi K2.6 family.", + "context_length": 262128, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.6-fast", + "name": "Kimi K2.6 Fast", + "description": "Moonshot Kimi K2.6 with thinking mode disabled for instant, lower-latency responses.", + "context_length": 262128, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": false, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.6-flex", + "name": "Kimi K2.6 Flex", + "description": "Kimi K2.6 on the flex tier — lower-cost serving with relaxed latency guarantees.", + "context_length": 262128, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "description": "Kimi K2.5 — quant-agnostic canonical name for the Kimi K2.5 family.", + "context_length": 262128, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.5-fast", + "name": "Kimi K2.5 Fast", + "description": "Moonshot Kimi K2.5 with thinking mode disabled for instant, lower-latency responses.", + "context_length": 262128, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": false, + "input_modalities": ["text", "image"] + }, + { + "id": "qwen3.6-35b", + "name": "Qwen3.6 35B", + "description": "Qwen3.6 35B-A3B — quant-agnostic canonical name for the Qwen3.6 35B family.", + "context_length": 131056, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "qwen3.6-35b-fast", + "name": "Qwen3.6 35B Fast", + "description": "Qwen3.6 35B with thinking mode disabled for instant responses. A lightweight, fast model for rapid iteration.", + "context_length": 131056, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": false, + "input_modalities": ["text", "image"] + }, + { + "id": "glm-5.2", + "name": "GLM-5.2", + "description": "Private GLM-5.2 test canary", + "context_length": 1048560, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "glm-5.2-fast", + "name": "GLM-5.2 (fast)", + "description": "GLM-5.2 with thinking skipped (reasoning_effort=none). Non-thinking tier, mirrors glm-5.1-fast.", + "context_length": 1048560, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": false, + "input_modalities": ["text"] + }, + { + "id": "glm-5.2-flex", + "name": "GLM-5.2 Flex", + "description": "GLM-5.2 on the flex tier — lower-cost serving with relaxed latency guarantees.", + "context_length": 1048560, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "glm-5.2-short", + "name": "GLM-5.2 (short)", + "description": "GLM-5.2 with a 200K context window and a bounded reasoning budget — faster, lower-energy serving for everyday coding, agentic, and chat workloads under 200K tokens. Private preview (grant-gated).", + "context_length": 199984, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "glm-5.2-short-fast", + "name": "GLM-5.2 (short, fast)", + "description": "GLM-5.2 short with reasoning OFF — the fastest, lowest-energy variant of the 200K pool, for latency-sensitive coding, chat, and tool-use that does not need chain-of-thought. Private preview (grant-gated).", + "context_length": 199984, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": false, + "input_modalities": ["text"] + }, + { + "id": "glm-5.2-short-flex", + "name": "GLM-5.2 (short, flex)", + "description": "GLM-5.2 short on the flex tier — lower-cost serving with relaxed latency guarantees for workloads under 200K tokens.", + "context_length": 199984, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "glm-5.2-short-fast-flex", + "name": "GLM-5.2 (short, fast, flex)", + "description": "GLM-5.2 short with reasoning OFF on the flex tier — lowest-cost variant of the 200K pool with relaxed latency guarantees.", + "context_length": 199984, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": false, + "input_modalities": ["text"] + } + ], + "auth_methods": ["api_key"] + }, { "id": "zai", "api_key_vars": "ZAI_API_KEY", @@ -1453,6 +1784,46 @@ "supports_reasoning": true, "input_modalities": ["text"] }, + { + "id": "global.anthropic.claude-sonnet-5", + "name": "Claude Sonnet 5 (Global)", + "description": "The best combination of speed and intelligence", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "us.anthropic.claude-sonnet-5", + "name": "Claude Sonnet 5 (US)", + "description": "The best combination of speed and intelligence", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "eu.anthropic.claude-sonnet-5", + "name": "Claude Sonnet 5 (EU)", + "description": "The best combination of speed and intelligence", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "anthropic.claude-sonnet-5", + "name": "Claude Sonnet 5", + "description": "The best combination of speed and intelligence", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "global.anthropic.claude-sonnet-4-6", "name": "Claude Sonnet 4.6 (Global)", @@ -2305,6 +2676,16 @@ "supports_reasoning": true, "input_modalities": ["text", "image"] }, + { + "id": "claude-sonnet-5", + "name": "Claude Sonnet 5", + "description": "The best combination of speed and intelligence", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6", @@ -2647,6 +3028,36 @@ "response_type": "OpenAI", "url": "https://chatgpt.com/backend-api/codex/responses", "models": [ + { + "id": "gpt-5.6-luna", + "name": "GPT-5.6 Luna", + "description": "GPT-5.6 model optimized for cost-sensitive workloads", + "context_length": 372000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "gpt-5.6-sol", + "name": "GPT-5.6 Sol", + "description": "Frontier model for complex professional work", + "context_length": 372000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "gpt-5.6-terra", + "name": "GPT-5.6 Terra", + "description": "GPT-5.6 model that balances intelligence and cost", + "context_length": 372000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "gpt-5.5", "name": "GPT-5.5", @@ -2847,6 +3258,16 @@ "supports_reasoning": true, "input_modalities": ["text", "image"] }, + { + "id": "claude-sonnet-5", + "name": "Claude Sonnet 5", + "description": "The best combination of speed and intelligence", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6", @@ -3108,6 +3529,16 @@ "supports_reasoning": true, "input_modalities": ["text", "image"] }, + { + "id": "kimi-k3", + "name": "Kimi K3", + "description": "Moonshot AI Kimi K3 flagship model with 2.8T parameters, 1M-token context, native vision, always-on reasoning, and tool calling capabilities", + "context_length": 1048576, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "claude-opus-4-7", "name": "Claude Opus 4.7", @@ -3338,6 +3769,16 @@ "supports_reasoning": true, "input_modalities": ["text", "image"] }, + { + "id": "kimi-k3", + "name": "Kimi K3", + "description": "Moonshot AI Kimi K3 flagship model with 2.8T parameters, 1M-token context, native vision, always-on reasoning, and tool calling capabilities", + "context_length": 1048576, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, { "id": "glm-5.2", "name": "GLM-5.2", @@ -3492,6 +3933,166 @@ ], "auth_methods": ["api_key"] }, + { + "id": "alibaba_token_plan", + "api_key_vars": "ALIBABA_TOKEN_PLAN_API_KEY", + "url_param_vars": [], + "response_type": "OpenAI", + "url": "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions", + "models": [ + { + "id": "qwen3.8-max-preview", + "name": "Qwen3.8 Max Preview", + "description": "Alibaba's flagship Qwen3.8 Max preview model with 1M context, multimodal input, reasoning, and tool calling capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "qwen3.7-max", + "name": "Qwen3.7 Max", + "description": "Alibaba's Qwen3.7 Max model with 1M context, reasoning, and tool calling capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "qwen3.7-plus", + "name": "Qwen3.7 Plus", + "description": "Alibaba's Qwen3.7 Plus model with 1M context, multimodal input, reasoning, and tool calling capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "qwen3.6-plus", + "name": "Qwen3.6 Plus", + "description": "Alibaba's Qwen3.6 Plus model with 1M context, multimodal input, reasoning, and tool calling capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "qwen3.6-flash", + "name": "Qwen3.6 Flash", + "description": "Alibaba's fast and economical Qwen3.6 Flash model with 1M context, multimodal input, reasoning, and tool calling capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "deepseek-v4-pro", + "name": "DeepSeek V4 Pro", + "description": "DeepSeek V4 Pro model with 1M context, reasoning, and tool calling capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "deepseek-v4-flash", + "name": "DeepSeek V4 Flash", + "description": "Fast DeepSeek V4 lane for economical reasoning, coding, and long-context work", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "deepseek-v3.2", + "name": "DeepSeek V3.2", + "description": "DeepSeek V3.2 model with reasoning and tool calling capabilities", + "context_length": 131072, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "description": "Moonshot AI Kimi K2.7 Code model with 256K context, multimodal input, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.6", + "name": "Kimi K2.6", + "description": "Moonshot AI Kimi K2.6 model with multimodal input, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "description": "Moonshot AI Kimi K2.5 model with multimodal input, reasoning, and tool calling capabilities", + "context_length": 262144, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "glm-5.2", + "name": "GLM-5.2", + "description": "Zhipu AI GLM-5.2 flagship model with 1M context, reasoning, and tool calling capabilities", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "glm-5.1", + "name": "GLM-5.1", + "description": "Zhipu AI GLM-5.1 model with 200K context, reasoning, and tool calling capabilities", + "context_length": 202752, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "glm-5", + "name": "GLM-5", + "description": "Zhipu AI GLM-5 model with 200K context, reasoning, and tool calling capabilities", + "context_length": 202752, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "MiniMax-M2.5", + "name": "MiniMax M2.5", + "description": "MiniMax M2.5 model with reasoning and tool calling capabilities", + "context_length": 196608, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + } + ], + "auth_methods": ["api_key"] + }, { "id": "novita", "api_key_vars": "NOVITA_API_KEY", @@ -3838,5 +4439,34 @@ "url": "https://api.ambient.xyz/v1/chat/completions", "models": "https://api.ambient.xyz/v1/models", "auth_methods": ["api_key"] + }, + { + "id": "orca_router", + "api_key_vars": "ORCAROUTER_API_KEY", + "url_param_vars": [], + "response_type": "OpenAI", + "url": "https://api.orcarouter.ai/v1/chat/completions", + "models": "https://api.orcarouter.ai/v1/models", + "auth_methods": ["api_key"] + }, + { + "id": "meta", + "api_key_vars": "META_API_KEY", + "url_param_vars": [], + "response_type": "OpenAIResponses", + "url": "https://api.meta.ai/v1/responses", + "models": [ + { + "id": "muse-spark-1.1", + "name": "Muse Spark 1.1", + "description": "Meta's multimodal model for agentic tool calling, coding, structured output, image and video understanding, and long-context reasoning", + "context_length": 1048576, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + } + ], + "auth_methods": ["api_key"] } ] diff --git a/crates/forge_repo/src/provider/provider_repo.rs b/crates/forge_repo/src/provider/provider_repo.rs index 9f9d2a5877..c8bb120b7d 100644 --- a/crates/forge_repo/src/provider/provider_repo.rs +++ b/crates/forge_repo/src/provider/provider_repo.rs @@ -902,6 +902,208 @@ mod tests { ); } + #[test] + fn test_neuralwatt_config() { + let configs = get_provider_configs(); + let config = configs + .iter() + .find(|c| c.id == ProviderId::NEURALWATT) + .unwrap(); + assert_eq!(config.id, ProviderId::NEURALWATT); + assert_eq!(config.api_key_vars, Some("NEURALWATT_API_KEY".to_string())); + assert!(config.url_param_vars.is_empty()); + assert_eq!(config.response_type, Some(ProviderResponse::OpenAI)); + assert_eq!( + config.url.as_str(), + "https://api.neuralwatt.com/v1/chat/completions" + ); + // Neuralwatt exposes a non-standard /models schema, so models are + // hardcoded in provider.json instead of fetched from the URL. + match config.models.as_ref().expect("models should be present") { + Models::Hardcoded(models) => { + assert!( + models.iter().any(|m| m.id.as_str() == "glm-5.2"), + "expected glm-5.2 to be present in hardcoded models" + ); + assert!( + models.iter().any(|m| m.id.as_str() == "qwen3.5-397b"), + "expected qwen3.5-397b to be present in hardcoded models" + ); + assert!( + models.iter().any(|m| m.id.as_str() == "glm-5.2-flex"), + "expected glm-5.2-flex to be present in hardcoded models" + ); + assert!( + models + .iter() + .any(|m| m.id.as_str() == "kimi-k2.7-code-flex"), + "expected kimi-k2.7-code-flex to be present in hardcoded models" + ); + } + other => panic!("expected hardcoded models, got {other:?}"), + } + } + + #[test] + fn test_orca_router_config() { + let configs = get_provider_configs(); + let config = configs + .iter() + .find(|c| c.id == ProviderId::ORCA_ROUTER) + .unwrap(); + assert_eq!(config.id, ProviderId::ORCA_ROUTER); + assert_eq!(config.api_key_vars, Some("ORCAROUTER_API_KEY".to_string())); + assert!(config.url_param_vars.is_empty()); + assert_eq!(config.response_type, Some(ProviderResponse::OpenAI)); + assert_eq!( + config.url.as_str(), + "https://api.orcarouter.ai/v1/chat/completions" + ); + match config.models.as_ref().expect("models should be present") { + Models::Url(model_url) => { + assert_eq!(model_url, "https://api.orcarouter.ai/v1/models"); + } + other => panic!("expected URL-driven models, got {other:?}"), + } + } + + #[test] + fn test_meta_config() { + let configs = get_provider_configs(); + let config = configs.iter().find(|c| c.id == ProviderId::META).unwrap(); + assert_eq!(config.id, ProviderId::META); + assert_eq!(config.api_key_vars, Some("META_API_KEY".to_string())); + assert!(config.url_param_vars.is_empty()); + assert_eq!( + config.response_type, + Some(ProviderResponse::OpenAIResponses) + ); + assert_eq!(config.url.as_str(), "https://api.meta.ai/v1/responses"); + + match config.models.as_ref().expect("models should be present") { + Models::Hardcoded(models) => { + let model = models + .iter() + .find(|m| m.id.as_str() == "muse-spark-1.1") + .expect("muse-spark-1.1 should be present in hardcoded models"); + assert_eq!( + model.context_length, + Some(1048576), + "muse-spark-1.1 should have 1048576 context length" + ); + assert_eq!( + model.tools_supported, + Some(true), + "muse-spark-1.1 should support tools" + ); + assert_eq!( + model.supports_parallel_tool_calls, + Some(true), + "muse-spark-1.1 should support parallel tool calls" + ); + assert_eq!( + model.supports_reasoning, + Some(true), + "muse-spark-1.1 should support reasoning" + ); + assert!( + model + .input_modalities + .contains(&forge_app::domain::InputModality::Image), + "muse-spark-1.1 should support image input" + ); + } + other => panic!("expected hardcoded models, got {other:?}"), + } + } + + #[test] + fn test_alibaba_token_plan_config() { + let configs = get_provider_configs(); + let config = configs + .iter() + .find(|c| c.id == ProviderId::ALIBABA_TOKEN_PLAN) + .unwrap(); + assert_eq!(config.id, ProviderId::ALIBABA_TOKEN_PLAN); + assert_eq!( + config.api_key_vars, + Some("ALIBABA_TOKEN_PLAN_API_KEY".to_string()) + ); + assert!(config.url_param_vars.is_empty()); + assert_eq!(config.response_type, Some(ProviderResponse::OpenAI)); + assert_eq!( + config.url.as_str(), + "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions" + ); + // Alibaba Token Plan exposes an OpenAI-compatible endpoint but no + // capability metadata via /models, so models are hardcoded in + // provider.json. + match config.models.as_ref().expect("models should be present") { + Models::Hardcoded(models) => { + assert!( + models.iter().any(|m| m.id.as_str() == "qwen3.7-max"), + "expected qwen3.7-max to be present in hardcoded models" + ); + } + other => panic!("expected hardcoded models, got {other:?}"), + } + } + + #[test] + fn test_moonshot_config() { + let configs = get_provider_configs(); + let config = configs + .iter() + .find(|c| c.id == ProviderId::MOONSHOT) + .unwrap(); + assert_eq!(config.id, ProviderId::MOONSHOT); + assert_eq!(config.api_key_vars, Some("MOONSHOT_API_KEY".to_string())); + assert!(config.url_param_vars.is_empty()); + assert_eq!(config.response_type, Some(ProviderResponse::OpenAI)); + assert_eq!( + config.url.as_str(), + "https://api.moonshot.ai/v1/chat/completions" + ); + // Moonshot's /models endpoint omits capability metadata (modalities, + // reasoning, tool support), so models are hardcoded in provider.json. + match config.models.as_ref().expect("models should be present") { + Models::Hardcoded(models) => { + assert!( + models.iter().any(|m| m.id.as_str() == "kimi-k3"), + "expected kimi-k3 to be present in hardcoded models" + ); + } + other => panic!("expected hardcoded models, got {other:?}"), + } + } + + #[test] + fn test_kimi_coding_config() { + let configs = get_provider_configs(); + let config = configs + .iter() + .find(|c| c.id == ProviderId::KIMI_CODING) + .unwrap(); + assert_eq!(config.id, ProviderId::KIMI_CODING); + assert_eq!(config.api_key_vars, Some("KIMI_API_KEY".to_string())); + assert_eq!(config.response_type, Some(ProviderResponse::OpenAI)); + assert_eq!( + config.url.as_str(), + "https://api.kimi.com/coding/v1/chat/completions" + ); + // Kimi Code's /models endpoint omits capability metadata, so models are + // hardcoded using the platform's canonical model IDs (k3, etc.). + match config.models.as_ref().expect("models should be present") { + Models::Hardcoded(models) => { + assert!( + models.iter().any(|m| m.id.as_str() == "k3"), + "expected k3 to be present in hardcoded models" + ); + } + other => panic!("expected hardcoded models, got {other:?}"), + } + } + #[test] fn test_provider_entry_with_static_models_converts_to_hardcoded() { let model = forge_domain::Model::new("Qwen3.6-35B-A3b-q3-mlx") diff --git a/crates/forge_tracker/Cargo.toml b/crates/forge_tracker/Cargo.toml index c55733fc7c..03e8e2a77d 100644 --- a/crates/forge_tracker/Cargo.toml +++ b/crates/forge_tracker/Cargo.toml @@ -13,7 +13,7 @@ serde_json.workspace = true tokio.workspace = true tracing.workspace = true sysinfo.workspace = true -posthog-rs = "0.14.0" +posthog-rs = "0.21.0" async-trait.workspace = true chrono.workspace = true whoami.workspace = true diff --git a/package-lock.json b/package-lock.json index 39432acdcf..482f7f5d1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@types/tmp": "^0.2.6", "@types/yargs": "^17.0.35", "ai": "^7.0.0", - "chalk": "^5.6.2", + "chalk": "^6.0.0", "csv-parse": "^7.0.0", "handlebars": "^4.7.9", "p-limit": "^7.2.0", @@ -24,20 +24,20 @@ "strip-ansi": "^7.1.2", "tmp": "^0.2.5", "tsx": "^4.20.6", - "typescript": "^6.0.0", + "typescript": "^7.0.0", "yaml": "^2.8.3", "yargs": "^18.0.0", "zod": "^4.0.0" } }, "node_modules/@ai-sdk/anthropic": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/anthropic/-/anthropic-4.0.0.tgz", - "integrity": "sha512-N0lT1g6/5DEIZvalpkpwYRCdu7n5qb8qPN3PcTem6k4VkPBLC2+T2LAAyx1GS0eNOxavVa0CP7n2kCiye0yyfw==", + "version": "4.0.24", + "resolved": "https://registry.npmjs.org/@ai-sdk/anthropic/-/anthropic-4.0.24.tgz", + "integrity": "sha512-ywMZXK/uOIxUKwo2vaow0kt2XqMjIEeZWBOxif/oDka3294fUDX0gcUESUjPzd8254Fnvz1lRO70gr9LOgLkww==", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/provider": "4.0.0", - "@ai-sdk/provider-utils": "5.0.0" + "@ai-sdk/provider": "4.0.4", + "@ai-sdk/provider-utils": "5.0.15" }, "engines": { "node": ">=22" @@ -47,13 +47,13 @@ } }, "node_modules/@ai-sdk/gateway": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-4.0.2.tgz", - "integrity": "sha512-Jz1BiiTSvhDsCBJrkFRSqLHDRMVjFtYk9GdbSi3UOqY+/epza+oIESMDzfN4m+YHT/1IYmNEmxaMfjXOvxKDjQ==", + "version": "4.0.32", + "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-4.0.32.tgz", + "integrity": "sha512-U82ZbFEQY80YTyzOEI0jrCjV4Q52uN7/ln/KyI1AvSNR/IX3XwePOfsQWOfDhvmqXkb3TcYbVzWr4p85msKgOw==", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/provider": "4.0.0", - "@ai-sdk/provider-utils": "5.0.0", + "@ai-sdk/provider": "4.0.4", + "@ai-sdk/provider-utils": "5.0.15", "@vercel/oidc": "3.2.0" }, "engines": { @@ -64,13 +64,13 @@ } }, "node_modules/@ai-sdk/google": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/google/-/google-4.0.0.tgz", - "integrity": "sha512-UXGGmsYmeJ8VEfFenETFd2SN5tGSU+g2yrLrCuL8uqUkDFpNqV9a9MSKdshh6EXQs8e+2PUELJwqe7qQO3UnSw==", + "version": "4.0.28", + "resolved": "https://registry.npmjs.org/@ai-sdk/google/-/google-4.0.28.tgz", + "integrity": "sha512-/40fma4dtjOXcZrBiv/8X/ggIEY54Crsd5cTssGP8/h5vYcE/JEoyyx0Py4/Tfk1qWnAkuSZ+jJnTeStr633Fw==", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/provider": "4.0.0", - "@ai-sdk/provider-utils": "5.0.0" + "@ai-sdk/provider": "4.0.4", + "@ai-sdk/provider-utils": "5.0.15" }, "engines": { "node": ">=22" @@ -80,16 +80,16 @@ } }, "node_modules/@ai-sdk/google-vertex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/google-vertex/-/google-vertex-5.0.0.tgz", - "integrity": "sha512-lqQutA8/OxTX1LxiB14RVitkd9vGKGEqNQ+rh2lrPK651ouWePq5Vn/uXCEuumdeROt6VeTRWfA3/rEzEUYuvg==", + "version": "5.0.35", + "resolved": "https://registry.npmjs.org/@ai-sdk/google-vertex/-/google-vertex-5.0.35.tgz", + "integrity": "sha512-qhJxbLJw/RJB93Mefd1hSMpKHvHEgxBtoBWcuQXqTqItW2vu6AdblHeCNLer5WWe13f87z0YdSPYIVeh4CKxpA==", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/anthropic": "4.0.0", - "@ai-sdk/google": "4.0.0", - "@ai-sdk/openai-compatible": "3.0.0", - "@ai-sdk/provider": "4.0.0", - "@ai-sdk/provider-utils": "5.0.0", + "@ai-sdk/anthropic": "4.0.24", + "@ai-sdk/google": "4.0.28", + "@ai-sdk/openai-compatible": "3.0.17", + "@ai-sdk/provider": "4.0.4", + "@ai-sdk/provider-utils": "5.0.15", "google-auth-library": "^10.6.2" }, "engines": { @@ -100,13 +100,13 @@ } }, "node_modules/@ai-sdk/openai-compatible": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/openai-compatible/-/openai-compatible-3.0.0.tgz", - "integrity": "sha512-2Ln97FfBrIKTlV/F1uTfUl+Pwk76LqrfnT5+6vu2LnSNwvLdDhTP5uMfryIrxCaYvY2MZeL4ciM1UVd52k7wTQ==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/@ai-sdk/openai-compatible/-/openai-compatible-3.0.17.tgz", + "integrity": "sha512-Y7G5nj1j2y2P8SDQCk9VSm2TmZwykpM6Ib1ofLA/Ofmr88vwRKW9fIT8E56tccmBn01l9Dqp0wq/5pabgYED2g==", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/provider": "4.0.0", - "@ai-sdk/provider-utils": "5.0.0" + "@ai-sdk/provider": "4.0.4", + "@ai-sdk/provider-utils": "5.0.15" }, "engines": { "node": ">=22" @@ -116,9 +116,9 @@ } }, "node_modules/@ai-sdk/provider": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-4.0.0.tgz", - "integrity": "sha512-fr9Gs89prDWiuox/T+kCA+i2cJkHpxU5S+tr4megjTzRC27ZsvFhwjU/+XrqqMbvBUlfmXxTOYWy8ng45dsjIg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-4.0.4.tgz", + "integrity": "sha512-tbHKNLirllUNF3ZlkCsXnwab2ZV1Sl4b1H/Cp9ruCce15IBmskE8Gwkk0yo9xDWY+jho2of7lVXtwSsyrq7cwQ==", "license": "Apache-2.0", "dependencies": { "json-schema": "^0.4.0" @@ -128,15 +128,16 @@ } }, "node_modules/@ai-sdk/provider-utils": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-5.0.0.tgz", - "integrity": "sha512-zj66M02jc6ASYwIgWZowsooDUwaVngeNZQ3H10GwcPMZ+KR6gHMhcUuKl6tkai+JPXTKDyHY1pnszuxRtw2D4A==", + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-5.0.15.tgz", + "integrity": "sha512-dnDM4/fS17qO+D7LxVU4003V1+8ZDEWgG7rPhvcDNNFs269qLx+Jnm2mTf72ejyjdzu+f0J+rKNSLXWjZWzxwA==", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/provider": "4.0.0", + "@ai-sdk/provider": "4.0.4", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", - "eventsource-parser": "^3.0.8" + "eventsource-parser": "^3.0.8", + "undici": "^7.28.0" }, "engines": { "node": ">=22" @@ -584,9 +585,9 @@ } }, "node_modules/@types/node": { - "version": "24.13.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.2.tgz", - "integrity": "sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==", + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", "license": "MIT", "dependencies": { "undici-types": "~7.18.0" @@ -613,6 +614,326 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "license": "MIT" }, + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/@vercel/oidc": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.2.0.tgz", @@ -638,14 +959,14 @@ } }, "node_modules/ai": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/ai/-/ai-7.0.2.tgz", - "integrity": "sha512-VMU08jHIDJnnKDrbC9AFa5ZsPpOTfAPRLvTRHtJk4FGAoeldmJROMxvZ2ak5lCjEJ2GP2OLPQbMRyEK8w0+S4A==", + "version": "7.0.42", + "resolved": "https://registry.npmjs.org/ai/-/ai-7.0.42.tgz", + "integrity": "sha512-61AEmo8DynuQmfxt1yOJHLJRonCnzK5baFvN6bsDiuOTt/qYk9ZexpbG4aRv3F6rx418BV6Eyblj6fA7UcH5vQ==", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/gateway": "4.0.2", - "@ai-sdk/provider": "4.0.0", - "@ai-sdk/provider-utils": "5.0.0" + "@ai-sdk/gateway": "4.0.32", + "@ai-sdk/provider": "4.0.4", + "@ai-sdk/provider-utils": "5.0.15" }, "engines": { "node": ">=22" @@ -723,12 +1044,12 @@ "license": "BSD-3-Clause" }, "node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.0.tgz", + "integrity": "sha512-2uNTXIuTTxk7ciZgAU1BQcgnchcG0xXnrs6jzkQfj9SsRa9M2s5zE8WT96hS6KmG4MzWHSrvH43DF1m4XRkrFg==", "license": "MIT", "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=22" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" @@ -755,9 +1076,9 @@ "license": "MIT" }, "node_modules/csv-parse": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-7.0.0.tgz", - "integrity": "sha512-CSssqPAK5us09FhMI9juM0jnqXUJP+rtWeIfivTYBLNH/8rnxkQlZvoRemF6MAyfNov9XU8mN2wwF/pP68sxTA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-7.0.1.tgz", + "integrity": "sha512-+2z7Ar0APQ7Uu6fX4cn+pitRmxjZ1WPBcGmZFKmA74FCyi7Et/XZx8cjNQ5CjbZ4HCOxXCOpRBYvYH08Qa003A==", "license": "MIT" }, "node_modules/data-uri-to-buffer": { @@ -983,9 +1304,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", "license": "MIT", "engines": { "node": ">=18" @@ -1183,9 +1504,9 @@ } }, "node_modules/p-limit": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.0.tgz", - "integrity": "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.1.tgz", + "integrity": "sha512-0trZaiG7Y7kN/Egy9a8j47t9osC0Tch4PaIWd9yGF6bvmlk7muExRvGNYb8sXBwEKMoNKsbNN9P8EefuQekE4Q==", "license": "MIT", "dependencies": { "yocto-queue": "^1.2.1" @@ -1437,9 +1758,9 @@ } }, "node_modules/tsx": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.4.tgz", - "integrity": "sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.1.tgz", + "integrity": "sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==", "license": "MIT", "dependencies": { "esbuild": "~0.28.0" @@ -1455,16 +1776,37 @@ } }, "node_modules/typescript": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", - "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", "license": "Apache-2.0", "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "tsc": "bin/tsc" }, "engines": { - "node": ">=14.17" + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" } }, "node_modules/uglify-js": { @@ -1480,6 +1822,15 @@ "node": ">=0.8.0" } }, + "node_modules/undici": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz", + "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { "version": "7.18.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", @@ -1549,15 +1900,15 @@ } }, "node_modules/yargs": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", - "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz", + "integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==", "license": "MIT", "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "string-width": "^7.2.0", + "string-width": "^8.2.1", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" }, @@ -1574,6 +1925,22 @@ "node": "^20.19.0 || ^22.12.0 || >=23" } }, + "node_modules/yargs/node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yocto-queue": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", diff --git a/package.json b/package.json index bf53ce9522..cf166f47af 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@types/tmp": "^0.2.6", "@types/yargs": "^17.0.35", "ai": "^7.0.0", - "chalk": "^5.6.2", + "chalk": "^6.0.0", "csv-parse": "^7.0.0", "handlebars": "^4.7.9", "p-limit": "^7.2.0", @@ -29,7 +29,7 @@ "strip-ansi": "^7.1.2", "tmp": "^0.2.5", "tsx": "^4.20.6", - "typescript": "^6.0.0", + "typescript": "^7.0.0", "yaml": "^2.8.3", "yargs": "^18.0.0", "zod": "^4.0.0" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5c97b7a605..c345b628c4 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.96" +channel = "1.97" profile = "default"