diff --git a/Cargo.lock b/Cargo.lock index 0e9a072d3..93921bb99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,11 +4,11 @@ version = 4 [[package]] name = "actix-codec" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.1", "bytes", "futures-core", "futures-sink", @@ -21,9 +21,9 @@ dependencies = [ [[package]] name = "actix-cors" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e772b3bcafe335042b5db010ab7c09013dad6eac4915c91d8d50902769f331" +checksum = "daa239b93927be1ff123eebada5a3ff23e89f0124ccb8609234e5103d5a5ae6d" dependencies = [ "actix-utils", "actix-web", @@ -36,27 +36,27 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" +checksum = "44dfe5c9e0004c623edc65391dfd51daa201e7e30ebd9c9bedf873048ec32bc2" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-tls", "actix-utils", - "ahash 0.8.11", "base64 0.22.1", - "bitflags 2.9.0", - "brotli", + "bitflags 2.9.1", + "brotli 8.0.1", "bytes", "bytestring", "derive_more", "encoding_rs", "flate2", + "foldhash", "futures-core", "h2 0.3.26", - "http 0.2.11", + "http 0.2.12", "httparse", "httpdate", "itoa", @@ -65,7 +65,7 @@ dependencies = [ "mime", "percent-encoding", "pin-project-lite", - "rand 0.8.5", + "rand 0.9.1", "sha1", "smallvec", "tokio", @@ -80,7 +80,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -91,7 +91,8 @@ checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", "cfg-if", - "http 0.2.11", + "http 0.2.12", + "regex", "regex-lite", "serde", "tracing", @@ -110,30 +111,28 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.2.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327" +checksum = "a65064ea4a457eaf07f2fba30b4c695bf43b721790e9530d26cb6f9019ff7502" dependencies = [ "actix-rt", "actix-service", "actix-utils", "futures-core", "futures-util", - "mio 0.8.11", - "num_cpus", - "socket2 0.4.9", + "mio", + "socket2", "tokio", "tracing", ] [[package]] name = "actix-service" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +checksum = "9e46f36bf0e5af44bdc4bdb36fbbd421aa98c79a9bce724e1edeb3894e10dc7f" dependencies = [ "futures-core", - "paste", "pin-project-lite", ] @@ -168,9 +167,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.9.0" +version = "4.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" +checksum = "a597b77b5c6d6a1e1097fddde329a83665e25c5437c696a3a9a4aa514a614dea" dependencies = [ "actix-codec", "actix-http", @@ -182,13 +181,13 @@ dependencies = [ "actix-tls", "actix-utils", "actix-web-codegen", - "ahash 0.8.11", "bytes", "bytestring", "cfg-if", "cookie", "derive_more", "encoding_rs", + "foldhash", "futures-core", "futures-util", "impl-more", @@ -203,8 +202,9 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.10", + "socket2", "time", + "tracing", "url", ] @@ -217,24 +217,55 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", +] + +[[package]] +name = "actix-web-lab" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33034dd88446a5deb20e42156dbfe43d07e0499345db3ae65b3f51854190531" +dependencies = [ + "actix-http", + "actix-router", + "actix-service", + "actix-utils", + "actix-web", + "ahash 0.8.12", + "arc-swap", + "bytes", + "bytestring", + "csv", + "derive_more", + "form_urlencoded", + "futures-core", + "futures-util", + "http 0.2.12", + "impl-more", + "itertools 0.14.0", + "local-channel", + "mime", + "pin-project-lite", + "regex", + "serde", + "serde_html_form", + "serde_json", + "serde_path_to_error", + "tokio", + "tokio-stream", + "tracing", + "url", ] [[package]] name = "addr2line" -version = "0.20.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.0" @@ -264,20 +295,20 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "const-random", - "getrandom 0.2.15", + "getrandom 0.3.3", "once_cell", "version_check", "zerocopy", @@ -321,15 +352,16 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] @@ -341,30 +373,31 @@ checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "once_cell_polyfill", + "windows-sys 0.59.0", ] [[package]] @@ -392,10 +425,16 @@ dependencies = [ ] [[package]] -name = "arrayvec" -version = "0.7.4" +name = "arc-swap" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "arroy" @@ -430,14 +469,49 @@ dependencies = [ ] [[package]] -name = "async-trait" -version = "0.1.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" +name = "async-openai" +version = "0.28.1" +source = "git+https://github.com/meilisearch/async-openai?branch=better-error-handling#42d05e5f7dd7cdd46115c0855965f0b3f24754a2" +dependencies = [ + "async-openai-macros", + "backoff", + "base64 0.22.1", + "bytes", + "derive_builder 0.20.2", + "eventsource-stream", + "futures", + "rand 0.8.5", + "reqwest", + "reqwest-eventsource", + "secrecy", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", +] + +[[package]] +name = "async-openai-macros" +version = "0.1.0" +source = "git+https://github.com/meilisearch/async-openai?branch=better-error-handling#42d05e5f7dd7cdd46115c0855965f0b3f24754a2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", +] + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", ] [[package]] @@ -448,23 +522,37 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "futures-core", + "getrandom 0.2.16", + "instant", + "pin-project-lite", + "rand 0.8.5", + "tokio", +] [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", - "miniz_oxide 0.7.2", + "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -497,7 +585,7 @@ dependencies = [ "anyhow", "bumpalo", "bytes", - "convert_case 0.6.0", + "convert_case", "criterion", "csv", "flate2", @@ -505,7 +593,7 @@ dependencies = [ "milli", "mimalloc", "rand 0.8.5", - "rand_chacha", + "rand_chacha 0.3.1", "reqwest", "roaring", "serde_json", @@ -542,7 +630,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cexpr", "clang-sys", "itertools 0.13.0", @@ -551,7 +639,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -588,9 +676,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" dependencies = [ "serde", ] @@ -627,9 +715,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" dependencies = [ "borsh-derive", "cfg_aliases", @@ -637,16 +725,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.1" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", - "syn_derive", + "syn 2.0.101", ] [[package]] @@ -657,14 +744,35 @@ checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", - "brotli-decompressor", + "brotli-decompressor 4.0.3", +] + +[[package]] +name = "brotli" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor 5.0.0", ] [[package]] name = "brotli-decompressor" -version = "4.0.1" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -672,9 +780,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.3" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "regex-automata", @@ -692,9 +800,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" dependencies = [ "allocator-api2", "serde", @@ -709,7 +817,7 @@ dependencies = [ "allocator-api2", "bitpacking", "bumpalo", - "hashbrown 0.15.2", + "hashbrown 0.15.3", "serde", "serde_json", ] @@ -749,15 +857,15 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.3" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" [[package]] name = "bytemuck" -version = "1.21.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" dependencies = [ "bytemuck_derive", ] @@ -770,7 +878,7 @@ checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -781,15 +889,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "bytestring" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" +checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" dependencies = [ "bytes", ] @@ -815,55 +923,55 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" dependencies = [ "serde", ] [[package]] name = "candle-core" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "855dfedff437d2681d68e1f34ae559d88b0dd84aa5a6b63f2c8e75ebdd875bbf" +checksum = "06ccf5ee3532e66868516d9b315f73aec9f34ea1a37ae98514534d458915dbf1" dependencies = [ "byteorder", "candle-kernels", "cudarc", - "gemm", - "half 2.4.1", + "gemm 0.17.1", + "half", "memmap2", "num-traits", "num_cpus", - "rand 0.8.5", + "rand 0.9.1", "rand_distr", "rayon", "safetensors", "thiserror 1.0.69", "ug", "ug-cuda", - "yoke", + "yoke 0.7.5", "zip 1.1.4", ] [[package]] name = "candle-kernels" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53343628fa470b7075c28c589b98735b4220b464e37ddbb8e117040e199f4787" +checksum = "a10885bd902fad1b8518ba2b22369aaed88a3d94e123533ad3ca73db33b1c8ca" dependencies = [ "bindgen_cuda", ] [[package]] name = "candle-nn" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd3c6b2ee0dfd64af12ae5b07e4b7c517898981cdaeffcb10b71d7dd5c8f359" +checksum = "be1160c3b63f47d40d91110a3e1e1e566ae38edddbbf492a60b40ffc3bc1ff38" dependencies = [ "candle-core", - "half 2.4.1", + "half", "num-traits", "rayon", "safetensors", @@ -873,16 +981,16 @@ dependencies = [ [[package]] name = "candle-transformers" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4270cc692c4a3df2051c2e8c3c4da3a189746af7ca3a547b99ecd335582b92e1" +checksum = "94a0900d49f8605e0e7e6693a1f560e6271279de98e5fa369e7abf3aac245020" dependencies = [ "byteorder", "candle-core", "candle-nn", "fancy-regex", "num-traits", - "rand 0.8.5", + "rand 0.9.1", "rayon", "serde", "serde_json", @@ -892,18 +1000,18 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] [[package]] name = "cargo_metadata" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8769706aad5d996120af43197bf46ef6ad0fda35216b4505f926a365a232d924" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ "camino", "cargo-platform", @@ -931,9 +1039,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.16" +version = "1.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" dependencies = [ "jobserver", "libc", @@ -1004,9 +1112,9 @@ dependencies = [ [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -1015,18 +1123,18 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", - "half 1.8.2", + "half", ] [[package]] @@ -1041,9 +1149,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -1052,9 +1160,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.24" +version = "4.5.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" +checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f" dependencies = [ "clap_builder", "clap_derive", @@ -1062,9 +1170,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.24" +version = "4.5.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" +checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51" dependencies = [ "anstream", "anstyle", @@ -1074,14 +1182,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.24" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -1104,9 +1212,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "concat-arrays" @@ -1121,15 +1229,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.7" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", - "lazy_static", "libc", + "once_cell", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.59.0", ] [[package]] @@ -1147,22 +1255,16 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "once_cell", "tiny-keccak", ] [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "convert_case" @@ -1184,6 +1286,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1201,18 +1313,18 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crc" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] @@ -1279,9 +1391,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -1298,24 +1410,24 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "crypto-common" @@ -1341,20 +1453,20 @@ dependencies = [ [[package]] name = "csv-core" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" dependencies = [ "memchr", ] [[package]] name = "cudarc" -version = "0.12.2" +version = "0.13.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd76de2aa3a7bdb9a65941ea5a3c688d941688f736a81b2fc5beb88747a7f25" +checksum = "486c221362668c63a1636cfa51463b09574433b39029326cff40864b3ba12b6e" dependencies = [ - "half 2.4.1", + "half", "libloading", ] @@ -1370,12 +1482,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core 0.20.10", - "darling_macro 0.20.10", + "darling_core 0.20.11", + "darling_macro 0.20.11", ] [[package]] @@ -1394,16 +1506,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -1419,13 +1531,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core 0.20.10", + "darling_core 0.20.11", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -1469,9 +1581,9 @@ checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", "serde", @@ -1485,7 +1597,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -1524,10 +1636,10 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling 0.20.10", + "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -1547,20 +1659,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core 0.20.2", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ - "convert_case 0.4.0", "proc-macro2", "quote", - "rustc_version", - "syn 1.0.109", + "syn 2.0.101", + "unicode-xid", ] [[package]] @@ -1586,10 +1706,10 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aadef696fce456c704f10186def1bdc0a40e646c9f4f18cf091477acadb731d8" dependencies = [ - "convert_case 0.6.0", + "convert_case", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -1653,15 +1773,9 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - [[package]] name = "doxygen-rs" version = "0.4.2" @@ -1678,7 +1792,7 @@ dependencies = [ "anyhow", "big_s", "flate2", - "http 1.2.0", + "http 1.3.1", "maplit", "meili-snap", "meilisearch-types", @@ -1706,19 +1820,28 @@ dependencies = [ ] [[package]] -name = "either" -version = "1.13.0" +name = "dyn-stack" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "490bd48eb68fffcfed519b4edbfd82c69cbe741d175b84f0e0cbe8c57cbe0bdd" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" dependencies = [ "serde", ] [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding" @@ -1804,14 +1927,14 @@ dependencies = [ [[package]] name = "enum-as-inner" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -1831,23 +1954,23 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1856,6 +1979,17 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d817e038c30374a4bcb22f94d0a8a0e216958d4c3dcde369b1439fec4bdda6e6" +[[package]] +name = "eventsource-stream" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab" +dependencies = [ + "futures-core", + "nom", + "pin-project-lite", +] + [[package]] name = "fancy-regex" version = "0.13.0" @@ -1885,14 +2019,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] @@ -1912,7 +2046,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", - "miniz_oxide 0.8.8", + "miniz_oxide", ] [[package]] @@ -1940,9 +2074,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "form_urlencoded" @@ -2021,7 +2155,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -2036,6 +2170,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -2084,7 +2224,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce20bbb48248608ba4908b45fe36e17e40f56f8c6bb385ecf5d3c4a1e8b05a22" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "debugid", "fxhash", "serde", @@ -2098,17 +2238,37 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ab24cc62135b40090e31a76a9b2766a501979f3070fa27f689c27ec04377d32" dependencies = [ - "dyn-stack", - "gemm-c32", - "gemm-c64", - "gemm-common", - "gemm-f16", - "gemm-f32", - "gemm-f64", + "dyn-stack 0.10.0", + "gemm-c32 0.17.1", + "gemm-c64 0.17.1", + "gemm-common 0.17.1", + "gemm-f16 0.17.1", + "gemm-f32 0.17.1", + "gemm-f64 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab96b703d31950f1aeddded248bc95543c9efc7ac9c4a21fda8703a83ee35451" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-c32 0.18.2", + "gemm-c64 0.18.2", + "gemm-common 0.18.2", + "gemm-f16 0.18.2", + "gemm-f32 0.18.2", + "gemm-f64 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] @@ -2118,12 +2278,27 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9c030d0b983d1e34a546b86e08f600c11696fde16199f971cd46c12e67512c0" dependencies = [ - "dyn-stack", - "gemm-common", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm-c32" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6db9fd9f40421d00eea9dd0770045a5603b8d684654816637732463f4073847" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] @@ -2133,12 +2308,27 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbb5f2e79fefb9693d18e1066a557b4546cd334b226beadc68b11a8f9431852a" dependencies = [ - "dyn-stack", - "gemm-common", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm-c64" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfcad8a3d35a43758330b635d02edad980c1e143dc2f21e6fd25f9e4eada8edf" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] @@ -2149,17 +2339,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2e7ea062c987abcd8db95db917b4ffb4ecdfd0668471d8dc54734fdff2354e8" dependencies = [ "bytemuck", - "dyn-stack", - "half 2.4.1", + "dyn-stack 0.10.0", + "half", "num-complex", "num-traits", "once_cell", "paste", - "pulp", - "raw-cpuid", + "pulp 0.18.22", + "raw-cpuid 10.7.0", "rayon", "seq-macro", - "sysctl", + "sysctl 0.5.5", +] + +[[package]] +name = "gemm-common" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a352d4a69cbe938b9e2a9cb7a3a63b7e72f9349174a2752a558a8a563510d0f3" +dependencies = [ + "bytemuck", + "dyn-stack 0.13.0", + "half", + "libm", + "num-complex", + "num-traits", + "once_cell", + "paste", + "pulp 0.21.5", + "raw-cpuid 11.5.0", + "rayon", + "seq-macro", + "sysctl 0.6.0", ] [[package]] @@ -2168,14 +2379,32 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ca4c06b9b11952071d317604acb332e924e817bd891bec8dfb494168c7cedd4" dependencies = [ - "dyn-stack", - "gemm-common", - "gemm-f32", - "half 2.4.1", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", + "gemm-f32 0.17.1", + "half", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "rayon", + "seq-macro", +] + +[[package]] +name = "gemm-f16" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff95ae3259432f3c3410eaa919033cd03791d81cebd18018393dc147952e109" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "gemm-f32 0.18.2", + "half", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "rayon", "seq-macro", ] @@ -2186,12 +2415,27 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9a69f51aaefbd9cf12d18faf273d3e982d9d711f60775645ed5c8047b4ae113" dependencies = [ - "dyn-stack", - "gemm-common", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm-f32" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc8d3d4385393304f407392f754cd2dc4b315d05063f62cf09f47b58de276864" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] @@ -2201,12 +2445,27 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa397a48544fadf0b81ec8741e5c0fba0043008113f71f2034def1935645d2b0" dependencies = [ - "dyn-stack", - "gemm-common", + "dyn-stack 0.10.0", + "gemm-common 0.17.1", "num-complex", "num-traits", "paste", - "raw-cpuid", + "raw-cpuid 10.7.0", + "seq-macro", +] + +[[package]] +name = "gemm-f64" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35b2a4f76ce4b8b16eadc11ccf2e083252d8237c1b589558a49b0183545015bd" +dependencies = [ + "dyn-stack 0.13.0", + "gemm-common 0.18.2", + "num-complex", + "num-traits", + "paste", + "raw-cpuid 11.5.0", "seq-macro", ] @@ -2228,9 +2487,9 @@ checksum = "36d244a08113319b5ebcabad2b8b7925732d15eec46d7e7ac3c11734f3b7a6ad" [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", @@ -2241,31 +2500,31 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.13.3+wasi-0.2.2", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", "wasm-bindgen", - "windows-targets 0.52.6", ] [[package]] name = "gimli" -version = "0.27.3" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git2" -version = "0.19.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "libc", "libgit2-sys", "log", @@ -2302,7 +2561,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.11", + "http 0.2.12", "indexmap", "slab", "tokio", @@ -2312,16 +2571,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.5" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.2.0", + "http 1.3.1", "indexmap", "slab", "tokio", @@ -2331,21 +2590,15 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "bytemuck", "cfg-if", "crunchy", "num-traits", - "rand 0.8.5", + "rand 0.9.1", "rand_distr", ] @@ -2369,19 +2622,19 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "allocator-api2", ] [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "allocator-api2", "equivalent", @@ -2399,12 +2652,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2417,7 +2664,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a56c94661ddfb51aa9cdfbf102cfcc340aa69267f95ebccc4af08d7c530d393" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "byteorder", "heed-traits", "heed-types", @@ -2450,15 +2697,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" [[package]] name = "hex" @@ -2472,7 +2713,7 @@ version = "0.3.2" source = "git+https://github.com/dureuill/hf-hub.git?branch=rust_tls#88d4f11cb9fa079f2912bacb96f5080b16825ce8" dependencies = [ "dirs", - "http 1.2.0", + "http 1.3.1", "indicatif", "log", "rand 0.8.5", @@ -2493,9 +2734,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -2504,9 +2745,9 @@ dependencies = [ [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -2515,23 +2756,23 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.2.0", + "http 1.3.1", ] [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", - "http 1.2.0", + "futures-core", + "http 1.3.1", "http-body", "pin-project-lite", ] @@ -2544,9 +2785,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" @@ -2557,8 +2798,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", - "http 1.2.0", + "h2 0.4.10", + "http 1.3.1", "http-body", "httparse", "httpdate", @@ -2571,20 +2812,20 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d" dependencies = [ - "futures-util", - "http 1.2.0", + "http 1.3.1", "hyper", "hyper-util", "rustls", + "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", - "webpki-roots 0.26.1", + "webpki-roots 1.0.0", ] [[package]] @@ -2598,14 +2839,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "http 1.2.0", + "http 1.3.1", "http-body", "hyper", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2", "tokio", "tower-service", "tracing", @@ -2613,21 +2854,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", - "yoke", + "potential_utf", + "yoke 0.8.0", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -2636,31 +2878,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -2668,67 +2890,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", - "yoke", + "yoke 0.8.0", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -2748,9 +2957,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -2758,9 +2967,9 @@ dependencies = [ [[package]] name = "impl-more" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" +checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" [[package]] name = "include-flate" @@ -2782,7 +2991,7 @@ dependencies = [ "libflate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -2795,7 +3004,7 @@ dependencies = [ "bumpalo", "bumparaw-collections", "byte-unit", - "convert_case 0.6.0", + "convert_case", "crossbeam-channel", "csv", "derive_builder 0.20.2", @@ -2826,33 +3035,33 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.3", "serde", ] [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" dependencies = [ "console", - "instant", "number_prefix", "portable-atomic", "unicode-width", + "web-time", ] [[package]] name = "inout" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ "generic-array", ] @@ -2874,9 +3083,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2910,15 +3119,21 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.13" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.4.0", + "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.10.5" @@ -2966,9 +3181,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jieba-macros" @@ -2981,9 +3196,9 @@ dependencies = [ [[package]] name = "jieba-rs" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1bcad6332969e4d48ee568d430e14ee6dea70740c2549d005d87677ebefb0c" +checksum = "b06096b4b61fb4bfdbf16c6a968ea2d6be1ac9617cf3db741c3b641e6c290a35" dependencies = [ "cedarwood", "fxhash", @@ -2996,10 +3211,11 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.3", "libc", ] @@ -3023,11 +3239,11 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "9.3.0" +version = "9.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "js-sys", "pem", "ring", @@ -3047,9 +3263,9 @@ dependencies = [ [[package]] name = "kstring" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" dependencies = [ "serde", "static_assertions", @@ -3078,9 +3294,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libflate" @@ -3102,15 +3318,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" dependencies = [ "core2", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "rle-decode-fast", ] [[package]] name = "libgit2-sys" -version = "0.17.0+1.8.1" +version = "0.18.1+1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +checksum = "e1dcb20f84ffcdd825c7a311ae347cce604a6f084a767dec4a4929829645290e" dependencies = [ "cc", "libc", @@ -3120,25 +3336,25 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.53.0", ] [[package]] name = "libm" -version = "0.2.8" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libmimalloc-sys" -version = "0.1.39" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" +checksum = "ec9d6fac27761dabcd4ee73571cdb06b7022dc99089acbe5435691edffaac0f4" dependencies = [ "cc", "libc", @@ -3156,10 +3372,21 @@ dependencies = [ ] [[package]] -name = "libz-sys" -version = "1.1.15" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.9.1", + "libc", + "redox_syscall", +] + +[[package]] +name = "libz-sys" +version = "1.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" dependencies = [ "cc", "libc", @@ -3298,17 +3525,22 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "liquid" -version = "0.26.9" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdcc72b82748f47c2933c172313f5a9aea5b2c4eb3fa4c66b4ea55bb60bb4b1" +checksum = "2a494c3f9dad3cb7ed16f1c51812cbe4b29493d6c2e5cd1e2b87477263d9534d" dependencies = [ - "doc-comment", "liquid-core", "liquid-derive", "liquid-lib", @@ -3317,15 +3549,14 @@ dependencies = [ [[package]] name = "liquid-core" -version = "0.26.9" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2752e978ffc53670f3f2e8b3ef09f348d6f7b5474a3be3f8a5befe5382e4effb" +checksum = "fc623edee8a618b4543e8e8505584f4847a4e51b805db1af6d9af0a3395d0d57" dependencies = [ "anymap2", - "itertools 0.13.0", + "itertools 0.14.0", "kstring", "liquid-derive", - "num-traits", "pest", "pest_derive", "regex", @@ -3335,24 +3566,23 @@ dependencies = [ [[package]] name = "liquid-derive" -version = "0.26.8" +version = "0.26.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b51f1d220e3fa869e24cfd75915efe3164bd09bb11b3165db3f37f57bf673e3" +checksum = "de66c928222984aea59fcaed8ba627f388aaac3c1f57dcb05cc25495ef8faefe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] name = "liquid-lib" -version = "0.26.9" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b1a298d3d2287ee5b1e43840d885b8fdfc37d3f4e90d82aacfd04d021618da" +checksum = "9befeedd61f5995bc128c571db65300aeb50d62e4f0542c88282dbcb5f72372a" dependencies = [ - "itertools 0.13.0", + "itertools 0.14.0", "liquid-core", - "once_cell", "percent-encoding", "regex", "time", @@ -3361,9 +3591,9 @@ dependencies = [ [[package]] name = "litemap" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lmdb-master-sys" @@ -3378,38 +3608,31 @@ dependencies = [ [[package]] name = "local-channel" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" dependencies = [ "futures-core", "futures-sink", - "futures-util", "local-waker", ] [[package]] name = "local-waker" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", ] -[[package]] -name = "lockfree-object-pool" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" - [[package]] name = "log" version = "0.4.27" @@ -3422,9 +3645,15 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.3", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "lzma-rs" version = "0.3.0" @@ -3448,9 +3677,9 @@ dependencies = [ [[package]] name = "macro_rules_attribute" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a82271f7bc033d84bbca59a3ce3e4159938cb08a9c3aebbe54d215131518a13" +checksum = "65049d7923698040cd0b1ddcced9b0eb14dd22c5f86ae59c3740eab64a676520" dependencies = [ "macro_rules_attribute-proc_macro", "paste", @@ -3458,9 +3687,9 @@ dependencies = [ [[package]] name = "macro_rules_attribute-proc_macro" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568" +checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" [[package]] name = "manifest-dir-macros" @@ -3471,7 +3700,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -3504,11 +3733,14 @@ dependencies = [ "actix-rt", "actix-utils", "actix-web", + "actix-web-lab", "anyhow", + "async-openai", "async-trait", - "brotli", + "brotli 6.0.0", "bstr", "build-info", + "bumpalo", "byte-unit", "bytes", "cargo_toml", @@ -3555,13 +3787,14 @@ dependencies = [ "rustls", "rustls-pemfile", "rustls-pki-types", + "secrecy", "segment", "serde", "serde_json", "serde_urlencoded", "sha-1", "sha2", - "siphasher 1.0.1", + "siphasher", "slice-group-by", "static-files", "sysinfo", @@ -3584,7 +3817,7 @@ dependencies = [ "uuid", "wiremock", "yaup", - "zip 2.3.0", + "zip 2.4.2", ] [[package]] @@ -3614,7 +3847,7 @@ dependencies = [ "anyhow", "bumpalo", "bumparaw-collections", - "convert_case 0.6.0", + "convert_case", "csv", "deserr", "either", @@ -3627,7 +3860,7 @@ dependencies = [ "memmap2", "milli", "roaring", - "rustc-hash 2.1.0", + "rustc-hash 2.1.1", "serde", "serde-cs", "serde_json", @@ -3694,7 +3927,7 @@ dependencies = [ "candle-transformers", "charabia", "concat-arrays", - "convert_case 0.6.0", + "convert_case", "crossbeam-channel", "csv", "deserr", @@ -3707,7 +3940,7 @@ dependencies = [ "fxhash", "geoutils", "grenad", - "hashbrown 0.15.2", + "hashbrown 0.15.3", "heed", "hf-hub", "indexmap", @@ -3732,7 +3965,7 @@ dependencies = [ "rhai", "roaring", "rstar", - "rustc-hash 2.1.0", + "rustc-hash 2.1.1", "serde", "serde_json", "slice-group-by", @@ -3755,9 +3988,9 @@ dependencies = [ [[package]] name = "mimalloc" -version = "0.1.43" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" +checksum = "995942f432bbb4822a7e9c3faa87a695185b0d09273ba85f097b54f4e458f2af" dependencies = [ "libmimalloc-sys", ] @@ -3770,9 +4003,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -3784,15 +4017,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.8" @@ -3804,32 +4028,21 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", -] - -[[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" -dependencies = [ - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "monostate" -version = "0.1.9" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f370ae88093ec6b11a710dec51321a61d420fafd1bad6e30d01bd9c920e8ee" +checksum = "aafe1be9d0c75642e3e50fedc7ecadf1ef1cbce6eb66462153fc44245343fbee" dependencies = [ "monostate-impl", "serde", @@ -3837,13 +4050,13 @@ dependencies = [ [[package]] name = "monostate-impl" -version = "0.1.9" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "371717c0a5543d6a800cac822eac735aa7d2d2fbb41002e9856a4089532dbdce" +checksum = "c402a4092d5e204f32c9e155431046831fa712637043c58cb73bc6bc6c9663b5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -3987,33 +4200,33 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -4033,9 +4246,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.31.1" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] @@ -4053,12 +4266,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "onig" -version = "6.4.0" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "onig" +version = "6.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.1", "libc", "once_cell", "onig_sys", @@ -4066,9 +4285,9 @@ dependencies = [ [[package]] name = "onig_sys" -version = "69.8.1" +version = "69.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7" +checksum = "c7f86c6eef3d6df15f23bcfb6af487cbd2fed4e5581d58d5bf1f5f8b7f6727dc" dependencies = [ "cc", "pkg-config", @@ -4076,9 +4295,15 @@ dependencies = [ [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "option-ext" @@ -4119,9 +4344,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -4129,22 +4354,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", - "windows-targets 0.48.1", + "windows-targets 0.52.6", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "path-matchers" @@ -4173,11 +4398,11 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.3" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "serde", ] @@ -4197,19 +4422,20 @@ dependencies = [ [[package]] name = "pest" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" dependencies = [ - "thiserror 1.0.69", + "memchr", + "thiserror 2.0.12", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5" dependencies = [ "pest", "pest_generator", @@ -4217,22 +4443,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] name = "pest_meta" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0" dependencies = [ "once_cell", "pest", @@ -4241,9 +4467,9 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", "phf_shared", @@ -4251,9 +4477,9 @@ dependencies = [ [[package]] name = "phf_codegen" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" dependencies = [ "phf_generator", "phf_shared", @@ -4261,9 +4487,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", "rand 0.8.5", @@ -4271,44 +4497,44 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ "phf_generator", "phf_shared", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher 0.3.11", + "siphasher", ] [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -4331,9 +4557,9 @@ checksum = "16f2611cd06a1ac239a0cea4521de9eb068a6ca110324ee00631aa68daa74fc0" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "platform-dirs" @@ -4346,9 +4572,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -4359,24 +4585,33 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] [[package]] name = "portable-atomic" -version = "1.5.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] [[package]] name = "powerfmt" @@ -4386,47 +4621,27 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ - "toml_edit 0.21.0", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", + "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -4437,10 +4652,10 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "hex", "procfs-core", - "rustix", + "rustix 0.38.44", ] [[package]] @@ -4449,7 +4664,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "hex", ] @@ -4512,9 +4727,9 @@ dependencies = [ [[package]] name = "pulp" -version = "0.18.9" +version = "0.18.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03457ac216146f43f921500bac4e892d5cd32b0479b929cbfc90f95cd6c599c2" +checksum = "a0a01a0dc67cf4558d279f0c25b0962bd08fc6dec0137699eae304103e882fe6" dependencies = [ "bytemuck", "libm", @@ -4523,61 +4738,89 @@ dependencies = [ ] [[package]] -name = "quinn" -version = "0.11.2" +name = "pulp" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" +checksum = "96b86df24f0a7ddd5e4b95c94fc9ed8a98f1ca94d3b01bdce2824097e7835907" +dependencies = [ + "bytemuck", + "cfg-if", + "libm", + "num-complex", + "reborrow", + "version_check", +] + +[[package]] +name = "quinn" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 1.1.0", + "rustc-hash 2.1.1", "rustls", - "thiserror 1.0.69", + "socket2", + "thiserror 2.0.12", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.8" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" dependencies = [ "bytes", - "rand 0.8.5", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.1", "ring", - "rustc-hash 2.1.0", + "rustc-hash 2.1.1", "rustls", + "rustls-pki-types", "slab", - "thiserror 1.0.69", + "thiserror 2.0.12", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.5.2" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46" +checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842" dependencies = [ + "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "radium" version = "0.7.0" @@ -4591,7 +4834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -4601,6 +4844,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ + "rand_chacha 0.9.0", "rand_core 0.9.3", ] @@ -4614,13 +4858,23 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -4628,15 +4882,18 @@ name = "rand_core" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] [[package]] name = "rand_distr" -version = "0.4.3" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.9.1", ] [[package]] @@ -4648,6 +4905,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "raw-cpuid" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +dependencies = [ + "bitflags 2.9.1", +] + [[package]] name = "rayon" version = "1.10.0" @@ -4696,30 +4962,21 @@ checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.1", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.15", - "redox_syscall 0.2.16", + "getrandom 0.2.16", + "libredox", "thiserror 1.0.69", ] @@ -4778,7 +5035,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "http 1.2.0", + "http 1.3.1", "http-body", "http-body-util", "hyper", @@ -4788,11 +5045,13 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls", + "rustls-native-certs", "rustls-pki-types", "serde", "serde_json", @@ -4812,13 +5071,29 @@ dependencies = [ "webpki-roots 1.0.0", ] +[[package]] +name = "reqwest-eventsource" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632c55746dbb44275691640e7b40c907c16a2dc1a5842aa98aaec90da6ec6bde" +dependencies = [ + "eventsource-stream", + "futures-core", + "futures-timer", + "mime", + "nom", + "pin-project-lite", + "reqwest", + "thiserror 1.0.69", +] + [[package]] name = "rhai" version = "1.20.0" source = "git+https://github.com/rhaiscript/rhai?rev=ef3df63121d27aacd838f366f2b83fd65f20a1e4#ef3df63121d27aacd838f366f2b83fd65f20a1e4" dependencies = [ - "ahash 0.8.11", - "bitflags 2.9.0", + "ahash 0.8.12", + "bitflags 2.9.1", "instant", "num-traits", "once_cell", @@ -4836,7 +5111,7 @@ source = "git+https://github.com/rhaiscript/rhai?rev=ef3df63121d27aacd838f366f2b dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -4847,7 +5122,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -4855,9 +5130,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", @@ -4873,9 +5148,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ "proc-macro2", "quote", @@ -4890,9 +5165,9 @@ checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" [[package]] name = "roaring" -version = "0.10.10" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a652edd001c53df0b3f96a36a8dc93fce6866988efc16808235653c6bcac8bf2" +checksum = "19e8d2cfa184d94d0726d650a9f4a1be7f9b76ac9fdb954219878dc00c1c1e7b" dependencies = [ "bytemuck", "byteorder", @@ -4913,9 +5188,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "faa7de2ba56ac291bd90c6b9bece784a52ae1411f9506544b3eae36dd2356d50" dependencies = [ "arrayvec", "borsh", @@ -4929,9 +5204,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -4941,37 +5216,41 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rustix" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "semver", + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", ] [[package]] name = "rustix" -version = "0.38.41" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", - "linux-raw-sys", - "windows-sys 0.52.0", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" dependencies = [ "log", "once_cell", @@ -4982,6 +5261,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -4993,15 +5284,19 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "web-time", + "zeroize", +] [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" dependencies = [ "ring", "rustls-pki-types", @@ -5010,21 +5305,21 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.19" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "safetensors" -version = "0.4.2" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d980e6bfb34436fb0a81e42bc41af43f11805bbbca443e7f68e9faaabe669ed" +checksum = "44560c11236a6130a46ce36c836a62936dc81ebf8c36a37947423571be0e55b6" dependencies = [ "serde", "serde_json", @@ -5039,6 +5334,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -5052,10 +5356,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] -name = "segment" -version = "0.2.5" +name = "secrecy" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd0f21b6eb87a45a7cce06075a29ccdb42658a6eb84bf40c8fc179479630609" +checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" +dependencies = [ + "serde", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +dependencies = [ + "bitflags 2.9.1", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "segment" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "971369158e31ad10bd73b558625f99de39554a2f00c2ff886a6796d950e69664" dependencies = [ "async-trait", "reqwest", @@ -5067,18 +5404,18 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" dependencies = [ "serde", ] [[package]] name = "seq-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" [[package]] name = "serde" @@ -5106,7 +5443,20 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", +] + +[[package]] +name = "serde_html_form" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4" +dependencies = [ + "form_urlencoded", + "indexmap", + "itoa", + "ryu", + "serde", ] [[package]] @@ -5122,6 +5472,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_plain" version = "1.0.2" @@ -5189,9 +5549,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -5215,9 +5575,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] @@ -5230,34 +5590,28 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "similar" -version = "2.2.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "simple_asn1" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 1.0.69", + "thiserror 2.0.12", "time", ] -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - [[package]] name = "siphasher" version = "1.0.1" @@ -5266,9 +5620,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -5291,9 +5645,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" dependencies = [ "serde", ] @@ -5310,16 +5664,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.10" @@ -5412,18 +5756,18 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -5438,32 +5782,20 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] @@ -5479,13 +5811,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -5494,7 +5826,21 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", + "byteorder", + "enum-as-inner", + "libc", + "thiserror 1.0.69", + "walkdir", +] + +[[package]] +name = "sysctl" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc" +dependencies = [ + "bitflags 2.9.1", "byteorder", "enum-as-inner", "libc", @@ -5544,15 +5890,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.15.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ - "cfg-if", "fastrand", - "getrandom 0.2.15", + "getrandom 0.3.3", "once_cell", - "rustix", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -5567,9 +5912,9 @@ dependencies = [ [[package]] name = "thin-vec" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" +checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d" dependencies = [ "serde", ] @@ -5600,7 +5945,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -5611,7 +5956,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -5642,9 +5987,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.37" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -5659,15 +6004,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -5684,9 +6029,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -5704,9 +6049,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -5725,7 +6070,7 @@ dependencies = [ "aho-corasick", "derive_builder 0.12.0", "esaxx-rs", - "getrandom 0.2.15", + "getrandom 0.2.16", "itertools 0.12.1", "lazy_static", "log", @@ -5756,11 +6101,11 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.3", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.10", + "socket2", "tokio-macros", "windows-sys 0.52.0", ] @@ -5773,25 +6118,35 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls", - "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", "tokio", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", @@ -5802,49 +6157,45 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.22", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.22.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.22", + "toml_write", + "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + [[package]] name = "tower" version = "0.5.2" @@ -5862,14 +6213,14 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc2d9e086a412a451384326f521c8123a99a466b329941a9403696bff9b0da2" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "bytes", "futures-util", - "http 1.2.0", + "http 1.3.1", "http-body", "iri-string", "pin-project-lite", @@ -5904,9 +6255,9 @@ dependencies = [ [[package]] name = "tracing-actix-web" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9f5c1aca50ebebf074ee665b9f99f2e84906dcf6b993a0d0090edb835166d" +checksum = "2340b7722695166c7fc9b3e3cd1166e7c74fedb9075b8f0c74d3822d2e41caf5" dependencies = [ "actix-web", "mutually_exclusive_features", @@ -5923,7 +6274,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -6002,21 +6353,21 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "ucd-trie" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uell" @@ -6029,48 +6380,52 @@ dependencies = [ [[package]] name = "ug" -version = "0.0.2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4eef2ebfc18c67a6dbcacd9d8a4d85e0568cc58c82515552382312c2730ea13" +checksum = "03719c61a91b51541f076dfdba45caacf750b230cefaa4b32d6f5411c3f7f437" dependencies = [ - "half 2.4.1", + "gemm 0.18.2", + "half", + "libloading", + "memmap2", "num", + "num-traits", + "num_cpus", + "rayon", + "safetensors", "serde", - "serde_json", "thiserror 1.0.69", + "tracing", + "yoke 0.7.5", ] [[package]] name = "ug-cuda" -version = "0.0.2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4dcab280ad0ef3957e153a82dcad608c954d02cf253b695322f502d1f8902e" +checksum = "50758486d7941f8b0a636ba7e29455c07071f41590beac1fd307ec893e8db69a" dependencies = [ "cudarc", - "half 2.4.1", + "half", "serde", - "serde_json", "thiserror 1.0.69", "ug", ] [[package]] name = "unescaper" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" +checksum = "c01d12e3a56a4432a8b436f293c25f4808bdf9e9f9f98f9260bba1f1bc5a1f26" dependencies = [ - "thiserror 1.0.69", + "thiserror 2.0.12", ] [[package]] name = "unicase" -version = "2.6.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-blocks" @@ -6080,9 +6435,9 @@ checksum = "6b12e05d9e06373163a9bb6bb8c263c261b396643a99445fe6b9811fd376581b" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-normalization" @@ -6104,15 +6459,21 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unicode_categories" @@ -6148,7 +6509,7 @@ dependencies = [ "serde_json", "socks", "url", - "webpki-roots 0.26.1", + "webpki-roots 0.26.11", ] [[package]] @@ -6169,17 +6530,11 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8-width" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" [[package]] name = "utf8_iter" @@ -6189,9 +6544,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utoipa" @@ -6214,7 +6569,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.87", + "syn 2.0.101", "uuid", ] @@ -6232,19 +6587,21 @@ dependencies = [ [[package]] name = "uuid" -version = "1.11.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.3.3", + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vcpkg" @@ -6254,9 +6611,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vergen" -version = "9.0.2" +version = "9.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f25fc8f8f05df455c7941e87f093ad22522a9ff33d7a027774815acf6f0639" +checksum = "6b2bf58be11fc9414104c6d3a2e464163db5ef74b12296bda593cac37b6e4777" dependencies = [ "anyhow", "derive_builder 0.20.2", @@ -6266,9 +6623,9 @@ dependencies = [ [[package]] name = "vergen-git2" -version = "1.0.2" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e63e069d8749fead1e3bab7a9d79e8fb90516b2ec66fc2243a798ecdc1a31d7" +checksum = "4f6ee511ec45098eabade8a0750e76eec671e7fb2d9360c563911336bea9cac1" dependencies = [ "anyhow", "derive_builder 0.20.2", @@ -6281,9 +6638,9 @@ dependencies = [ [[package]] name = "vergen-lib" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0c767e6751c09fc85cde58722cf2f1007e80e4c8d5a4321fc90d83dc54ca147" +checksum = "9b07e6010c0f3e59fcb164e0163834597da68d1f864e2b8ca49f74de01e9c166" dependencies = [ "anyhow", "derive_builder 0.20.2", @@ -6292,9 +6649,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" @@ -6334,9 +6691,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] @@ -6363,18 +6720,19 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] @@ -6397,7 +6755,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6413,9 +6771,9 @@ dependencies = [ [[package]] name = "wasm-streams" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", @@ -6426,9 +6784,19 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -6436,11 +6804,11 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.1" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "rustls-pki-types", + "webpki-roots 1.0.0", ] [[package]] @@ -6458,7 +6826,7 @@ version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "471d1c1645d361eb782a1650b1786a8fb58dd625e681a04c09f5ff7c8764a7b0" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", "once_cell", ] @@ -6480,11 +6848,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -6523,7 +6891,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -6534,7 +6902,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -6546,22 +6914,13 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -6584,32 +6943,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -6621,7 +6965,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", @@ -6629,16 +6973,26 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-targets" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" @@ -6647,16 +7001,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +name = "windows_aarch64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" @@ -6665,16 +7019,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "windows_i686_gnu" -version = "0.42.2" +name = "windows_aarch64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" @@ -6682,6 +7036,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" @@ -6689,16 +7049,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" @@ -6707,16 +7067,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +name = "windows_i686_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" @@ -6725,16 +7085,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +name = "windows_x86_64_gnu" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" @@ -6743,16 +7103,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +name = "windows_x86_64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" @@ -6761,35 +7121,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winnow" -version = "0.5.40" +name = "windows_x86_64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.6.22" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" dependencies = [ "memchr", ] [[package]] name = "wiremock" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fff469918e7ca034884c7fd8f93fe27bacb7fcb599fd879df6c7b429a29b646" +checksum = "101681b74cd87b5899e87bcf5a64e83334dd313fcd3053ea72e6dba18928e301" dependencies = [ "assert-json-diff", "async-trait", "base64 0.22.1", "deadpool", "futures", - "http 1.2.0", + "http 1.3.1", "http-body-util", "hyper", "hyper-util", @@ -6804,24 +7161,18 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "wyz" @@ -6834,13 +7185,12 @@ dependencies = [ [[package]] name = "xattr" -version = "1.3.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" dependencies = [ "libc", - "linux-raw-sys", - "rustix", + "rustix 1.0.7", ] [[package]] @@ -6900,7 +7250,19 @@ checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", - "yoke-derive", + "yoke-derive 0.7.5", + "zerofrom", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive 0.8.0", "zerofrom", ] @@ -6912,48 +7274,60 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", + "synstructure", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] name = "zerofrom" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", "synstructure", ] @@ -6974,29 +7348,40 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke 0.8.0", + "zerofrom", ] [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ - "yoke", + "yoke 0.8.0", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.101", ] [[package]] @@ -7016,9 +7401,9 @@ dependencies = [ [[package]] name = "zip" -version = "2.3.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e9a772a54b54236b9b744aaaf8d7be01b4d6e99725523cb82cb32d1c81b1d7" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" dependencies = [ "aes", "arbitrary", @@ -7029,7 +7414,7 @@ dependencies = [ "deflate64", "displaydoc", "flate2", - "getrandom 0.3.1", + "getrandom 0.3.3", "hmac", "indexmap", "lzma-rs", @@ -7046,41 +7431,39 @@ dependencies = [ [[package]] name = "zopfli" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" dependencies = [ "bumpalo", "crc32fast", - "lockfree-object-pool", "log", - "once_cell", "simd-adler32", ] [[package]] name = "zstd" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.0" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa556e971e7b568dc775c136fc9de8c779b1c2fc3a63defaafadffdbd3181afa" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ "cc", "pkg-config", diff --git a/crates/benchmarks/Cargo.toml b/crates/benchmarks/Cargo.toml index a2cddd554..a5b3a39e1 100644 --- a/crates/benchmarks/Cargo.toml +++ b/crates/benchmarks/Cargo.toml @@ -31,7 +31,7 @@ anyhow = "1.0.95" bytes = "1.9.0" convert_case = "0.6.0" flate2 = "1.0.35" -reqwest = { version = "0.12.12", features = ["blocking", "rustls-tls"], default-features = false } +reqwest = { version = "0.12.15", features = ["blocking", "rustls-tls"], default-features = false } [features] default = ["milli/all-tokenizations"] diff --git a/crates/benchmarks/benches/search_geo.rs b/crates/benchmarks/benches/search_geo.rs index d76929f99..b16eb41f1 100644 --- a/crates/benchmarks/benches/search_geo.rs +++ b/crates/benchmarks/benches/search_geo.rs @@ -2,7 +2,8 @@ mod datasets_paths; mod utils; use criterion::{criterion_group, criterion_main}; -use milli::{update::Settings, FilterableAttributesRule}; +use milli::update::Settings; +use milli::FilterableAttributesRule; use utils::Conf; #[cfg(not(windows))] diff --git a/crates/benchmarks/benches/search_songs.rs b/crates/benchmarks/benches/search_songs.rs index 680a675ef..e1cbb5730 100644 --- a/crates/benchmarks/benches/search_songs.rs +++ b/crates/benchmarks/benches/search_songs.rs @@ -2,7 +2,8 @@ mod datasets_paths; mod utils; use criterion::{criterion_group, criterion_main}; -use milli::{update::Settings, FilterableAttributesRule}; +use milli::update::Settings; +use milli::FilterableAttributesRule; use utils::Conf; #[cfg(not(windows))] diff --git a/crates/dump/src/lib.rs b/crates/dump/src/lib.rs index 95d75700e..285818a87 100644 --- a/crates/dump/src/lib.rs +++ b/crates/dump/src/lib.rs @@ -305,6 +305,7 @@ pub(crate) mod test { localized_attributes: Setting::NotSet, facet_search: Setting::NotSet, prefix_search: Setting::NotSet, + chat: Setting::NotSet, _kind: std::marker::PhantomData, }; settings.check() diff --git a/crates/dump/src/reader/compat/v5_to_v6.rs b/crates/dump/src/reader/compat/v5_to_v6.rs index 14570c258..f7bda81c6 100644 --- a/crates/dump/src/reader/compat/v5_to_v6.rs +++ b/crates/dump/src/reader/compat/v5_to_v6.rs @@ -405,6 +405,7 @@ impl From> for v6::Settings { search_cutoff_ms: v6::Setting::NotSet, facet_search: v6::Setting::NotSet, prefix_search: v6::Setting::NotSet, + chat: v6::Setting::NotSet, _kind: std::marker::PhantomData, } } diff --git a/crates/index-scheduler/src/features.rs b/crates/index-scheduler/src/features.rs index 109e6b867..78ffc0766 100644 --- a/crates/index-scheduler/src/features.rs +++ b/crates/index-scheduler/src/features.rs @@ -131,6 +131,19 @@ impl RoFeatures { .into()) } } + + pub fn check_chat_completions(&self, disabled_action: &'static str) -> Result<()> { + if self.runtime.chat_completions { + Ok(()) + } else { + Err(FeatureNotEnabledError { + disabled_action, + feature: "chat completions", + issue_link: "https://github.com/orgs/meilisearch/discussions/835", + } + .into()) + } + } } impl FeatureData { diff --git a/crates/index-scheduler/src/insta_snapshot.rs b/crates/index-scheduler/src/insta_snapshot.rs index 89e615132..d01548319 100644 --- a/crates/index-scheduler/src/insta_snapshot.rs +++ b/crates/index-scheduler/src/insta_snapshot.rs @@ -34,6 +34,7 @@ pub fn snapshot_index_scheduler(scheduler: &IndexScheduler) -> String { planned_failures: _, run_loop_iteration: _, embedders: _, + chat_settings: _, } = scheduler; let rtxn = env.read_txn().unwrap(); diff --git a/crates/index-scheduler/src/lib.rs b/crates/index-scheduler/src/lib.rs index 6ff274da7..505ce23f8 100644 --- a/crates/index-scheduler/src/lib.rs +++ b/crates/index-scheduler/src/lib.rs @@ -51,10 +51,12 @@ pub use features::RoFeatures; use flate2::bufread::GzEncoder; use flate2::Compression; use meilisearch_types::batches::Batch; -use meilisearch_types::features::{InstanceTogglableFeatures, Network, RuntimeTogglableFeatures}; +use meilisearch_types::features::{ + ChatCompletionSettings, InstanceTogglableFeatures, Network, RuntimeTogglableFeatures, +}; use meilisearch_types::heed::byteorder::BE; -use meilisearch_types::heed::types::I128; -use meilisearch_types::heed::{self, Env, RoTxn, WithoutTls}; +use meilisearch_types::heed::types::{DecodeIgnore, SerdeJson, Str, I128}; +use meilisearch_types::heed::{self, Database, Env, RoTxn, WithoutTls}; use meilisearch_types::milli::index::IndexEmbeddingConfig; use meilisearch_types::milli::update::IndexerConfig; use meilisearch_types::milli::vector::{Embedder, EmbedderOptions, EmbeddingConfigs}; @@ -75,6 +77,7 @@ use crate::utils::clamp_to_page_size; pub(crate) type BEI128 = I128; const TASK_SCHEDULER_SIZE_THRESHOLD_PERCENT_INT: u64 = 40; +const CHAT_SETTINGS_DB_NAME: &str = "chat-settings"; #[derive(Debug)] pub struct IndexSchedulerOptions { @@ -153,6 +156,9 @@ pub struct IndexScheduler { /// In charge of fetching and setting the status of experimental features. features: features::FeatureData, + /// Stores the custom chat prompts and other settings of the indexes. + pub(crate) chat_settings: Database>, + /// Everything related to the processing of the tasks pub scheduler: scheduler::Scheduler, @@ -211,11 +217,16 @@ impl IndexScheduler { #[cfg(test)] run_loop_iteration: self.run_loop_iteration.clone(), features: self.features.clone(), + chat_settings: self.chat_settings, } } pub(crate) const fn nb_db() -> u32 { - Versioning::nb_db() + Queue::nb_db() + IndexMapper::nb_db() + features::FeatureData::nb_db() + Versioning::nb_db() + + Queue::nb_db() + + IndexMapper::nb_db() + + features::FeatureData::nb_db() + + 1 // chat-prompts } /// Create an index scheduler and start its run loop. @@ -269,6 +280,7 @@ impl IndexScheduler { let features = features::FeatureData::new(&env, &mut wtxn, options.instance_features)?; let queue = Queue::new(&env, &mut wtxn, &options)?; let index_mapper = IndexMapper::new(&env, &mut wtxn, &options, budget)?; + let chat_settings = env.create_database(&mut wtxn, Some(CHAT_SETTINGS_DB_NAME))?; wtxn.commit()?; // allow unreachable_code to get rids of the warning in the case of a test build. @@ -292,12 +304,17 @@ impl IndexScheduler { #[cfg(test)] run_loop_iteration: Arc::new(RwLock::new(0)), features, + chat_settings, }; this.run(); Ok(this) } + fn read_txn(&self) -> Result> { + self.env.read_txn().map_err(|e| e.into()) + } + /// Return `Ok(())` if the index scheduler is able to access one of its database. pub fn health(&self) -> Result<()> { let rtxn = self.env.read_txn()?; @@ -374,10 +391,6 @@ impl IndexScheduler { } } - pub fn read_txn(&self) -> Result> { - self.env.read_txn().map_err(|e| e.into()) - } - /// Start the run loop for the given index scheduler. /// /// This function will execute in a different thread and must be called @@ -495,7 +508,7 @@ impl IndexScheduler { /// Returns the total number of indexes available for the specified filter. /// And a `Vec` of the index_uid + its stats - pub fn get_paginated_indexes_stats( + pub fn paginated_indexes_stats( &self, filters: &meilisearch_auth::AuthFilter, from: usize, @@ -536,6 +549,24 @@ impl IndexScheduler { ret.map(|ret| (total, ret)) } + /// Returns the total number of chat workspaces available ~~for the specified filter~~. + /// And a `Vec` of the workspace_uids + pub fn paginated_chat_workspace_uids( + &self, + from: usize, + limit: usize, + ) -> Result<(usize, Vec)> { + let rtxn = self.read_txn()?; + let total = self.chat_settings.len(&rtxn)?; + let mut iter = self.chat_settings.iter(&rtxn)?.skip(from); + iter.by_ref() + .take(limit) + .map(|ret| ret.map_err(Error::from)) + .map(|ret| ret.map(|(uid, _)| uid.to_string())) + .collect::, Error>>() + .map(|ret| (total as usize, ret)) + } + /// The returned structure contains: /// 1. The name of the property being observed can be `statuses`, `types`, or `indexes`. /// 2. The name of the specific data related to the property can be `enqueued` for the `statuses`, `settingsUpdate` for the `types`, or the name of the index for the `indexes`, for example. @@ -864,6 +895,31 @@ impl IndexScheduler { .collect(); res.map(EmbeddingConfigs::new) } + + pub fn chat_settings(&self, uid: &str) -> Result> { + let rtxn = self.env.read_txn()?; + self.chat_settings.get(&rtxn, uid).map_err(Into::into) + } + + /// Return true if chat workspace exists. + pub fn chat_workspace_exists(&self, name: &str) -> Result { + let rtxn = self.env.read_txn()?; + Ok(self.chat_settings.remap_data_type::().get(&rtxn, name)?.is_some()) + } + + pub fn put_chat_settings(&self, uid: &str, settings: &ChatCompletionSettings) -> Result<()> { + let mut wtxn = self.env.write_txn()?; + self.chat_settings.put(&mut wtxn, uid, settings)?; + wtxn.commit()?; + Ok(()) + } + + pub fn delete_chat_settings(&self, uid: &str) -> Result { + let mut wtxn = self.env.write_txn()?; + let deleted = self.chat_settings.delete(&mut wtxn, uid)?; + wtxn.commit()?; + Ok(deleted) + } } /// The outcome of calling the [`IndexScheduler::tick`] function. diff --git a/crates/index-scheduler/src/scheduler/mod.rs b/crates/index-scheduler/src/scheduler/mod.rs index f1775a892..0e258e27b 100644 --- a/crates/index-scheduler/src/scheduler/mod.rs +++ b/crates/index-scheduler/src/scheduler/mod.rs @@ -375,9 +375,11 @@ impl IndexScheduler { post_commit_dabases_sizes .get(dbname) .map(|post_size| { - use byte_unit::{Byte, UnitType::Binary}; use std::cmp::Ordering::{Equal, Greater, Less}; + use byte_unit::Byte; + use byte_unit::UnitType::Binary; + let post = Byte::from_u64(*post_size as u64).get_appropriate_unit(Binary); let diff_size = post_size.abs_diff(*pre_size) as u64; let diff = Byte::from_u64(diff_size).get_appropriate_unit(Binary); diff --git a/crates/index-scheduler/src/scheduler/snapshots/test.rs/test_settings_update/after_registering_settings_task.snap b/crates/index-scheduler/src/scheduler/snapshots/test.rs/test_settings_update/after_registering_settings_task.snap index d9d8b0724..c66a6b5b3 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test.rs/test_settings_update/after_registering_settings_task.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test.rs/test_settings_update/after_registering_settings_task.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, status: enqueued, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"default": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(4), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"default": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(4), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, status: enqueued, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"default": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(4), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"default": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(4), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: enqueued [0,] diff --git a/crates/index-scheduler/src/scheduler/snapshots/test.rs/test_settings_update/settings_update_processed.snap b/crates/index-scheduler/src/scheduler/snapshots/test.rs/test_settings_update/settings_update_processed.snap index 35eb3f162..b7faefa8a 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test.rs/test_settings_update/settings_update_processed.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test.rs/test_settings_update/settings_update_processed.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"default": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(4), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"default": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(4), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"default": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(4), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"default": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(4), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: enqueued [] diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/Intel to kefir succeeds.snap b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/Intel to kefir succeeds.snap index b90d5944a..c8955e2b6 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/Intel to kefir succeeds.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/Intel to kefir succeeds.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_embedders.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, batch_uid: 1, status: succeeded, details: { received_documents: 1, indexed_documents: Some(1) }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: UpdateDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 1, allow_index_creation: true }} 2 {uid: 2, batch_uid: 2, status: succeeded, details: { received_documents: 1, indexed_documents: Some(1) }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: None, method: UpdateDocuments, content_file: 00000000-0000-0000-0000-000000000001, documents_count: 1, allow_index_creation: true }} ---------------------------------------------------------------------- diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/Intel to kefir.snap b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/Intel to kefir.snap index 58bf78290..23e43860f 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/Intel to kefir.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/Intel to kefir.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_embedders.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, batch_uid: 1, status: succeeded, details: { received_documents: 1, indexed_documents: Some(1) }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: UpdateDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 1, allow_index_creation: true }} 2 {uid: 2, status: enqueued, details: { received_documents: 1, indexed_documents: None }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: None, method: UpdateDocuments, content_file: 00000000-0000-0000-0000-000000000001, documents_count: 1, allow_index_creation: true }} ---------------------------------------------------------------------- diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/adding Intel succeeds.snap b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/adding Intel succeeds.snap index 90ac17702..732527fa8 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/adding Intel succeeds.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/adding Intel succeeds.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_embedders.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, batch_uid: 1, status: succeeded, details: { received_documents: 1, indexed_documents: Some(1) }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: UpdateDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 1, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/after adding Intel.snap b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/after adding Intel.snap index 10f87d389..5e01ffcdf 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/after adding Intel.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/after adding Intel.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_embedders.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, status: enqueued, details: { received_documents: 1, indexed_documents: None }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: UpdateDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 1, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/after_registering_settings_task_vectors.snap b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/after_registering_settings_task_vectors.snap index 35bd9dee9..1172d1118 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/after_registering_settings_task_vectors.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/after_registering_settings_task_vectors.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_embedders.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, status: enqueued, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, status: enqueued, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: enqueued [0,] diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/settings_update_processed_vectors.snap b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/settings_update_processed_vectors.snap index ec8f387f0..3653eeb9a 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/settings_update_processed_vectors.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_embedders.rs/import_vectors/settings_update_processed_vectors.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_embedders.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: NotSet, sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: Set({"A_fakerest": Set(EmbeddingSettings { source: Set(Rest), model: NotSet, revision: NotSet, pooling: NotSet, api_key: Set("My super secret"), dimensions: Set(384), binary_quantized: NotSet, document_template: NotSet, document_template_max_bytes: NotSet, url: Set("http://localhost:7777"), request: Set(String("{{text}}")), response: Set(String("{{embedding}}")), headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet }), "B_small_hf": Set(EmbeddingSettings { source: Set(HuggingFace), model: Set("sentence-transformers/all-MiniLM-L6-v2"), revision: Set("e4ce9877abf3edfe10b0d82785e83bdcb973e22e"), pooling: NotSet, api_key: NotSet, dimensions: NotSet, binary_quantized: NotSet, document_template: Set("{{doc.doggo}} the {{doc.breed}} best doggo"), document_template_max_bytes: NotSet, url: NotSet, request: NotSet, response: NotSet, headers: NotSet, search_embedder: NotSet, indexing_embedder: NotSet, distribution: NotSet })}), search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: enqueued [] diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_adding_the_documents.snap b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_adding_the_documents.snap index c5696578a..96d93de51 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_adding_the_documents.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_adding_the_documents.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_failure.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, batch_uid: 1, status: succeeded, details: { received_documents: 3, indexed_documents: Some(3) }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: ReplaceDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 3, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_adding_the_settings.snap b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_adding_the_settings.snap index edabbfa3c..76a77e5c0 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_adding_the_settings.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_adding_the_settings.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_failure.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, status: enqueued, details: { received_documents: 3, indexed_documents: None }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: ReplaceDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 3, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_removing_the_documents.snap b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_removing_the_documents.snap index aa86c61be..422bed51f 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_removing_the_documents.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/after_removing_the_documents.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_failure.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, batch_uid: 1, status: succeeded, details: { received_documents: 3, indexed_documents: Some(3) }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: ReplaceDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 3, allow_index_creation: true }} 2 {uid: 2, batch_uid: 2, status: succeeded, details: { received_document_ids: 1, deleted_documents: Some(1) }, kind: DocumentDeletion { index_uid: "doggos", documents_ids: ["1"] }} 3 {uid: 3, batch_uid: 2, status: failed, error: ResponseError { code: 200, message: "Index `doggos`: Invalid type for filter subexpression: expected: String, Array, found: true.", error_code: "invalid_document_filter", error_type: "invalid_request", error_link: "https://docs.meilisearch.com/errors#invalid_document_filter" }, details: { original_filter: true, deleted_documents: Some(0) }, kind: DocumentDeletionByFilter { index_uid: "doggos", filter_expr: Bool(true) }} diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/registered_the_document_deletions.snap b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/registered_the_document_deletions.snap index 410c9c68e..d8996f82c 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/registered_the_document_deletions.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/registered_the_document_deletions.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_failure.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, batch_uid: 0, status: succeeded, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, batch_uid: 1, status: succeeded, details: { received_documents: 3, indexed_documents: Some(3) }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: ReplaceDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 3, allow_index_creation: true }} 2 {uid: 2, status: enqueued, details: { received_document_ids: 1, deleted_documents: None }, kind: DocumentDeletion { index_uid: "doggos", documents_ids: ["1"] }} 3 {uid: 3, status: enqueued, details: { original_filter: true, deleted_documents: None }, kind: DocumentDeletionByFilter { index_uid: "doggos", filter_expr: Bool(true) }} diff --git a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/registered_the_setting_and_document_addition.snap b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/registered_the_setting_and_document_addition.snap index 0ba3ef598..e7b06eb31 100644 --- a/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/registered_the_setting_and_document_addition.snap +++ b/crates/index-scheduler/src/scheduler/snapshots/test_failure.rs/fail_in_process_batch_for_document_deletion/registered_the_setting_and_document_addition.snap @@ -6,7 +6,7 @@ source: crates/index-scheduler/src/scheduler/test_failure.rs [] ---------------------------------------------------------------------- ### All Tasks: -0 {uid: 0, status: enqueued, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} +0 {uid: 0, status: enqueued, details: { settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData } }, kind: SettingsUpdate { index_uid: "doggos", new_settings: Settings { displayed_attributes: WildcardSetting(NotSet), searchable_attributes: WildcardSetting(NotSet), filterable_attributes: Set([Field("catto")]), sortable_attributes: NotSet, ranking_rules: NotSet, stop_words: NotSet, non_separator_tokens: NotSet, separator_tokens: NotSet, dictionary: NotSet, synonyms: NotSet, distinct_attribute: NotSet, proximity_precision: NotSet, typo_tolerance: NotSet, faceting: NotSet, pagination: NotSet, embedders: NotSet, search_cutoff_ms: NotSet, localized_attributes: NotSet, facet_search: NotSet, prefix_search: NotSet, chat: NotSet, _kind: PhantomData }, is_deletion: false, allow_index_creation: true }} 1 {uid: 1, status: enqueued, details: { received_documents: 3, indexed_documents: None }, kind: DocumentAdditionOrUpdate { index_uid: "doggos", primary_key: Some("id"), method: ReplaceDocuments, content_file: 00000000-0000-0000-0000-000000000000, documents_count: 3, allow_index_creation: true }} ---------------------------------------------------------------------- ### Status: diff --git a/crates/index-scheduler/src/scheduler/test.rs b/crates/index-scheduler/src/scheduler/test.rs index f13af9f87..06bc14051 100644 --- a/crates/index-scheduler/src/scheduler/test.rs +++ b/crates/index-scheduler/src/scheduler/test.rs @@ -894,7 +894,7 @@ fn create_and_list_index() { let err = index_scheduler.index("kefir").map(|_| ()).unwrap_err(); snapshot!(err, @"Index `kefir` not found."); - let empty = index_scheduler.get_paginated_indexes_stats(&AuthFilter::default(), 0, 20).unwrap(); + let empty = index_scheduler.paginated_indexes_stats(&AuthFilter::default(), 0, 20).unwrap(); snapshot!(format!("{empty:?}"), @"(0, [])"); // After advancing just once the index should've been created, the wtxn has been released and commited @@ -902,7 +902,7 @@ fn create_and_list_index() { handle.advance_till([InsideProcessBatch]); index_scheduler.index("kefir").unwrap(); - let list = index_scheduler.get_paginated_indexes_stats(&AuthFilter::default(), 0, 20).unwrap(); + let list = index_scheduler.paginated_indexes_stats(&AuthFilter::default(), 0, 20).unwrap(); snapshot!(json_string!(list, { "[1][0][1].created_at" => "[date]", "[1][0][1].updated_at" => "[date]", "[1][0][1].used_database_size" => "[bytes]", "[1][0][1].database_size" => "[bytes]" }), @r###" [ 1, diff --git a/crates/index-scheduler/src/scheduler/test_failure.rs b/crates/index-scheduler/src/scheduler/test_failure.rs index 191910d38..ad7f22bd8 100644 --- a/crates/index-scheduler/src/scheduler/test_failure.rs +++ b/crates/index-scheduler/src/scheduler/test_failure.rs @@ -2,10 +2,9 @@ use std::time::Instant; use big_s::S; use meili_snap::snapshot; -use meilisearch_types::milli::obkv_to_json; use meilisearch_types::milli::update::IndexDocumentsMethod::*; use meilisearch_types::milli::update::Setting; -use meilisearch_types::milli::FilterableAttributesRule; +use meilisearch_types::milli::{obkv_to_json, FilterableAttributesRule}; use meilisearch_types::tasks::{Kind, KindWithContent}; use crate::insta_snapshot::snapshot_index_scheduler; diff --git a/crates/meilisearch-auth/src/lib.rs b/crates/meilisearch-auth/src/lib.rs index 01c986d9f..27d163192 100644 --- a/crates/meilisearch-auth/src/lib.rs +++ b/crates/meilisearch-auth/src/lib.rs @@ -165,6 +165,7 @@ impl AuthController { } } +#[derive(Debug)] pub struct AuthFilter { search_rules: Option, key_authorized_indexes: SearchRules, @@ -349,6 +350,7 @@ pub struct IndexSearchRules { } fn generate_default_keys(store: &HeedAuthStore) -> Result<()> { + store.put_api_key(Key::default_chat())?; store.put_api_key(Key::default_admin())?; store.put_api_key(Key::default_search())?; diff --git a/crates/meilisearch-auth/src/store.rs b/crates/meilisearch-auth/src/store.rs index 2fd380194..bae27afe4 100644 --- a/crates/meilisearch-auth/src/store.rs +++ b/crates/meilisearch-auth/src/store.rs @@ -125,6 +125,12 @@ impl HeedAuthStore { Action::MetricsAll => { actions.insert(Action::MetricsGet); } + Action::ChatsAll => { + actions.extend([Action::ChatsGet, Action::ChatsDelete]); + } + Action::ChatsSettingsAll => { + actions.extend([Action::ChatsSettingsGet, Action::ChatsSettingsUpdate]); + } other => { actions.insert(*other); } diff --git a/crates/meilisearch-types/src/deserr/mod.rs b/crates/meilisearch-types/src/deserr/mod.rs index f5ad18d5c..f1470c201 100644 --- a/crates/meilisearch-types/src/deserr/mod.rs +++ b/crates/meilisearch-types/src/deserr/mod.rs @@ -4,9 +4,12 @@ use std::marker::PhantomData; use std::ops::ControlFlow; use deserr::errors::{JsonError, QueryParamError}; -use deserr::{take_cf_content, DeserializeError, IntoValue, MergeWithError, ValuePointerRef}; +use deserr::{ + take_cf_content, DeserializeError, Deserr, IntoValue, MergeWithError, ValuePointerRef, +}; +use milli::update::ChatSettings; -use crate::error::deserr_codes::*; +use crate::error::deserr_codes::{self, *}; use crate::error::{ Code, DeserrParseBoolError, DeserrParseIntError, ErrorCode, InvalidTaskDateError, ParseOffsetDateTimeError, @@ -33,6 +36,7 @@ pub struct DeserrError { pub code: Code, _phantom: PhantomData<(Format, C)>, } + impl DeserrError { pub fn new(msg: String, code: Code) -> Self { Self { msg, code, _phantom: PhantomData } @@ -117,6 +121,16 @@ impl DeserializeError for DeserrQueryParamError { } } +impl Deserr> for ChatSettings { + fn deserialize_from_value( + value: deserr::Value, + location: ValuePointerRef, + ) -> Result> { + Deserr::::deserialize_from_value(value, location) + .map_err(|e| DeserrError::new(e.to_string(), InvalidSettingsIndexChat.error_code())) + } +} + pub fn immutable_field_error(field: &str, accepted: &[&str], code: Code) -> DeserrJsonError { let msg = format!( "Immutable field `{field}`: expected one of {}", diff --git a/crates/meilisearch-types/src/error.rs b/crates/meilisearch-types/src/error.rs index 6c547d51e..d2500b7e1 100644 --- a/crates/meilisearch-types/src/error.rs +++ b/crates/meilisearch-types/src/error.rs @@ -194,200 +194,220 @@ macro_rules! make_error_codes { // An exhaustive list of all the error codes used by meilisearch. make_error_codes! { -ApiKeyAlreadyExists , InvalidRequest , CONFLICT ; -ApiKeyNotFound , InvalidRequest , NOT_FOUND ; -BadParameter , InvalidRequest , BAD_REQUEST; -BadRequest , InvalidRequest , BAD_REQUEST; -DatabaseSizeLimitReached , Internal , INTERNAL_SERVER_ERROR; -DocumentNotFound , InvalidRequest , NOT_FOUND; -DumpAlreadyProcessing , InvalidRequest , CONFLICT; -DumpNotFound , InvalidRequest , NOT_FOUND; -DumpProcessFailed , Internal , INTERNAL_SERVER_ERROR; -DuplicateIndexFound , InvalidRequest , BAD_REQUEST; -ImmutableApiKeyActions , InvalidRequest , BAD_REQUEST; -ImmutableApiKeyCreatedAt , InvalidRequest , BAD_REQUEST; -ImmutableApiKeyExpiresAt , InvalidRequest , BAD_REQUEST; -ImmutableApiKeyIndexes , InvalidRequest , BAD_REQUEST; -ImmutableApiKeyKey , InvalidRequest , BAD_REQUEST; -ImmutableApiKeyUid , InvalidRequest , BAD_REQUEST; -ImmutableApiKeyUpdatedAt , InvalidRequest , BAD_REQUEST; -ImmutableIndexCreatedAt , InvalidRequest , BAD_REQUEST; -ImmutableIndexUid , InvalidRequest , BAD_REQUEST; -ImmutableIndexUpdatedAt , InvalidRequest , BAD_REQUEST; -IndexAlreadyExists , InvalidRequest , CONFLICT ; -IndexCreationFailed , Internal , INTERNAL_SERVER_ERROR; -IndexNotFound , InvalidRequest , NOT_FOUND; -IndexPrimaryKeyAlreadyExists , InvalidRequest , BAD_REQUEST ; -IndexPrimaryKeyMultipleCandidatesFound, InvalidRequest , BAD_REQUEST; -IndexPrimaryKeyNoCandidateFound , InvalidRequest , BAD_REQUEST ; -Internal , Internal , INTERNAL_SERVER_ERROR ; -InvalidApiKey , Auth , FORBIDDEN ; -InvalidApiKeyActions , InvalidRequest , BAD_REQUEST ; -InvalidApiKeyDescription , InvalidRequest , BAD_REQUEST ; -InvalidApiKeyExpiresAt , InvalidRequest , BAD_REQUEST ; -InvalidApiKeyIndexes , InvalidRequest , BAD_REQUEST ; -InvalidApiKeyLimit , InvalidRequest , BAD_REQUEST ; -InvalidApiKeyName , InvalidRequest , BAD_REQUEST ; -InvalidApiKeyOffset , InvalidRequest , BAD_REQUEST ; -InvalidApiKeyUid , InvalidRequest , BAD_REQUEST ; -InvalidContentType , InvalidRequest , UNSUPPORTED_MEDIA_TYPE ; -InvalidDocumentCsvDelimiter , InvalidRequest , BAD_REQUEST ; -InvalidDocumentFields , InvalidRequest , BAD_REQUEST ; -InvalidDocumentRetrieveVectors , InvalidRequest , BAD_REQUEST ; -MissingDocumentFilter , InvalidRequest , BAD_REQUEST ; -MissingDocumentEditionFunction , InvalidRequest , BAD_REQUEST ; -InvalidDocumentFilter , InvalidRequest , BAD_REQUEST ; -InvalidDocumentGeoField , InvalidRequest , BAD_REQUEST ; -InvalidVectorDimensions , InvalidRequest , BAD_REQUEST ; -InvalidVectorsType , InvalidRequest , BAD_REQUEST ; -InvalidDocumentId , InvalidRequest , BAD_REQUEST ; -InvalidDocumentIds , InvalidRequest , BAD_REQUEST ; -InvalidDocumentLimit , InvalidRequest , BAD_REQUEST ; -InvalidDocumentOffset , InvalidRequest , BAD_REQUEST ; -InvalidSearchEmbedder , InvalidRequest , BAD_REQUEST ; -InvalidSimilarEmbedder , InvalidRequest , BAD_REQUEST ; -InvalidSearchHybridQuery , InvalidRequest , BAD_REQUEST ; -InvalidIndexLimit , InvalidRequest , BAD_REQUEST ; -InvalidIndexOffset , InvalidRequest , BAD_REQUEST ; -InvalidIndexPrimaryKey , InvalidRequest , BAD_REQUEST ; -InvalidIndexUid , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchFacets , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchFacetsByIndex , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchFacetOrder , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchFederated , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchFederationOptions , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchMaxValuesPerFacet , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchMergeFacets , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchQueryFacets , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchQueryPagination , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchQueryRankingRules , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchQueryPosition , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchRemote , InvalidRequest , BAD_REQUEST ; -InvalidMultiSearchWeight , InvalidRequest , BAD_REQUEST ; -InvalidNetworkRemotes , InvalidRequest , BAD_REQUEST ; -InvalidNetworkSelf , InvalidRequest , BAD_REQUEST ; -InvalidNetworkSearchApiKey , InvalidRequest , BAD_REQUEST ; -InvalidNetworkUrl , InvalidRequest , BAD_REQUEST ; -InvalidSearchAttributesToSearchOn , InvalidRequest , BAD_REQUEST ; -InvalidSearchAttributesToCrop , InvalidRequest , BAD_REQUEST ; -InvalidSearchAttributesToHighlight , InvalidRequest , BAD_REQUEST ; -InvalidSimilarAttributesToRetrieve , InvalidRequest , BAD_REQUEST ; -InvalidSimilarRetrieveVectors , InvalidRequest , BAD_REQUEST ; -InvalidSearchAttributesToRetrieve , InvalidRequest , BAD_REQUEST ; -InvalidSearchRankingScoreThreshold , InvalidRequest , BAD_REQUEST ; -InvalidSimilarRankingScoreThreshold , InvalidRequest , BAD_REQUEST ; -InvalidSearchRetrieveVectors , InvalidRequest , BAD_REQUEST ; -InvalidSearchCropLength , InvalidRequest , BAD_REQUEST ; -InvalidSearchCropMarker , InvalidRequest , BAD_REQUEST ; -InvalidSearchFacets , InvalidRequest , BAD_REQUEST ; -InvalidSearchSemanticRatio , InvalidRequest , BAD_REQUEST ; -InvalidSearchLocales , InvalidRequest , BAD_REQUEST ; -InvalidFacetSearchExhaustiveFacetCount, InvalidRequest , BAD_REQUEST ; -InvalidFacetSearchFacetName , InvalidRequest , BAD_REQUEST ; -InvalidSimilarId , InvalidRequest , BAD_REQUEST ; -InvalidSearchFilter , InvalidRequest , BAD_REQUEST ; -InvalidSimilarFilter , InvalidRequest , BAD_REQUEST ; -InvalidSearchHighlightPostTag , InvalidRequest , BAD_REQUEST ; -InvalidSearchHighlightPreTag , InvalidRequest , BAD_REQUEST ; -InvalidSearchHitsPerPage , InvalidRequest , BAD_REQUEST ; -InvalidSimilarLimit , InvalidRequest , BAD_REQUEST ; -InvalidSearchLimit , InvalidRequest , BAD_REQUEST ; -InvalidSearchMatchingStrategy , InvalidRequest , BAD_REQUEST ; -InvalidSimilarOffset , InvalidRequest , BAD_REQUEST ; -InvalidSearchOffset , InvalidRequest , BAD_REQUEST ; -InvalidSearchPage , InvalidRequest , BAD_REQUEST ; -InvalidSearchQ , InvalidRequest , BAD_REQUEST ; -InvalidFacetSearchQuery , InvalidRequest , BAD_REQUEST ; -InvalidFacetSearchName , InvalidRequest , BAD_REQUEST ; -FacetSearchDisabled , InvalidRequest , BAD_REQUEST ; -InvalidSearchVector , InvalidRequest , BAD_REQUEST ; -InvalidSearchShowMatchesPosition , InvalidRequest , BAD_REQUEST ; -InvalidSearchShowRankingScore , InvalidRequest , BAD_REQUEST ; -InvalidSimilarShowRankingScore , InvalidRequest , BAD_REQUEST ; -InvalidSearchShowRankingScoreDetails , InvalidRequest , BAD_REQUEST ; -InvalidSimilarShowRankingScoreDetails , InvalidRequest , BAD_REQUEST ; -InvalidSearchSort , InvalidRequest , BAD_REQUEST ; -InvalidSearchDistinct , InvalidRequest , BAD_REQUEST ; -InvalidSettingsDisplayedAttributes , InvalidRequest , BAD_REQUEST ; -InvalidSettingsDistinctAttribute , InvalidRequest , BAD_REQUEST ; -InvalidSettingsProximityPrecision , InvalidRequest , BAD_REQUEST ; -InvalidSettingsFacetSearch , InvalidRequest , BAD_REQUEST ; -InvalidSettingsPrefixSearch , InvalidRequest , BAD_REQUEST ; -InvalidSettingsFaceting , InvalidRequest , BAD_REQUEST ; -InvalidSettingsFilterableAttributes , InvalidRequest , BAD_REQUEST ; -InvalidSettingsPagination , InvalidRequest , BAD_REQUEST ; -InvalidSettingsSearchCutoffMs , InvalidRequest , BAD_REQUEST ; -InvalidSettingsEmbedders , InvalidRequest , BAD_REQUEST ; -InvalidSettingsRankingRules , InvalidRequest , BAD_REQUEST ; -InvalidSettingsSearchableAttributes , InvalidRequest , BAD_REQUEST ; -InvalidSettingsSortableAttributes , InvalidRequest , BAD_REQUEST ; -InvalidSettingsStopWords , InvalidRequest , BAD_REQUEST ; -InvalidSettingsNonSeparatorTokens , InvalidRequest , BAD_REQUEST ; -InvalidSettingsSeparatorTokens , InvalidRequest , BAD_REQUEST ; -InvalidSettingsDictionary , InvalidRequest , BAD_REQUEST ; -InvalidSettingsSynonyms , InvalidRequest , BAD_REQUEST ; -InvalidSettingsTypoTolerance , InvalidRequest , BAD_REQUEST ; -InvalidSettingsLocalizedAttributes , InvalidRequest , BAD_REQUEST ; -InvalidState , Internal , INTERNAL_SERVER_ERROR ; -InvalidStoreFile , Internal , INTERNAL_SERVER_ERROR ; -InvalidSwapDuplicateIndexFound , InvalidRequest , BAD_REQUEST ; -InvalidSwapIndexes , InvalidRequest , BAD_REQUEST ; -InvalidTaskAfterEnqueuedAt , InvalidRequest , BAD_REQUEST ; -InvalidTaskAfterFinishedAt , InvalidRequest , BAD_REQUEST ; -InvalidTaskAfterStartedAt , InvalidRequest , BAD_REQUEST ; -InvalidTaskBeforeEnqueuedAt , InvalidRequest , BAD_REQUEST ; -InvalidTaskBeforeFinishedAt , InvalidRequest , BAD_REQUEST ; -InvalidTaskBeforeStartedAt , InvalidRequest , BAD_REQUEST ; -InvalidTaskCanceledBy , InvalidRequest , BAD_REQUEST ; -InvalidTaskFrom , InvalidRequest , BAD_REQUEST ; -InvalidTaskLimit , InvalidRequest , BAD_REQUEST ; -InvalidTaskReverse , InvalidRequest , BAD_REQUEST ; -InvalidTaskStatuses , InvalidRequest , BAD_REQUEST ; -InvalidTaskTypes , InvalidRequest , BAD_REQUEST ; -InvalidTaskUids , InvalidRequest , BAD_REQUEST ; -InvalidBatchUids , InvalidRequest , BAD_REQUEST ; -IoError , System , UNPROCESSABLE_ENTITY; -FeatureNotEnabled , InvalidRequest , BAD_REQUEST ; -MalformedPayload , InvalidRequest , BAD_REQUEST ; -MaxFieldsLimitExceeded , InvalidRequest , BAD_REQUEST ; -MissingApiKeyActions , InvalidRequest , BAD_REQUEST ; -MissingApiKeyExpiresAt , InvalidRequest , BAD_REQUEST ; -MissingApiKeyIndexes , InvalidRequest , BAD_REQUEST ; -MissingAuthorizationHeader , Auth , UNAUTHORIZED ; -MissingContentType , InvalidRequest , UNSUPPORTED_MEDIA_TYPE ; -MissingDocumentId , InvalidRequest , BAD_REQUEST ; -MissingFacetSearchFacetName , InvalidRequest , BAD_REQUEST ; -MissingIndexUid , InvalidRequest , BAD_REQUEST ; -MissingMasterKey , Auth , UNAUTHORIZED ; -MissingNetworkUrl , InvalidRequest , BAD_REQUEST ; -MissingPayload , InvalidRequest , BAD_REQUEST ; -MissingSearchHybrid , InvalidRequest , BAD_REQUEST ; -MissingSwapIndexes , InvalidRequest , BAD_REQUEST ; -MissingTaskFilters , InvalidRequest , BAD_REQUEST ; -NoSpaceLeftOnDevice , System , UNPROCESSABLE_ENTITY; -PayloadTooLarge , InvalidRequest , PAYLOAD_TOO_LARGE ; -RemoteBadResponse , System , BAD_GATEWAY ; -RemoteBadRequest , InvalidRequest , BAD_REQUEST ; -RemoteCouldNotSendRequest , System , BAD_GATEWAY ; -RemoteInvalidApiKey , Auth , FORBIDDEN ; -RemoteRemoteError , System , BAD_GATEWAY ; -RemoteTimeout , System , BAD_GATEWAY ; -TooManySearchRequests , System , SERVICE_UNAVAILABLE ; -TaskNotFound , InvalidRequest , NOT_FOUND ; -TaskFileNotFound , InvalidRequest , NOT_FOUND ; -BatchNotFound , InvalidRequest , NOT_FOUND ; -TooManyOpenFiles , System , UNPROCESSABLE_ENTITY ; -TooManyVectors , InvalidRequest , BAD_REQUEST ; -UnretrievableDocument , Internal , BAD_REQUEST ; -UnretrievableErrorCode , InvalidRequest , BAD_REQUEST ; -UnsupportedMediaType , InvalidRequest , UNSUPPORTED_MEDIA_TYPE ; +ApiKeyAlreadyExists , InvalidRequest , CONFLICT ; +ApiKeyNotFound , InvalidRequest , NOT_FOUND ; +BadParameter , InvalidRequest , BAD_REQUEST; +BadRequest , InvalidRequest , BAD_REQUEST; +DatabaseSizeLimitReached , Internal , INTERNAL_SERVER_ERROR; +DocumentNotFound , InvalidRequest , NOT_FOUND; +DumpAlreadyProcessing , InvalidRequest , CONFLICT; +DumpNotFound , InvalidRequest , NOT_FOUND; +DumpProcessFailed , Internal , INTERNAL_SERVER_ERROR; +DuplicateIndexFound , InvalidRequest , BAD_REQUEST; +ImmutableApiKeyActions , InvalidRequest , BAD_REQUEST; +ImmutableApiKeyCreatedAt , InvalidRequest , BAD_REQUEST; +ImmutableApiKeyExpiresAt , InvalidRequest , BAD_REQUEST; +ImmutableApiKeyIndexes , InvalidRequest , BAD_REQUEST; +ImmutableApiKeyKey , InvalidRequest , BAD_REQUEST; +ImmutableApiKeyUid , InvalidRequest , BAD_REQUEST; +ImmutableApiKeyUpdatedAt , InvalidRequest , BAD_REQUEST; +ImmutableIndexCreatedAt , InvalidRequest , BAD_REQUEST; +ImmutableIndexUid , InvalidRequest , BAD_REQUEST; +ImmutableIndexUpdatedAt , InvalidRequest , BAD_REQUEST; +IndexAlreadyExists , InvalidRequest , CONFLICT ; +IndexCreationFailed , Internal , INTERNAL_SERVER_ERROR; +IndexNotFound , InvalidRequest , NOT_FOUND; +IndexPrimaryKeyAlreadyExists , InvalidRequest , BAD_REQUEST ; +IndexPrimaryKeyMultipleCandidatesFound , InvalidRequest , BAD_REQUEST; +IndexPrimaryKeyNoCandidateFound , InvalidRequest , BAD_REQUEST ; +Internal , Internal , INTERNAL_SERVER_ERROR ; +InvalidApiKey , Auth , FORBIDDEN ; +InvalidApiKeyActions , InvalidRequest , BAD_REQUEST ; +InvalidApiKeyDescription , InvalidRequest , BAD_REQUEST ; +InvalidApiKeyExpiresAt , InvalidRequest , BAD_REQUEST ; +InvalidApiKeyIndexes , InvalidRequest , BAD_REQUEST ; +InvalidApiKeyLimit , InvalidRequest , BAD_REQUEST ; +InvalidApiKeyName , InvalidRequest , BAD_REQUEST ; +InvalidApiKeyOffset , InvalidRequest , BAD_REQUEST ; +InvalidApiKeyUid , InvalidRequest , BAD_REQUEST ; +InvalidContentType , InvalidRequest , UNSUPPORTED_MEDIA_TYPE ; +InvalidDocumentCsvDelimiter , InvalidRequest , BAD_REQUEST ; +InvalidDocumentFields , InvalidRequest , BAD_REQUEST ; +InvalidDocumentRetrieveVectors , InvalidRequest , BAD_REQUEST ; +MissingDocumentFilter , InvalidRequest , BAD_REQUEST ; +MissingDocumentEditionFunction , InvalidRequest , BAD_REQUEST ; +InvalidDocumentFilter , InvalidRequest , BAD_REQUEST ; +InvalidDocumentGeoField , InvalidRequest , BAD_REQUEST ; +InvalidVectorDimensions , InvalidRequest , BAD_REQUEST ; +InvalidVectorsType , InvalidRequest , BAD_REQUEST ; +InvalidDocumentId , InvalidRequest , BAD_REQUEST ; +InvalidDocumentIds , InvalidRequest , BAD_REQUEST ; +InvalidDocumentLimit , InvalidRequest , BAD_REQUEST ; +InvalidDocumentOffset , InvalidRequest , BAD_REQUEST ; +InvalidSearchEmbedder , InvalidRequest , BAD_REQUEST ; +InvalidSimilarEmbedder , InvalidRequest , BAD_REQUEST ; +InvalidSearchHybridQuery , InvalidRequest , BAD_REQUEST ; +InvalidIndexLimit , InvalidRequest , BAD_REQUEST ; +InvalidIndexOffset , InvalidRequest , BAD_REQUEST ; +InvalidIndexPrimaryKey , InvalidRequest , BAD_REQUEST ; +InvalidIndexUid , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchFacets , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchFacetsByIndex , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchFacetOrder , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchFederated , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchFederationOptions , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchMaxValuesPerFacet , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchMergeFacets , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchQueryFacets , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchQueryPagination , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchQueryRankingRules , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchQueryPosition , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchRemote , InvalidRequest , BAD_REQUEST ; +InvalidMultiSearchWeight , InvalidRequest , BAD_REQUEST ; +InvalidNetworkRemotes , InvalidRequest , BAD_REQUEST ; +InvalidNetworkSelf , InvalidRequest , BAD_REQUEST ; +InvalidNetworkSearchApiKey , InvalidRequest , BAD_REQUEST ; +InvalidNetworkUrl , InvalidRequest , BAD_REQUEST ; +InvalidSearchAttributesToSearchOn , InvalidRequest , BAD_REQUEST ; +InvalidSearchAttributesToCrop , InvalidRequest , BAD_REQUEST ; +InvalidSearchAttributesToHighlight , InvalidRequest , BAD_REQUEST ; +InvalidSimilarAttributesToRetrieve , InvalidRequest , BAD_REQUEST ; +InvalidSimilarRetrieveVectors , InvalidRequest , BAD_REQUEST ; +InvalidSearchAttributesToRetrieve , InvalidRequest , BAD_REQUEST ; +InvalidSearchRankingScoreThreshold , InvalidRequest , BAD_REQUEST ; +InvalidSimilarRankingScoreThreshold , InvalidRequest , BAD_REQUEST ; +InvalidSearchRetrieveVectors , InvalidRequest , BAD_REQUEST ; +InvalidSearchCropLength , InvalidRequest , BAD_REQUEST ; +InvalidSearchCropMarker , InvalidRequest , BAD_REQUEST ; +InvalidSearchFacets , InvalidRequest , BAD_REQUEST ; +InvalidSearchSemanticRatio , InvalidRequest , BAD_REQUEST ; +InvalidSearchLocales , InvalidRequest , BAD_REQUEST ; +InvalidFacetSearchExhaustiveFacetCount , InvalidRequest , BAD_REQUEST ; +InvalidFacetSearchFacetName , InvalidRequest , BAD_REQUEST ; +InvalidSimilarId , InvalidRequest , BAD_REQUEST ; +InvalidSearchFilter , InvalidRequest , BAD_REQUEST ; +InvalidSimilarFilter , InvalidRequest , BAD_REQUEST ; +InvalidSearchHighlightPostTag , InvalidRequest , BAD_REQUEST ; +InvalidSearchHighlightPreTag , InvalidRequest , BAD_REQUEST ; +InvalidSearchHitsPerPage , InvalidRequest , BAD_REQUEST ; +InvalidSimilarLimit , InvalidRequest , BAD_REQUEST ; +InvalidSearchLimit , InvalidRequest , BAD_REQUEST ; +InvalidSearchMatchingStrategy , InvalidRequest , BAD_REQUEST ; +InvalidSimilarOffset , InvalidRequest , BAD_REQUEST ; +InvalidSearchOffset , InvalidRequest , BAD_REQUEST ; +InvalidSearchPage , InvalidRequest , BAD_REQUEST ; +InvalidSearchQ , InvalidRequest , BAD_REQUEST ; +InvalidFacetSearchQuery , InvalidRequest , BAD_REQUEST ; +InvalidFacetSearchName , InvalidRequest , BAD_REQUEST ; +FacetSearchDisabled , InvalidRequest , BAD_REQUEST ; +InvalidSearchVector , InvalidRequest , BAD_REQUEST ; +InvalidSearchShowMatchesPosition , InvalidRequest , BAD_REQUEST ; +InvalidSearchShowRankingScore , InvalidRequest , BAD_REQUEST ; +InvalidSimilarShowRankingScore , InvalidRequest , BAD_REQUEST ; +InvalidSearchShowRankingScoreDetails , InvalidRequest , BAD_REQUEST ; +InvalidSimilarShowRankingScoreDetails , InvalidRequest , BAD_REQUEST ; +InvalidSearchSort , InvalidRequest , BAD_REQUEST ; +InvalidSearchDistinct , InvalidRequest , BAD_REQUEST ; +InvalidSettingsDisplayedAttributes , InvalidRequest , BAD_REQUEST ; +InvalidSettingsDistinctAttribute , InvalidRequest , BAD_REQUEST ; +InvalidSettingsProximityPrecision , InvalidRequest , BAD_REQUEST ; +InvalidSettingsFacetSearch , InvalidRequest , BAD_REQUEST ; +InvalidSettingsPrefixSearch , InvalidRequest , BAD_REQUEST ; +InvalidSettingsFaceting , InvalidRequest , BAD_REQUEST ; +InvalidSettingsFilterableAttributes , InvalidRequest , BAD_REQUEST ; +InvalidSettingsPagination , InvalidRequest , BAD_REQUEST ; +InvalidSettingsSearchCutoffMs , InvalidRequest , BAD_REQUEST ; +InvalidSettingsEmbedders , InvalidRequest , BAD_REQUEST ; +InvalidSettingsRankingRules , InvalidRequest , BAD_REQUEST ; +InvalidSettingsSearchableAttributes , InvalidRequest , BAD_REQUEST ; +InvalidSettingsSortableAttributes , InvalidRequest , BAD_REQUEST ; +InvalidSettingsStopWords , InvalidRequest , BAD_REQUEST ; +InvalidSettingsNonSeparatorTokens , InvalidRequest , BAD_REQUEST ; +InvalidSettingsSeparatorTokens , InvalidRequest , BAD_REQUEST ; +InvalidSettingsDictionary , InvalidRequest , BAD_REQUEST ; +InvalidSettingsSynonyms , InvalidRequest , BAD_REQUEST ; +InvalidSettingsTypoTolerance , InvalidRequest , BAD_REQUEST ; +InvalidSettingsLocalizedAttributes , InvalidRequest , BAD_REQUEST ; +InvalidState , Internal , INTERNAL_SERVER_ERROR ; +InvalidStoreFile , Internal , INTERNAL_SERVER_ERROR ; +InvalidSwapDuplicateIndexFound , InvalidRequest , BAD_REQUEST ; +InvalidSwapIndexes , InvalidRequest , BAD_REQUEST ; +InvalidTaskAfterEnqueuedAt , InvalidRequest , BAD_REQUEST ; +InvalidTaskAfterFinishedAt , InvalidRequest , BAD_REQUEST ; +InvalidTaskAfterStartedAt , InvalidRequest , BAD_REQUEST ; +InvalidTaskBeforeEnqueuedAt , InvalidRequest , BAD_REQUEST ; +InvalidTaskBeforeFinishedAt , InvalidRequest , BAD_REQUEST ; +InvalidTaskBeforeStartedAt , InvalidRequest , BAD_REQUEST ; +InvalidTaskCanceledBy , InvalidRequest , BAD_REQUEST ; +InvalidTaskFrom , InvalidRequest , BAD_REQUEST ; +InvalidTaskLimit , InvalidRequest , BAD_REQUEST ; +InvalidTaskReverse , InvalidRequest , BAD_REQUEST ; +InvalidTaskStatuses , InvalidRequest , BAD_REQUEST ; +InvalidTaskTypes , InvalidRequest , BAD_REQUEST ; +InvalidTaskUids , InvalidRequest , BAD_REQUEST ; +InvalidBatchUids , InvalidRequest , BAD_REQUEST ; +IoError , System , UNPROCESSABLE_ENTITY; +FeatureNotEnabled , InvalidRequest , BAD_REQUEST ; +MalformedPayload , InvalidRequest , BAD_REQUEST ; +MaxFieldsLimitExceeded , InvalidRequest , BAD_REQUEST ; +MissingApiKeyActions , InvalidRequest , BAD_REQUEST ; +MissingApiKeyExpiresAt , InvalidRequest , BAD_REQUEST ; +MissingApiKeyIndexes , InvalidRequest , BAD_REQUEST ; +MissingAuthorizationHeader , Auth , UNAUTHORIZED ; +MissingContentType , InvalidRequest , UNSUPPORTED_MEDIA_TYPE ; +MissingDocumentId , InvalidRequest , BAD_REQUEST ; +MissingFacetSearchFacetName , InvalidRequest , BAD_REQUEST ; +MissingIndexUid , InvalidRequest , BAD_REQUEST ; +MissingMasterKey , Auth , UNAUTHORIZED ; +MissingNetworkUrl , InvalidRequest , BAD_REQUEST ; +MissingPayload , InvalidRequest , BAD_REQUEST ; +MissingSearchHybrid , InvalidRequest , BAD_REQUEST ; +MissingSwapIndexes , InvalidRequest , BAD_REQUEST ; +MissingTaskFilters , InvalidRequest , BAD_REQUEST ; +NoSpaceLeftOnDevice , System , UNPROCESSABLE_ENTITY; +PayloadTooLarge , InvalidRequest , PAYLOAD_TOO_LARGE ; +RemoteBadResponse , System , BAD_GATEWAY ; +RemoteBadRequest , InvalidRequest , BAD_REQUEST ; +RemoteCouldNotSendRequest , System , BAD_GATEWAY ; +RemoteInvalidApiKey , Auth , FORBIDDEN ; +RemoteRemoteError , System , BAD_GATEWAY ; +RemoteTimeout , System , BAD_GATEWAY ; +TooManySearchRequests , System , SERVICE_UNAVAILABLE ; +TaskNotFound , InvalidRequest , NOT_FOUND ; +TaskFileNotFound , InvalidRequest , NOT_FOUND ; +BatchNotFound , InvalidRequest , NOT_FOUND ; +TooManyOpenFiles , System , UNPROCESSABLE_ENTITY ; +TooManyVectors , InvalidRequest , BAD_REQUEST ; +UnretrievableDocument , Internal , BAD_REQUEST ; +UnretrievableErrorCode , InvalidRequest , BAD_REQUEST ; +UnsupportedMediaType , InvalidRequest , UNSUPPORTED_MEDIA_TYPE ; // Experimental features -VectorEmbeddingError , InvalidRequest , BAD_REQUEST ; -NotFoundSimilarId , InvalidRequest , BAD_REQUEST ; -InvalidDocumentEditionContext , InvalidRequest , BAD_REQUEST ; -InvalidDocumentEditionFunctionFilter , InvalidRequest , BAD_REQUEST ; -EditDocumentsByFunctionError , InvalidRequest , BAD_REQUEST +VectorEmbeddingError , InvalidRequest , BAD_REQUEST ; +NotFoundSimilarId , InvalidRequest , BAD_REQUEST ; +InvalidDocumentEditionContext , InvalidRequest , BAD_REQUEST ; +InvalidDocumentEditionFunctionFilter , InvalidRequest , BAD_REQUEST ; +EditDocumentsByFunctionError , InvalidRequest , BAD_REQUEST ; +InvalidSettingsIndexChat , InvalidRequest , BAD_REQUEST ; +// Experimental features - Chat Completions +UnimplementedExternalFunctionCalling , InvalidRequest , NOT_IMPLEMENTED ; +UnimplementedNonStreamingChatCompletions , InvalidRequest , NOT_IMPLEMENTED ; +UnimplementedMultiChoiceChatCompletions , InvalidRequest , NOT_IMPLEMENTED ; +ChatNotFound , InvalidRequest , NOT_FOUND ; +InvalidChatSettingDocumentTemplate , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionOrgId , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionProjectId , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionApiVersion , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionDeploymentId , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionSource , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionBaseApi , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionApiKey , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionPrompts , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionSystemPrompt , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionSearchDescriptionPrompt , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionSearchQueryParamPrompt , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionSearchIndexUidParamPrompt , InvalidRequest , BAD_REQUEST ; +InvalidChatCompletionPreQueryPrompt , InvalidRequest , BAD_REQUEST } impl ErrorCode for JoinError { @@ -430,6 +450,7 @@ impl ErrorCode for milli::Error { | UserError::InvalidSettingsDimensions { .. } | UserError::InvalidUrl { .. } | UserError::InvalidSettingsDocumentTemplateMaxBytes { .. } + | UserError::InvalidChatSettingsDocumentTemplateMaxBytes | UserError::InvalidPrompt(_) | UserError::InvalidDisableBinaryQuantization { .. } | UserError::InvalidSourceForNested { .. } diff --git a/crates/meilisearch-types/src/features.rs b/crates/meilisearch-types/src/features.rs index 5db8775b6..651077484 100644 --- a/crates/meilisearch-types/src/features.rs +++ b/crates/meilisearch-types/src/features.rs @@ -2,6 +2,14 @@ use std::collections::BTreeMap; use serde::{Deserialize, Serialize}; +use crate::error::{Code, ResponseError}; + +pub const DEFAULT_CHAT_SYSTEM_PROMPT: &str = "You are a highly capable research assistant with access to powerful search tools. IMPORTANT INSTRUCTIONS:1. When answering questions, you MUST make multiple tool calls (at least 2-3) to gather comprehensive information.2. Use different search queries for each tool call - vary keywords, rephrase questions, and explore different semantic angles to ensure broad coverage.3. Always explicitly announce BEFORE making each tool call by saying: \"I'll search for [specific information] now.\"4. Combine information from ALL tool calls to provide complete, nuanced answers rather than relying on a single source.5. For complex topics, break down your research into multiple targeted queries rather than using a single generic search."; +pub const DEFAULT_CHAT_SEARCH_DESCRIPTION_PROMPT: &str = + "Search the database for relevant JSON documents using an optional query."; +pub const DEFAULT_CHAT_SEARCH_Q_PARAM_PROMPT: &str = "The search query string used to find relevant documents in the index. This should contain keywords or phrases that best represent what the user is looking for. More specific queries will yield more precise results."; +pub const DEFAULT_CHAT_SEARCH_INDEX_UID_PARAM_PROMPT: &str = "The name of the index to search within. An index is a collection of documents organized for search. Selecting the right index ensures the most relevant results for the user query."; + #[derive(Serialize, Deserialize, Debug, Clone, Copy, Default, PartialEq, Eq)] #[serde(rename_all = "camelCase", default)] pub struct RuntimeTogglableFeatures { @@ -12,6 +20,7 @@ pub struct RuntimeTogglableFeatures { pub network: bool, pub get_task_documents_route: bool, pub composite_embedders: bool, + pub chat_completions: bool, } #[derive(Default, Debug, Clone, Copy)] @@ -37,3 +46,218 @@ pub struct Network { #[serde(default)] pub remotes: BTreeMap, } + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)] +#[serde(rename_all = "camelCase")] +pub struct ChatCompletionSettings { + pub source: ChatCompletionSource, + #[serde(default)] + pub org_id: Option, + #[serde(default)] + pub project_id: Option, + #[serde(default)] + pub api_version: Option, + #[serde(default)] + pub deployment_id: Option, + #[serde(default)] + pub base_url: Option, + #[serde(default)] + pub api_key: Option, + #[serde(default)] + pub prompts: ChatCompletionPrompts, +} + +impl ChatCompletionSettings { + pub fn hide_secrets(&mut self) { + if let Some(api_key) = &mut self.api_key { + Self::hide_secret(api_key); + } + } + + fn hide_secret(secret: &mut String) { + match secret.len() { + x if x < 10 => { + secret.replace_range(.., "XXX..."); + } + x if x < 20 => { + secret.replace_range(2.., "XXXX..."); + } + x if x < 30 => { + secret.replace_range(3.., "XXXXX..."); + } + _x => { + secret.replace_range(5.., "XXXXXX..."); + } + } + } + + pub fn validate(&self) -> Result<(), ResponseError> { + use ChatCompletionSource::*; + match self { + Self { source: AzureOpenAi, base_url, deployment_id, api_version, .. } if base_url.is_none() || deployment_id.is_none() || api_version.is_none() => Err(ResponseError::from_msg( + "azureOpenAi requires setting a valid `baseUrl`, `deploymentId`, and `apiVersion`".to_string(), + Code::BadRequest, + )), + Self { source: VLlm, base_url, .. } if base_url.is_none() => Err(ResponseError::from_msg( + "vLlm requires setting a valid `baseUrl`".to_string(), + Code::BadRequest, + )), + _otherwise => Ok(()), + } + } +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)] +#[serde(rename_all = "camelCase")] +pub enum ChatCompletionSource { + #[default] + OpenAi, + AzureOpenAi, + Mistral, + Gemini, + VLlm, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum SystemRole { + System, + Developer, +} + +impl ChatCompletionSource { + pub fn system_role(&self, model: &str) -> SystemRole { + use ChatCompletionSource::*; + use SystemRole::*; + match self { + OpenAi if Self::old_openai_model(model) => System, + OpenAi => Developer, + AzureOpenAi if Self::old_openai_model(model) => System, + AzureOpenAi => Developer, + Mistral => System, + Gemini => System, + VLlm => System, + } + } + + /// Returns true if the model is an old OpenAI model. + /// + /// Old OpenAI models use the system role while new ones use the developer role. + fn old_openai_model(model: &str) -> bool { + ["gpt-3.5", "gpt-4", "gpt-4.1", "gpt-4.5", "gpt-4o", "chatgpt-4o"].iter().any(|old| { + model.starts_with(old) + && model.chars().nth(old.chars().count()).is_none_or(|last| last == '-') + }) + } + + pub fn base_url(&self) -> Option<&'static str> { + use ChatCompletionSource::*; + match self { + OpenAi => Some("https://api.openai.com/v1/"), + Mistral => Some("https://api.mistral.ai/v1/"), + Gemini => Some("https://generativelanguage.googleapis.com/v1beta/openai/"), + AzureOpenAi | VLlm => None, + } + } +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct ChatCompletionPrompts { + pub system: String, + pub search_description: String, + pub search_q_param: String, + pub search_index_uid_param: String, +} + +impl Default for ChatCompletionPrompts { + fn default() -> Self { + Self { + system: DEFAULT_CHAT_SYSTEM_PROMPT.to_string(), + search_description: DEFAULT_CHAT_SEARCH_DESCRIPTION_PROMPT.to_string(), + search_q_param: DEFAULT_CHAT_SEARCH_Q_PARAM_PROMPT.to_string(), + search_index_uid_param: DEFAULT_CHAT_SEARCH_INDEX_UID_PARAM_PROMPT.to_string(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const ALL_OPENAI_MODELS_OLDINESS: &[(&str, bool)] = &[ + ("gpt-4-0613", true), + ("gpt-4", true), + ("gpt-3.5-turbo", true), + ("gpt-4o-audio-preview-2025-06-03", true), + ("gpt-4.1-nano", true), + ("gpt-4o-realtime-preview-2025-06-03", true), + ("gpt-3.5-turbo-instruct", true), + ("gpt-3.5-turbo-instruct-0914", true), + ("gpt-4-1106-preview", true), + ("gpt-3.5-turbo-1106", true), + ("gpt-4-0125-preview", true), + ("gpt-4-turbo-preview", true), + ("gpt-3.5-turbo-0125", true), + ("gpt-4-turbo", true), + ("gpt-4-turbo-2024-04-09", true), + ("gpt-4o", true), + ("gpt-4o-2024-05-13", true), + ("gpt-4o-mini-2024-07-18", true), + ("gpt-4o-mini", true), + ("gpt-4o-2024-08-06", true), + ("chatgpt-4o-latest", true), + ("gpt-4o-realtime-preview-2024-10-01", true), + ("gpt-4o-audio-preview-2024-10-01", true), + ("gpt-4o-audio-preview", true), + ("gpt-4o-realtime-preview", true), + ("gpt-4o-realtime-preview-2024-12-17", true), + ("gpt-4o-audio-preview-2024-12-17", true), + ("gpt-4o-mini-realtime-preview-2024-12-17", true), + ("gpt-4o-mini-audio-preview-2024-12-17", true), + ("gpt-4o-mini-realtime-preview", true), + ("gpt-4o-mini-audio-preview", true), + ("gpt-4o-2024-11-20", true), + ("gpt-4.5-preview", true), + ("gpt-4.5-preview-2025-02-27", true), + ("gpt-4o-search-preview-2025-03-11", true), + ("gpt-4o-search-preview", true), + ("gpt-4o-mini-search-preview-2025-03-11", true), + ("gpt-4o-mini-search-preview", true), + ("gpt-4o-transcribe", true), + ("gpt-4o-mini-transcribe", true), + ("gpt-4o-mini-tts", true), + ("gpt-4.1-2025-04-14", true), + ("gpt-4.1", true), + ("gpt-4.1-mini-2025-04-14", true), + ("gpt-4.1-mini", true), + ("gpt-4.1-nano-2025-04-14", true), + ("gpt-3.5-turbo-16k", true), + // + // new models + ("o1-preview-2024-09-12", false), + ("o1-preview", false), + ("o1-mini-2024-09-12", false), + ("o1-mini", false), + ("o1-2024-12-17", false), + ("o1", false), + ("o3-mini", false), + ("o3-mini-2025-01-31", false), + ("o1-pro-2025-03-19", false), + ("o1-pro", false), + ("o3-2025-04-16", false), + ("o4-mini-2025-04-16", false), + ("o3", false), + ("o4-mini", false), + ]; + + #[test] + fn old_openai_models() { + for (name, is_old) in ALL_OPENAI_MODELS_OLDINESS.iter().copied() { + assert_eq!( + ChatCompletionSource::old_openai_model(name), + is_old, + "Model {name} is not considered old" + ); + } + } +} diff --git a/crates/meilisearch-types/src/keys.rs b/crates/meilisearch-types/src/keys.rs index 27f2047ee..df2810727 100644 --- a/crates/meilisearch-types/src/keys.rs +++ b/crates/meilisearch-types/src/keys.rs @@ -53,7 +53,7 @@ pub struct CreateApiKey { #[schema(example = json!(["documents.add"]))] #[deserr(error = DeserrJsonError, missing_field_error = DeserrJsonError::missing_api_key_actions)] pub actions: Vec, - /// A list of accesible indexes permitted for the key. `["*"]` for all indexes. The `*` character can be used as a wildcard when located at the last position. e.g. `products_*` to allow access to all indexes whose names start with `products_`. + /// A list of accessible indexes permitted for the key. `["*"]` for all indexes. The `*` character can be used as a wildcard when located at the last position. e.g. `products_*` to allow access to all indexes whose names start with `products_`. #[deserr(error = DeserrJsonError, missing_field_error = DeserrJsonError::missing_api_key_indexes)] #[schema(value_type = Vec, example = json!(["products"]))] pub indexes: Vec, @@ -158,6 +158,21 @@ impl Key { updated_at: now, } } + + pub fn default_chat() -> Self { + let now = OffsetDateTime::now_utc(); + let uid = Uuid::new_v4(); + Self { + name: Some("Default Chat API Key".to_string()), + description: Some("Use it to chat and search from the frontend".to_string()), + uid, + actions: vec![Action::ChatCompletions, Action::Search], + indexes: vec![IndexUidPattern::all()], + expires_at: None, + created_at: now, + updated_at: now, + } + } } fn parse_expiration_date( @@ -308,6 +323,27 @@ pub enum Action { #[serde(rename = "network.update")] #[deserr(rename = "network.update")] NetworkUpdate, + #[serde(rename = "chatCompletions")] + #[deserr(rename = "chatCompletions")] + ChatCompletions, + #[serde(rename = "chats.*")] + #[deserr(rename = "chats.*")] + ChatsAll, + #[serde(rename = "chats.get")] + #[deserr(rename = "chats.get")] + ChatsGet, + #[serde(rename = "chats.delete")] + #[deserr(rename = "chats.delete")] + ChatsDelete, + #[serde(rename = "chatsSettings.*")] + #[deserr(rename = "chatsSettings.*")] + ChatsSettingsAll, + #[serde(rename = "chatsSettings.get")] + #[deserr(rename = "chatsSettings.get")] + ChatsSettingsGet, + #[serde(rename = "chatsSettings.update")] + #[deserr(rename = "chatsSettings.update")] + ChatsSettingsUpdate, } impl Action { @@ -333,6 +369,13 @@ impl Action { SETTINGS_ALL => Some(Self::SettingsAll), SETTINGS_GET => Some(Self::SettingsGet), SETTINGS_UPDATE => Some(Self::SettingsUpdate), + CHAT_COMPLETIONS => Some(Self::ChatCompletions), + CHATS_ALL => Some(Self::ChatsAll), + CHATS_GET => Some(Self::ChatsGet), + CHATS_DELETE => Some(Self::ChatsDelete), + CHATS_SETTINGS_ALL => Some(Self::ChatsSettingsAll), + CHATS_SETTINGS_GET => Some(Self::ChatsSettingsGet), + CHATS_SETTINGS_UPDATE => Some(Self::ChatsSettingsUpdate), STATS_ALL => Some(Self::StatsAll), STATS_GET => Some(Self::StatsGet), METRICS_ALL => Some(Self::MetricsAll), @@ -397,4 +440,12 @@ pub mod actions { pub const NETWORK_GET: u8 = NetworkGet.repr(); pub const NETWORK_UPDATE: u8 = NetworkUpdate.repr(); + + pub const CHAT_COMPLETIONS: u8 = ChatCompletions.repr(); + pub const CHATS_ALL: u8 = ChatsAll.repr(); + pub const CHATS_GET: u8 = ChatsGet.repr(); + pub const CHATS_DELETE: u8 = ChatsDelete.repr(); + pub const CHATS_SETTINGS_ALL: u8 = ChatsSettingsAll.repr(); + pub const CHATS_SETTINGS_GET: u8 = ChatsSettingsGet.repr(); + pub const CHATS_SETTINGS_UPDATE: u8 = ChatsSettingsUpdate.repr(); } diff --git a/crates/meilisearch-types/src/settings.rs b/crates/meilisearch-types/src/settings.rs index edb136567..d26c575d6 100644 --- a/crates/meilisearch-types/src/settings.rs +++ b/crates/meilisearch-types/src/settings.rs @@ -11,6 +11,7 @@ use fst::IntoStreamer; use milli::disabled_typos_terms::DisabledTyposTerms; use milli::index::{IndexEmbeddingConfig, PrefixSearch}; use milli::proximity::ProximityPrecision; +pub use milli::update::ChatSettings; use milli::update::Setting; use milli::{Criterion, CriterionError, FilterableAttributesRule, Index, DEFAULT_VALUES_PER_FACET}; use serde::{Deserialize, Serialize, Serializer}; @@ -185,7 +186,7 @@ impl Deserr for SettingEmbeddingSettings { /// Holds all the settings for an index. `T` can either be `Checked` if they represents settings /// whose validity is guaranteed, or `Unchecked` if they need to be validated. In the later case, a /// call to `check` will return a `Settings` from a `Settings`. -#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Deserr, ToSchema)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Deserr, ToSchema)] #[serde( deny_unknown_fields, rename_all = "camelCase", @@ -199,72 +200,86 @@ pub struct Settings { #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!(["id", "title", "description", "url"]))] pub displayed_attributes: WildcardSetting, + /// Fields in which to search for matching query words sorted by order of importance. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!(["title", "description"]))] pub searchable_attributes: WildcardSetting, + /// Attributes to use for faceting and filtering. See [Filtering and Faceted Search](https://www.meilisearch.com/docs/learn/filtering_and_sorting/search_with_facet_filters). #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!(["release_date", "genre"]))] pub filterable_attributes: Setting>, + /// Attributes to use when sorting search results. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!(["release_date"]))] pub sortable_attributes: Setting>, + /// List of ranking rules sorted by order of importance. The order is customizable. /// [A list of ordered built-in ranking rules](https://www.meilisearch.com/docs/learn/relevancy/relevancy). #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!([RankingRuleView::Words, RankingRuleView::Typo, RankingRuleView::Proximity, RankingRuleView::Attribute, RankingRuleView::Exactness]))] pub ranking_rules: Setting>, + /// List of words ignored when present in search queries. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!(["the", "a", "them", "their"]))] pub stop_words: Setting>, + /// List of characters not delimiting where one term begins and ends. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!([" ", "\n"]))] pub non_separator_tokens: Setting>, + /// List of characters delimiting where one term begins and ends. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!(["S"]))] pub separator_tokens: Setting>, + /// List of strings Meilisearch should parse as a single term. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!(["iPhone pro"]))] pub dictionary: Setting>, + /// List of associated words treated similarly. A word associated to an array of word as synonyms. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>>, example = json!({ "he": ["she", "they", "them"], "phone": ["iPhone", "android"]}))] pub synonyms: Setting>>, + /// Search returns documents with distinct (different) values of the given field. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option, example = json!("sku"))] pub distinct_attribute: Setting, + /// Precision level when calculating the proximity ranking rule. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option, example = json!(ProximityPrecisionView::ByAttribute))] pub proximity_precision: Setting, + /// Customize typo tolerance feature. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option, example = json!({ "enabled": true, "disableOnAttributes": ["title"]}))] pub typo_tolerance: Setting, + /// Faceting settings. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option, example = json!({ "maxValuesPerFacet": 10, "sortFacetValuesBy": { "genre": FacetValuesSort::Count }}))] pub faceting: Setting, + /// Pagination settings. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] @@ -276,24 +291,34 @@ pub struct Settings { #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>)] pub embedders: Setting>, + /// Maximum duration of a search query. #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option, example = json!(50))] pub search_cutoff_ms: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option>, example = json!(50))] pub localized_attributes: Setting>, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option, example = json!(true))] pub facet_search: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default, error = DeserrJsonError)] #[schema(value_type = Option, example = json!("Hemlo"))] pub prefix_search: Setting, + /// Customize the chat prompting. + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option)] + pub chat: Setting, + #[serde(skip)] #[deserr(skip)] pub _kind: PhantomData, @@ -359,6 +384,7 @@ impl Settings { localized_attributes: Setting::Reset, facet_search: Setting::Reset, prefix_search: Setting::Reset, + chat: Setting::Reset, _kind: PhantomData, } } @@ -385,6 +411,7 @@ impl Settings { localized_attributes: localized_attributes_rules, facet_search, prefix_search, + chat, _kind, } = self; @@ -409,6 +436,7 @@ impl Settings { localized_attributes: localized_attributes_rules, facet_search, prefix_search, + chat, _kind: PhantomData, } } @@ -459,6 +487,7 @@ impl Settings { localized_attributes: self.localized_attributes, facet_search: self.facet_search, prefix_search: self.prefix_search, + chat: self.chat, _kind: PhantomData, } } @@ -533,8 +562,9 @@ impl Settings { Setting::Set(this) } }, - prefix_search: other.prefix_search.or(self.prefix_search), facet_search: other.facet_search.or(self.facet_search), + prefix_search: other.prefix_search.or(self.prefix_search), + chat: other.chat.clone().or(self.chat.clone()), _kind: PhantomData, } } @@ -573,6 +603,7 @@ pub fn apply_settings_to_builder( localized_attributes: localized_attributes_rules, facet_search, prefix_search, + chat, _kind, } = settings; @@ -783,6 +814,12 @@ pub fn apply_settings_to_builder( Setting::Reset => builder.reset_facet_search(), Setting::NotSet => (), } + + match chat { + Setting::Set(chat) => builder.set_chat(chat.clone()), + Setting::Reset => builder.reset_chat(), + Setting::NotSet => (), + } } pub enum SecretPolicy { @@ -880,14 +917,11 @@ pub fn settings( }) .collect(); let embedders = Setting::Set(embedders); - let search_cutoff_ms = index.search_cutoff(rtxn)?; - let localized_attributes_rules = index.localized_attributes_rules(rtxn)?; - let prefix_search = index.prefix_search(rtxn)?.map(PrefixSearchSettings::from); - let facet_search = index.facet_search(rtxn)?; + let chat = index.chat_config(rtxn).map(ChatSettings::from)?; let mut settings = Settings { displayed_attributes: match displayed_attributes { @@ -925,8 +959,9 @@ pub fn settings( Some(rules) => Setting::Set(rules.into_iter().map(|r| r.into()).collect()), None => Setting::Reset, }, - prefix_search: Setting::Set(prefix_search.unwrap_or_default()), facet_search: Setting::Set(facet_search), + prefix_search: Setting::Set(prefix_search.unwrap_or_default()), + chat: Setting::Set(chat), _kind: PhantomData, }; @@ -1154,6 +1189,7 @@ pub(crate) mod test { search_cutoff_ms: Setting::NotSet, facet_search: Setting::NotSet, prefix_search: Setting::NotSet, + chat: Setting::NotSet, _kind: PhantomData::, }; @@ -1185,6 +1221,8 @@ pub(crate) mod test { search_cutoff_ms: Setting::NotSet, facet_search: Setting::NotSet, prefix_search: Setting::NotSet, + chat: Setting::NotSet, + _kind: PhantomData::, }; diff --git a/crates/meilisearch-types/src/task_view.rs b/crates/meilisearch-types/src/task_view.rs index 7a6faee39..86a00426b 100644 --- a/crates/meilisearch-types/src/task_view.rs +++ b/crates/meilisearch-types/src/task_view.rs @@ -8,7 +8,7 @@ use crate::error::ResponseError; use crate::settings::{Settings, Unchecked}; use crate::tasks::{serialize_duration, Details, IndexSwap, Kind, Status, Task, TaskId}; -#[derive(Debug, Clone, PartialEq, Eq, Serialize, ToSchema)] +#[derive(Debug, Clone, PartialEq, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] #[schema(rename_all = "camelCase")] pub struct TaskView { @@ -67,7 +67,7 @@ impl TaskView { } } -#[derive(Default, Debug, PartialEq, Eq, Clone, Serialize, Deserialize, ToSchema)] +#[derive(Default, Debug, PartialEq, Clone, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] #[schema(rename_all = "camelCase")] pub struct DetailsView { diff --git a/crates/meilisearch-types/src/tasks.rs b/crates/meilisearch-types/src/tasks.rs index 24254d36e..95c52d9a6 100644 --- a/crates/meilisearch-types/src/tasks.rs +++ b/crates/meilisearch-types/src/tasks.rs @@ -597,7 +597,7 @@ impl fmt::Display for ParseTaskKindError { } impl std::error::Error for ParseTaskKindError {} -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub enum Details { DocumentAdditionOrUpdate { received_documents: u64, diff --git a/crates/meilisearch/Cargo.toml b/crates/meilisearch/Cargo.toml index 40c0d98b5..c75b55bc2 100644 --- a/crates/meilisearch/Cargo.toml +++ b/crates/meilisearch/Cargo.toml @@ -32,6 +32,7 @@ async-trait = "0.1.85" bstr = "1.11.3" byte-unit = { version = "5.1.6", features = ["serde"] } bytes = "1.9.0" +bumpalo = "3.16.0" clap = { version = "4.5.24", features = ["derive", "env"] } crossbeam-channel = "0.5.15" deserr = { version = "0.6.3", features = ["actix-web"] } @@ -111,6 +112,9 @@ utoipa = { version = "5.3.1", features = [ "openapi_extensions", ] } utoipa-scalar = { version = "0.3.0", optional = true, features = ["actix-web"] } +async-openai = { git = "https://github.com/meilisearch/async-openai", branch = "better-error-handling" } +secrecy = "0.10.3" +actix-web-lab = { version = "0.24.1", default-features = false } [dev-dependencies] actix-rt = "2.10.0" diff --git a/crates/meilisearch/src/analytics/segment_analytics.rs b/crates/meilisearch/src/analytics/segment_analytics.rs index ee8a9ee20..c7e0634f4 100644 --- a/crates/meilisearch/src/analytics/segment_analytics.rs +++ b/crates/meilisearch/src/analytics/segment_analytics.rs @@ -197,6 +197,7 @@ struct Infos { experimental_max_number_of_batched_tasks: usize, experimental_limit_batched_tasks_total_size: u64, experimental_network: bool, + experimental_chat_completions: bool, experimental_get_task_documents_route: bool, experimental_composite_embedders: bool, experimental_embedding_cache_entries: usize, @@ -296,6 +297,7 @@ impl Infos { network, get_task_documents_route, composite_embedders, + chat_completions, } = features; // We're going to override every sensible information. @@ -314,6 +316,7 @@ impl Infos { experimental_enable_logs_route: experimental_enable_logs_route | logs_route, experimental_reduce_indexing_memory_usage, experimental_network: network, + experimental_chat_completions: chat_completions, experimental_get_task_documents_route: get_task_documents_route, experimental_composite_embedders: composite_embedders, experimental_embedding_cache_entries, diff --git a/crates/meilisearch/src/extractors/authentication/mod.rs b/crates/meilisearch/src/extractors/authentication/mod.rs index 28a6d770e..86614f153 100644 --- a/crates/meilisearch/src/extractors/authentication/mod.rs +++ b/crates/meilisearch/src/extractors/authentication/mod.rs @@ -4,6 +4,7 @@ use std::marker::PhantomData; use std::ops::Deref; use std::pin::Pin; +use actix_web::http::header::AUTHORIZATION; use actix_web::web::Data; use actix_web::FromRequest; pub use error::AuthenticationError; @@ -94,36 +95,44 @@ impl FromRequest for GuardedData _payload: &mut actix_web::dev::Payload, ) -> Self::Future { match req.app_data::>().cloned() { - Some(auth) => match req - .headers() - .get("Authorization") - .map(|type_token| type_token.to_str().unwrap_or_default().splitn(2, ' ')) - { - Some(mut type_token) => match type_token.next() { - Some("Bearer") => { - // TODO: find a less hardcoded way? - let index = req.match_info().get("index_uid"); - match type_token.next() { - Some(token) => Box::pin(Self::auth_bearer( - auth, - token.to_string(), - index.map(String::from), - req.app_data::().cloned(), - )), - None => Box::pin(err(AuthenticationError::InvalidToken.into())), - } - } - _otherwise => { - Box::pin(err(AuthenticationError::MissingAuthorizationHeader.into())) - } - }, - None => Box::pin(Self::auth_token(auth, req.app_data::().cloned())), + Some(auth) => match extract_token_from_request(req) { + Ok(Some(token)) => { + // TODO: find a less hardcoded way? + let index = req.match_info().get("index_uid"); + Box::pin(Self::auth_bearer( + auth, + token.to_string(), + index.map(String::from), + req.app_data::().cloned(), + )) + } + Ok(None) => Box::pin(Self::auth_token(auth, req.app_data::().cloned())), + Err(e) => Box::pin(err(e.into())), }, None => Box::pin(err(AuthenticationError::IrretrievableState.into())), } } } +pub fn extract_token_from_request( + req: &actix_web::HttpRequest, +) -> Result, AuthenticationError> { + match req + .headers() + .get(AUTHORIZATION) + .map(|type_token| type_token.to_str().unwrap_or_default().splitn(2, ' ')) + { + Some(mut type_token) => match type_token.next() { + Some("Bearer") => match type_token.next() { + Some(token) => Ok(Some(token)), + None => Err(AuthenticationError::InvalidToken), + }, + _otherwise => Err(AuthenticationError::MissingAuthorizationHeader), + }, + None => Ok(None), + } +} + pub trait Policy { fn authenticate( auth: Data, @@ -299,8 +308,8 @@ pub mod policies { auth: &AuthController, token: &str, ) -> Result { - // Only search action can be accessed by a tenant token. - if A != actions::SEARCH { + // Only search and chat actions can be accessed by a tenant token. + if A != actions::SEARCH && A != actions::CHAT_COMPLETIONS { return Ok(TenantTokenOutcome::NotATenantToken); } diff --git a/crates/meilisearch/src/routes/chats/chat_completions.rs b/crates/meilisearch/src/routes/chats/chat_completions.rs new file mode 100644 index 000000000..7431609e6 --- /dev/null +++ b/crates/meilisearch/src/routes/chats/chat_completions.rs @@ -0,0 +1,733 @@ +use std::collections::HashMap; +use std::fmt::Write as _; +use std::mem; +use std::ops::ControlFlow; +use std::time::Duration; + +use actix_web::web::{self, Data}; +use actix_web::{Either, HttpRequest, HttpResponse, Responder}; +use actix_web_lab::sse::{Event, Sse}; +use async_openai::types::{ + ChatCompletionMessageToolCall, ChatCompletionMessageToolCallChunk, + ChatCompletionRequestAssistantMessageArgs, ChatCompletionRequestDeveloperMessage, + ChatCompletionRequestDeveloperMessageContent, ChatCompletionRequestMessage, + ChatCompletionRequestSystemMessage, ChatCompletionRequestSystemMessageContent, + ChatCompletionRequestToolMessage, ChatCompletionRequestToolMessageContent, + ChatCompletionStreamResponseDelta, ChatCompletionToolArgs, ChatCompletionToolType, + CreateChatCompletionRequest, CreateChatCompletionStreamResponse, FinishReason, FunctionCall, + FunctionCallStream, FunctionObjectArgs, +}; +use async_openai::Client; +use bumpalo::Bump; +use futures::StreamExt; +use index_scheduler::IndexScheduler; +use meilisearch_auth::AuthController; +use meilisearch_types::error::{Code, ResponseError}; +use meilisearch_types::features::{ChatCompletionPrompts as DbChatCompletionPrompts, SystemRole}; +use meilisearch_types::keys::actions; +use meilisearch_types::milli::index::ChatConfig; +use meilisearch_types::milli::{all_obkv_to_json, obkv_to_json, TimeBudget}; +use meilisearch_types::{Document, Index}; +use serde::Deserialize; +use serde_json::json; +use tokio::runtime::Handle; +use tokio::sync::mpsc::error::SendError; + +use super::config::Config; +use super::errors::StreamErrorEvent; +use super::utils::format_documents; +use super::{ + ChatsParam, MEILI_APPEND_CONVERSATION_MESSAGE_NAME, MEILI_SEARCH_IN_INDEX_FUNCTION_NAME, + MEILI_SEARCH_PROGRESS_NAME, MEILI_SEARCH_SOURCES_NAME, +}; +use crate::error::MeilisearchHttpError; +use crate::extractors::authentication::policies::ActionPolicy; +use crate::extractors::authentication::{extract_token_from_request, GuardedData, Policy as _}; +use crate::metrics::MEILISEARCH_DEGRADED_SEARCH_REQUESTS; +use crate::routes::chats::utils::SseEventSender; +use crate::routes::indexes::search::search_kind; +use crate::search::{add_search_rules, prepare_search, search_from_kind, SearchQuery}; +use crate::search_queue::SearchQueue; + +pub fn configure(cfg: &mut web::ServiceConfig) { + cfg.service(web::resource("").route(web::post().to(chat))); +} + +/// Get a chat completion +async fn chat( + index_scheduler: GuardedData, Data>, + auth_ctrl: web::Data, + chats_param: web::Path, + req: HttpRequest, + search_queue: web::Data, + web::Json(chat_completion): web::Json, +) -> impl Responder { + let ChatsParam { workspace_uid } = chats_param.into_inner(); + + if chat_completion.stream.unwrap_or(false) { + Either::Right( + streamed_chat( + index_scheduler, + auth_ctrl, + search_queue, + &workspace_uid, + req, + chat_completion, + ) + .await, + ) + } else { + Either::Left( + non_streamed_chat( + index_scheduler, + auth_ctrl, + search_queue, + &workspace_uid, + req, + chat_completion, + ) + .await, + ) + } +} + +#[derive(Default, Debug, Clone, Copy)] +pub struct FunctionSupport { + /// Defines if we can call the _meiliSearchProgress function + /// to inform the front-end about what we are searching for. + report_progress: bool, + /// Defines if we can call the _meiliSearchSources function + /// to inform the front-end about the sources of the search. + report_sources: bool, + /// Defines if we can call the _meiliAppendConversationMessage + /// function to provide the messages to append into the conversation. + append_to_conversation: bool, +} + +/// Setup search tool in chat completion request +fn setup_search_tool( + index_scheduler: &Data, + filters: &meilisearch_auth::AuthFilter, + chat_completion: &mut CreateChatCompletionRequest, + prompts: &DbChatCompletionPrompts, + system_role: SystemRole, +) -> Result { + let tools = chat_completion.tools.get_or_insert_default(); + for tool in &tools[..] { + match tool.function.name.as_str() { + MEILI_SEARCH_IN_INDEX_FUNCTION_NAME => { + return Err(ResponseError::from_msg( + format!("{MEILI_SEARCH_IN_INDEX_FUNCTION_NAME} function is already defined."), + Code::BadRequest, + )); + } + MEILI_SEARCH_PROGRESS_NAME + | MEILI_SEARCH_SOURCES_NAME + | MEILI_APPEND_CONVERSATION_MESSAGE_NAME => (), + external_function_name => { + return Err(ResponseError::from_msg( + format!("{external_function_name}: External functions are not supported yet."), + Code::UnimplementedExternalFunctionCalling, + )); + } + } + } + + // Remove internal tools used for front-end notifications as they should be hidden from the LLM. + let mut report_progress = false; + let mut report_sources = false; + let mut append_to_conversation = false; + tools.retain(|tool| { + match tool.function.name.as_str() { + MEILI_SEARCH_PROGRESS_NAME => { + report_progress = true; + false + } + MEILI_SEARCH_SOURCES_NAME => { + report_sources = true; + false + } + MEILI_APPEND_CONVERSATION_MESSAGE_NAME => { + append_to_conversation = true; + false + } + _ => true, // keep other tools + } + }); + + let mut index_uids = Vec::new(); + let mut function_description = prompts.search_description.clone(); + index_scheduler.try_for_each_index::<_, ()>(|name, index| { + // Make sure to skip unauthorized indexes + if !filters.is_index_authorized(name) { + return Ok(()); + } + + let rtxn = index.read_txn()?; + let chat_config = index.chat_config(&rtxn)?; + let index_description = chat_config.description; + let _ = writeln!(&mut function_description, "\n\n - {name}: {index_description}\n"); + index_uids.push(name.to_string()); + + Ok(()) + })?; + + let tool = ChatCompletionToolArgs::default() + .r#type(ChatCompletionToolType::Function) + .function( + FunctionObjectArgs::default() + .name(MEILI_SEARCH_IN_INDEX_FUNCTION_NAME) + .description(&function_description) + .parameters(json!({ + "type": "object", + "properties": { + "index_uid": { + "type": "string", + "enum": index_uids, + "description": prompts.search_index_uid_param, + }, + "q": { + // Unfortunately, Mistral does not support an array of types, here. + // "type": ["string", "null"], + "type": "string", + "description": prompts.search_q_param, + } + }, + "required": ["index_uid", "q"], + "additionalProperties": false, + })) + .strict(true) + .build() + .unwrap(), + ) + .build() + .unwrap(); + + tools.push(tool); + + let system_message = match system_role { + SystemRole::System => { + ChatCompletionRequestMessage::System(ChatCompletionRequestSystemMessage { + content: ChatCompletionRequestSystemMessageContent::Text(prompts.system.clone()), + name: None, + }) + } + SystemRole::Developer => { + ChatCompletionRequestMessage::Developer(ChatCompletionRequestDeveloperMessage { + content: ChatCompletionRequestDeveloperMessageContent::Text(prompts.system.clone()), + name: None, + }) + } + }; + chat_completion.messages.insert(0, system_message); + + Ok(FunctionSupport { report_progress, report_sources, append_to_conversation }) +} + +/// Process search request and return formatted results +async fn process_search_request( + index_scheduler: &GuardedData< + ActionPolicy<{ actions::CHAT_COMPLETIONS }>, + Data, + >, + auth_ctrl: web::Data, + search_queue: &web::Data, + auth_token: &str, + index_uid: String, + q: Option, +) -> Result<(Index, Vec, String), ResponseError> { + let index = index_scheduler.index(&index_uid)?; + let rtxn = index.static_read_txn()?; + let ChatConfig { description: _, prompt: _, search_parameters } = index.chat_config(&rtxn)?; + let mut query = SearchQuery { q, ..SearchQuery::from(search_parameters) }; + let auth_filter = ActionPolicy::<{ actions::SEARCH }>::authenticate( + auth_ctrl, + auth_token, + Some(index_uid.as_str()), + )?; + + // Tenant token search_rules. + if let Some(search_rules) = auth_filter.get_index_search_rules(&index_uid) { + add_search_rules(&mut query.filter, search_rules); + } + let search_kind = + search_kind(&query, index_scheduler.get_ref(), index_uid.to_string(), &index)?; + + let permit = search_queue.try_get_search_permit().await?; + let features = index_scheduler.features(); + let index_cloned = index.clone(); + let output = tokio::task::spawn_blocking(move || -> Result<_, ResponseError> { + let time_budget = match index_cloned + .search_cutoff(&rtxn) + .map_err(|e| MeilisearchHttpError::from_milli(e, Some(index_uid.clone())))? + { + Some(cutoff) => TimeBudget::new(Duration::from_millis(cutoff)), + None => TimeBudget::default(), + }; + + let (search, _is_finite_pagination, _max_total_hits, _offset) = + prepare_search(&index_cloned, &rtxn, &query, &search_kind, time_budget, features)?; + + search_from_kind(index_uid, search_kind, search) + .map(|(search_results, _)| (rtxn, search_results)) + .map_err(ResponseError::from) + }) + .await; + permit.drop().await; + + let output = output?; + let mut documents = Vec::new(); + if let Ok((ref rtxn, ref search_result)) = output { + // aggregate.succeed(search_result); + if search_result.degraded { + MEILISEARCH_DEGRADED_SEARCH_REQUESTS.inc(); + } + + let fields_ids_map = index.fields_ids_map(rtxn)?; + let displayed_fields = index.displayed_fields_ids(rtxn)?; + for &document_id in &search_result.documents_ids { + let obkv = index.document(rtxn, document_id)?; + let document = match displayed_fields { + Some(ref fields) => obkv_to_json(fields, &fields_ids_map, obkv)?, + None => all_obkv_to_json(obkv, &fields_ids_map)?, + }; + documents.push(document); + } + } + + let (rtxn, search_result) = output?; + let render_alloc = Bump::new(); + let formatted = format_documents(&rtxn, &index, &render_alloc, search_result.documents_ids)?; + let text = formatted.join("\n"); + drop(rtxn); + + Ok((index, documents, text)) +} + +#[allow(unreachable_code, unused_variables)] // will be correctly implemented in the future +async fn non_streamed_chat( + index_scheduler: GuardedData, Data>, + auth_ctrl: web::Data, + search_queue: web::Data, + workspace_uid: &str, + req: HttpRequest, + chat_completion: CreateChatCompletionRequest, +) -> Result { + index_scheduler.features().check_chat_completions("using the /chats chat completions route")?; + + if let Some(n) = chat_completion.n.filter(|&n| n != 1) { + return Err(ResponseError::from_msg( + format!("You tried to specify n = {n} but only single choices are supported (n = 1)."), + Code::UnimplementedMultiChoiceChatCompletions, + )); + } + + return Err(ResponseError::from_msg( + "Non-streamed chat completions is not implemented".to_string(), + Code::UnimplementedNonStreamingChatCompletions, + )); + + let filters = index_scheduler.filters(); + let chat_settings = match index_scheduler.chat_settings(workspace_uid).unwrap() { + Some(settings) => settings, + None => { + return Err(ResponseError::from_msg( + format!("Chat `{workspace_uid}` not found"), + Code::ChatNotFound, + )) + } + }; + + let config = Config::new(&chat_settings); + let client = Client::with_config(config); + let auth_token = extract_token_from_request(&req)?.unwrap(); + let system_role = chat_settings.source.system_role(&chat_completion.model); + // TODO do function support later + let _function_support = setup_search_tool( + &index_scheduler, + filters, + &mut chat_completion, + &chat_settings.prompts, + system_role, + )?; + + let mut response; + loop { + response = client.chat().create(chat_completion.clone()).await.unwrap(); + + let choice = &mut response.choices[0]; + match choice.finish_reason { + Some(FinishReason::ToolCalls) => { + let tool_calls = mem::take(&mut choice.message.tool_calls).unwrap_or_default(); + + let (meili_calls, other_calls): (Vec<_>, Vec<_>) = tool_calls + .into_iter() + .partition(|call| call.function.name == MEILI_SEARCH_IN_INDEX_FUNCTION_NAME); + + chat_completion.messages.push( + ChatCompletionRequestAssistantMessageArgs::default() + .tool_calls(meili_calls.clone()) + .build() + .unwrap() + .into(), + ); + + for call in meili_calls { + let result = match serde_json::from_str(&call.function.arguments) { + Ok(SearchInIndexParameters { index_uid, q }) => process_search_request( + &index_scheduler, + auth_ctrl.clone(), + &search_queue, + auth_token, + index_uid, + q, + ) + .await + .map_err(|e| e.to_string()), + Err(err) => Err(err.to_string()), + }; + + // TODO report documents sources later + let answer = match result { + Ok((_, _documents, text)) => text, + Err(err) => err, + }; + + chat_completion.messages.push(ChatCompletionRequestMessage::Tool( + ChatCompletionRequestToolMessage { + tool_call_id: call.id.clone(), + content: ChatCompletionRequestToolMessageContent::Text(answer), + }, + )); + } + + // Let the client call other tools by themselves + if !other_calls.is_empty() { + response.choices[0].message.tool_calls = Some(other_calls); + break; + } + } + _ => break, + } + } + + Ok(HttpResponse::Ok().json(response)) +} + +async fn streamed_chat( + index_scheduler: GuardedData, Data>, + auth_ctrl: web::Data, + search_queue: web::Data, + workspace_uid: &str, + req: HttpRequest, + mut chat_completion: CreateChatCompletionRequest, +) -> Result { + index_scheduler.features().check_chat_completions("using the /chats chat completions route")?; + let filters = index_scheduler.filters(); + + if let Some(n) = chat_completion.n.filter(|&n| n != 1) { + return Err(ResponseError::from_msg( + format!("You tried to specify n = {n} but only single choices are supported (n = 1)."), + Code::UnimplementedMultiChoiceChatCompletions, + )); + } + + let chat_settings = match index_scheduler.chat_settings(workspace_uid)? { + Some(settings) => settings, + None => { + return Err(ResponseError::from_msg( + format!("Chat `{workspace_uid}` not found"), + Code::ChatNotFound, + )) + } + }; + + let config = Config::new(&chat_settings); + let auth_token = extract_token_from_request(&req)?.unwrap().to_string(); + let system_role = chat_settings.source.system_role(&chat_completion.model); + let function_support = setup_search_tool( + &index_scheduler, + filters, + &mut chat_completion, + &chat_settings.prompts, + system_role, + )?; + + tracing::debug!("Conversation function support: {function_support:?}"); + + let (tx, rx) = tokio::sync::mpsc::channel(10); + let tx = SseEventSender::new(tx); + let _join_handle = Handle::current().spawn(async move { + let client = Client::with_config(config.clone()); + let mut global_tool_calls = HashMap::::new(); + + // Limit the number of internal calls to satisfy the search requests of the LLM + for _ in 0..20 { + let output = run_conversation( + &index_scheduler, + &auth_ctrl, + &search_queue, + &auth_token, + &client, + &mut chat_completion, + &tx, + &mut global_tool_calls, + function_support, + ); + + match output.await { + Ok(ControlFlow::Continue(())) => (), + Ok(ControlFlow::Break(_finish_reason)) => break, + // If the connection is closed we must stop + Err(SendError(_)) => return, + } + } + + let _ = tx.stop().await; + }); + + Ok(Sse::from_infallible_receiver(rx).with_retry_duration(Duration::from_secs(10))) +} + +/// Updates the chat completion with the new messages, streams the LLM tokens, +/// and report progress and errors. +#[allow(clippy::too_many_arguments)] +async fn run_conversation( + index_scheduler: &GuardedData< + ActionPolicy<{ actions::CHAT_COMPLETIONS }>, + Data, + >, + auth_ctrl: &web::Data, + search_queue: &web::Data, + auth_token: &str, + client: &Client, + chat_completion: &mut CreateChatCompletionRequest, + tx: &SseEventSender, + global_tool_calls: &mut HashMap, + function_support: FunctionSupport, +) -> Result, ()>, SendError> { + let mut finish_reason = None; + // safety: unwrap: can only happens if `stream` was set to `false` + let mut response = client.chat().create_stream(chat_completion.clone()).await.unwrap(); + while let Some(result) = response.next().await { + match result { + Ok(resp) => { + let choice = &resp.choices[0]; + finish_reason = choice.finish_reason; + + let ChatCompletionStreamResponseDelta { ref tool_calls, .. } = &choice.delta; + + match tool_calls { + Some(tool_calls) => { + for chunk in tool_calls { + let ChatCompletionMessageToolCallChunk { + index, + id, + r#type: _, + function, + } = chunk; + let FunctionCallStream { name, arguments } = function.as_ref().unwrap(); + + global_tool_calls + .entry(*index) + .and_modify(|call| { + if call.is_internal() { + call.append(arguments.as_ref().unwrap()) + } + }) + .or_insert_with(|| { + if name.as_deref() == Some(MEILI_SEARCH_IN_INDEX_FUNCTION_NAME) + { + Call::Internal { + id: id.as_ref().unwrap().clone(), + function_name: name.as_ref().unwrap().clone(), + arguments: arguments.as_ref().unwrap().clone(), + } + } else { + Call::External + } + }); + } + } + None => { + if !global_tool_calls.is_empty() { + let (meili_calls, _other_calls): (Vec<_>, Vec<_>) = + mem::take(global_tool_calls) + .into_values() + .flat_map(|call| match call { + Call::Internal { id, function_name: name, arguments } => { + Some(ChatCompletionMessageToolCall { + id, + r#type: Some(ChatCompletionToolType::Function), + function: FunctionCall { name, arguments }, + }) + } + Call::External => None, + }) + .partition(|call| { + call.function.name == MEILI_SEARCH_IN_INDEX_FUNCTION_NAME + }); + + chat_completion.messages.push( + ChatCompletionRequestAssistantMessageArgs::default() + .tool_calls(meili_calls.clone()) + .build() + .unwrap() + .into(), + ); + + handle_meili_tools( + index_scheduler, + auth_ctrl, + search_queue, + auth_token, + tx, + meili_calls, + chat_completion, + &resp, + function_support, + ) + .await?; + } else { + tx.forward_response(&resp).await?; + } + } + } + } + Err(error) => { + let error = StreamErrorEvent::from_openai_error(error).await.unwrap(); + tx.send_error(&error).await?; + return Ok(ControlFlow::Break(None)); + } + } + } + + // We must stop if the finish reason is not something we can solve with Meilisearch + match finish_reason { + Some(FinishReason::ToolCalls) => Ok(ControlFlow::Continue(())), + otherwise => Ok(ControlFlow::Break(otherwise)), + } +} + +#[allow(clippy::too_many_arguments)] +async fn handle_meili_tools( + index_scheduler: &GuardedData< + ActionPolicy<{ actions::CHAT_COMPLETIONS }>, + Data, + >, + auth_ctrl: &web::Data, + search_queue: &web::Data, + auth_token: &str, + tx: &SseEventSender, + meili_calls: Vec, + chat_completion: &mut CreateChatCompletionRequest, + resp: &CreateChatCompletionStreamResponse, + FunctionSupport { report_progress, report_sources, append_to_conversation, .. }: FunctionSupport, +) -> Result<(), SendError> { + for call in meili_calls { + if report_progress { + tx.report_search_progress( + resp.clone(), + &call.id, + &call.function.name, + &call.function.arguments, + ) + .await?; + } + + if append_to_conversation { + tx.append_tool_call_conversation_message( + resp.clone(), + call.id.clone(), + call.function.name.clone(), + call.function.arguments.clone(), + ) + .await?; + } + + let mut error = None; + + let result = match serde_json::from_str(&call.function.arguments) { + Ok(SearchInIndexParameters { index_uid, q }) => match process_search_request( + index_scheduler, + auth_ctrl.clone(), + search_queue, + auth_token, + index_uid, + q, + ) + .await + { + Ok(output) => Ok(output), + Err(err) => { + let error_text = format!("the search tool call failed with {err}"); + error = Some(err); + Err(error_text) + } + }, + Err(err) => Err(err.to_string()), + }; + + let answer = match result { + Ok((_index, documents, text)) => { + if report_sources { + tx.report_sources(resp.clone(), &call.id, &documents).await?; + } + text + } + Err(err) => err, + }; + + let tool = ChatCompletionRequestMessage::Tool(ChatCompletionRequestToolMessage { + tool_call_id: call.id.clone(), + content: ChatCompletionRequestToolMessageContent::Text(answer), + }); + + if append_to_conversation { + tx.append_conversation_message(resp.clone(), &tool).await?; + } + + chat_completion.messages.push(tool); + + if let Some(error) = error { + tx.send_error(&StreamErrorEvent::from_response_error(error)).await?; + } + } + + Ok(()) +} + +/// The structure used to aggregate the function calls to make. +#[derive(Debug)] +enum Call { + /// Tool calls to tools that must be managed by Meilisearch internally. + /// Typically the search functions. + Internal { id: String, function_name: String, arguments: String }, + /// Tool calls that we track but only to know that its not our functions. + /// We return the function calls as-is to the end-user. + External, +} + +impl Call { + fn is_internal(&self) -> bool { + matches!(self, Call::Internal { .. }) + } + + /// # Panics + /// + /// - if called on external calls + fn append(&mut self, more: &str) { + match self { + Call::Internal { arguments, .. } => arguments.push_str(more), + Call::External => panic!("Cannot append argument chunks to an external function"), + } + } +} + +#[derive(Deserialize)] +struct SearchInIndexParameters { + /// The index uid to search in. + index_uid: String, + /// The query parameter to use. + q: Option, +} diff --git a/crates/meilisearch/src/routes/chats/config.rs b/crates/meilisearch/src/routes/chats/config.rs new file mode 100644 index 000000000..182eff735 --- /dev/null +++ b/crates/meilisearch/src/routes/chats/config.rs @@ -0,0 +1,87 @@ +use async_openai::config::{AzureConfig, OpenAIConfig}; +use meilisearch_types::features::ChatCompletionSettings as DbChatSettings; +use reqwest::header::HeaderMap; +use secrecy::SecretString; + +#[derive(Debug, Clone)] +pub enum Config { + OpenAiCompatible(OpenAIConfig), + AzureOpenAiCompatible(AzureConfig), +} + +impl Config { + pub fn new(chat_settings: &DbChatSettings) -> Self { + use meilisearch_types::features::ChatCompletionSource::*; + match chat_settings.source { + OpenAi | Mistral | Gemini | VLlm => { + let mut config = OpenAIConfig::default(); + if let Some(org_id) = chat_settings.org_id.as_ref() { + config = config.with_org_id(org_id); + } + if let Some(project_id) = chat_settings.project_id.as_ref() { + config = config.with_project_id(project_id); + } + if let Some(api_key) = chat_settings.api_key.as_ref() { + config = config.with_api_key(api_key); + } + if let Some(base_url) = chat_settings.base_url.as_ref() { + config = config.with_api_base(base_url); + } + Self::OpenAiCompatible(config) + } + AzureOpenAi => { + let mut config = AzureConfig::default(); + if let Some(version) = chat_settings.api_version.as_ref() { + config = config.with_api_version(version); + } + if let Some(deployment_id) = chat_settings.deployment_id.as_ref() { + config = config.with_deployment_id(deployment_id); + } + if let Some(api_key) = chat_settings.api_key.as_ref() { + config = config.with_api_key(api_key); + } + if let Some(base_url) = chat_settings.base_url.as_ref() { + config = config.with_api_base(base_url); + } + Self::AzureOpenAiCompatible(config) + } + } + } +} + +impl async_openai::config::Config for Config { + fn headers(&self) -> HeaderMap { + match self { + Config::OpenAiCompatible(config) => config.headers(), + Config::AzureOpenAiCompatible(config) => config.headers(), + } + } + + fn url(&self, path: &str) -> String { + match self { + Config::OpenAiCompatible(config) => config.url(path), + Config::AzureOpenAiCompatible(config) => config.url(path), + } + } + + fn query(&self) -> Vec<(&str, &str)> { + match self { + Config::OpenAiCompatible(config) => config.query(), + Config::AzureOpenAiCompatible(config) => config.query(), + } + } + + fn api_base(&self) -> &str { + match self { + Config::OpenAiCompatible(config) => config.api_base(), + Config::AzureOpenAiCompatible(config) => config.api_base(), + } + } + + fn api_key(&self) -> &SecretString { + match self { + Config::OpenAiCompatible(config) => config.api_key(), + Config::AzureOpenAiCompatible(config) => config.api_key(), + } + } +} diff --git a/crates/meilisearch/src/routes/chats/errors.rs b/crates/meilisearch/src/routes/chats/errors.rs new file mode 100644 index 000000000..efa60ba50 --- /dev/null +++ b/crates/meilisearch/src/routes/chats/errors.rs @@ -0,0 +1,204 @@ +use async_openai::error::{ApiError, OpenAIError}; +use async_openai::reqwest_eventsource::Error as EventSourceError; +use meilisearch_types::error::ResponseError; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +#[derive(Debug, Clone, Deserialize)] +pub struct OpenAiOutsideError { + /// Emitted when an error occurs. + error: OpenAiInnerError, +} + +/// Emitted when an error occurs. +#[derive(Debug, Clone, Deserialize)] +pub struct OpenAiInnerError { + /// The error code. + code: Option, + /// The error message. + message: String, + /// The error parameter. + param: Option, + /// The type of the event. Always `error`. + r#type: String, +} + +/// An error that occurs during the streaming process. +/// +/// It directly comes from the OpenAI API and you can +/// read more about error events on their website: +/// +#[derive(Debug, Serialize, Deserialize)] +pub struct StreamErrorEvent { + /// The unique ID of the server event. + pub event_id: String, + /// The event type, must be error. + pub r#type: String, + /// Details of the error. + pub error: StreamError, +} + +/// Details of the error. +#[derive(Debug, Serialize, Deserialize)] +pub struct StreamError { + /// The type of error (e.g., "invalid_request_error", "server_error"). + pub r#type: String, + /// Error code, if any. + pub code: Option, + /// A human-readable error message. + pub message: String, + /// Parameter related to the error, if any. + pub param: Option, + /// The event_id of the client event that caused the error, if applicable. + pub event_id: Option, +} + +impl StreamErrorEvent { + const ERROR_TYPE: &str = "error"; + + pub async fn from_openai_error(error: OpenAIError) -> Result { + match error { + OpenAIError::Reqwest(e) => Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "internal_reqwest_error".to_string(), + code: Some("internal".to_string()), + message: e.to_string(), + param: None, + event_id: None, + }, + }), + OpenAIError::ApiError(ApiError { message, r#type, param, code }) => { + Ok(StreamErrorEvent { + r#type: Self::ERROR_TYPE.to_string(), + event_id: Uuid::new_v4().to_string(), + error: StreamError { + r#type: r#type.unwrap_or_else(|| "unknown".to_string()), + code, + message, + param, + event_id: None, + }, + }) + } + OpenAIError::JSONDeserialize(error) => Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "json_deserialize_error".to_string(), + code: Some("internal".to_string()), + message: error.to_string(), + param: None, + event_id: None, + }, + }), + OpenAIError::FileSaveError(_) | OpenAIError::FileReadError(_) => unreachable!(), + OpenAIError::StreamError(error) => match error { + EventSourceError::InvalidStatusCode(_status_code, response) => { + let OpenAiOutsideError { + error: OpenAiInnerError { code, message, param, r#type }, + } = response.json().await?; + + Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { r#type, code, message, param, event_id: None }, + }) + } + EventSourceError::InvalidContentType(_header_value, response) => { + let OpenAiOutsideError { + error: OpenAiInnerError { code, message, param, r#type }, + } = response.json().await?; + + Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { r#type, code, message, param, event_id: None }, + }) + } + EventSourceError::Utf8(error) => Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "invalid_utf8_error".to_string(), + code: None, + message: error.to_string(), + param: None, + event_id: None, + }, + }), + EventSourceError::Parser(error) => Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "parser_error".to_string(), + code: None, + message: error.to_string(), + param: None, + event_id: None, + }, + }), + EventSourceError::Transport(error) => Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "transport_error".to_string(), + code: None, + message: error.to_string(), + param: None, + event_id: None, + }, + }), + EventSourceError::InvalidLastEventId(message) => Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "invalid_last_event_id".to_string(), + code: None, + message, + param: None, + event_id: None, + }, + }), + EventSourceError::StreamEnded => Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "stream_ended".to_string(), + code: None, + message: "Stream ended".to_string(), + param: None, + event_id: None, + }, + }), + }, + OpenAIError::InvalidArgument(message) => Ok(StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "invalid_argument".to_string(), + code: None, + message, + param: None, + event_id: None, + }, + }), + } + } + + pub fn from_response_error(error: ResponseError) -> Self { + let ResponseError { code, message, .. } = error; + StreamErrorEvent { + event_id: Uuid::new_v4().to_string(), + r#type: Self::ERROR_TYPE.to_string(), + error: StreamError { + r#type: "response_error".to_string(), + code: Some(code.as_str().to_string()), + message, + param: None, + event_id: None, + }, + } + } +} diff --git a/crates/meilisearch/src/routes/chats/mod.rs b/crates/meilisearch/src/routes/chats/mod.rs new file mode 100644 index 000000000..a8a93e6a4 --- /dev/null +++ b/crates/meilisearch/src/routes/chats/mod.rs @@ -0,0 +1,134 @@ +use actix_web::web::{self, Data}; +use actix_web::HttpResponse; +use deserr::actix_web::AwebQueryParameter; +use deserr::Deserr; +use index_scheduler::IndexScheduler; +use meilisearch_types::deserr::query_params::Param; +use meilisearch_types::deserr::DeserrQueryParamError; +use meilisearch_types::error::deserr_codes::{InvalidIndexLimit, InvalidIndexOffset}; +use meilisearch_types::error::{Code, ResponseError}; +use meilisearch_types::index_uid::IndexUid; +use meilisearch_types::keys::actions; +use serde::{Deserialize, Serialize}; +use serde_json::json; +use tracing::debug; +use utoipa::{IntoParams, ToSchema}; + +use super::Pagination; +use crate::extractors::authentication::policies::ActionPolicy; +use crate::extractors::authentication::GuardedData; +use crate::routes::PAGINATION_DEFAULT_LIMIT; + +pub mod chat_completions; +mod config; +mod errors; +pub mod settings; +mod utils; + +/// The function name to report search progress. +/// This function is used to report on what meilisearch is +/// doing which must be used on the frontend to report progress. +const MEILI_SEARCH_PROGRESS_NAME: &str = "_meiliSearchProgress"; +/// The function name to append a conversation message in the user conversation. +/// This function is used to append a conversation message in the user conversation. +/// This must be used on the frontend to keep context of what happened on the +/// Meilisearch-side and keep good context for follow up questions. +const MEILI_APPEND_CONVERSATION_MESSAGE_NAME: &str = "_meiliAppendConversationMessage"; +/// The function name to report sources to the frontend. +/// This function is used to report sources to the frontend. +/// The call id is associated to the one used by the search progress function. +const MEILI_SEARCH_SOURCES_NAME: &str = "_meiliSearchSources"; +/// The *internal* function name to provide to the LLM to search in indexes. +/// This function must not leak to the user as the LLM will call it and the +/// main goal of Meilisearch is to provide an answer to these calls. +const MEILI_SEARCH_IN_INDEX_FUNCTION_NAME: &str = "_meiliSearchInIndex"; + +#[derive(Deserialize)] +pub struct ChatsParam { + workspace_uid: String, +} + +pub fn configure(cfg: &mut web::ServiceConfig) { + cfg.service(web::resource("").route(web::get().to(list_workspaces))).service( + web::scope("/{workspace_uid}") + .service( + web::resource("") + .route(web::get().to(get_chat)) + .route(web::delete().to(delete_chat)), + ) + .service(web::scope("/chat/completions").configure(chat_completions::configure)) + .service(web::scope("/settings").configure(settings::configure)), + ); +} + +pub async fn get_chat( + index_scheduler: GuardedData, Data>, + workspace_uid: web::Path, +) -> Result { + index_scheduler.features().check_chat_completions("displaying a chat")?; + + let workspace_uid = IndexUid::try_from(workspace_uid.into_inner())?; + if index_scheduler.chat_workspace_exists(&workspace_uid)? { + Ok(HttpResponse::Ok().json(json!({ "uid": workspace_uid }))) + } else { + Err(ResponseError::from_msg(format!("chat {workspace_uid} not found"), Code::ChatNotFound)) + } +} + +pub async fn delete_chat( + index_scheduler: GuardedData, Data>, + workspace_uid: web::Path, +) -> Result { + index_scheduler.features().check_chat_completions("deleting a chat")?; + + let workspace_uid = workspace_uid.into_inner(); + if index_scheduler.delete_chat_settings(&workspace_uid)? { + Ok(HttpResponse::NoContent().finish()) + } else { + Err(ResponseError::from_msg(format!("chat {workspace_uid} not found"), Code::ChatNotFound)) + } +} + +#[derive(Deserr, Debug, Clone, Copy, IntoParams)] +#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)] +#[into_params(rename_all = "camelCase", parameter_in = Query)] +pub struct ListChats { + /// The number of chat workspaces to skip before starting to retrieve anything + #[param(value_type = Option, default, example = 100)] + #[deserr(default, error = DeserrQueryParamError)] + pub offset: Param, + /// The number of chat workspaces to retrieve + #[param(value_type = Option, default = 20, example = 1)] + #[deserr(default = Param(PAGINATION_DEFAULT_LIMIT), error = DeserrQueryParamError)] + pub limit: Param, +} + +impl ListChats { + fn as_pagination(self) -> Pagination { + Pagination { offset: self.offset.0, limit: self.limit.0 } + } +} + +#[derive(Debug, Serialize, Clone, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ChatWorkspaceView { + /// Unique identifier for the index + pub uid: String, +} + +pub async fn list_workspaces( + index_scheduler: GuardedData, Data>, + paginate: AwebQueryParameter, +) -> Result { + index_scheduler.features().check_chat_completions("listing the chats")?; + + debug!(parameters = ?paginate, "List chat workspaces"); + let (total, workspaces) = + index_scheduler.paginated_chat_workspace_uids(*paginate.offset, *paginate.limit)?; + let workspaces = + workspaces.into_iter().map(|uid| ChatWorkspaceView { uid }).collect::>(); + let ret = paginate.as_pagination().format_with(total, workspaces); + + debug!(returns = ?ret, "List chat workspaces"); + Ok(HttpResponse::Ok().json(ret)) +} diff --git a/crates/meilisearch/src/routes/chats/settings.rs b/crates/meilisearch/src/routes/chats/settings.rs new file mode 100644 index 000000000..28611ee98 --- /dev/null +++ b/crates/meilisearch/src/routes/chats/settings.rs @@ -0,0 +1,260 @@ +use actix_web::web::{self, Data}; +use actix_web::HttpResponse; +use deserr::Deserr; +use index_scheduler::IndexScheduler; +use meilisearch_types::deserr::DeserrJsonError; +use meilisearch_types::error::deserr_codes::*; +use meilisearch_types::error::{Code, ResponseError}; +use meilisearch_types::features::{ + ChatCompletionPrompts as DbChatCompletionPrompts, ChatCompletionSettings, + ChatCompletionSource as DbChatCompletionSource, DEFAULT_CHAT_SEARCH_DESCRIPTION_PROMPT, + DEFAULT_CHAT_SEARCH_INDEX_UID_PARAM_PROMPT, DEFAULT_CHAT_SEARCH_Q_PARAM_PROMPT, + DEFAULT_CHAT_SYSTEM_PROMPT, +}; +use meilisearch_types::keys::actions; +use meilisearch_types::milli::update::Setting; +use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; + +use super::ChatsParam; +use crate::extractors::authentication::policies::ActionPolicy; +use crate::extractors::authentication::GuardedData; +use crate::extractors::sequential_extractor::SeqHandler; + +pub fn configure(cfg: &mut web::ServiceConfig) { + cfg.service( + web::resource("") + .route(web::get().to(SeqHandler(get_settings))) + .route(web::patch().to(SeqHandler(patch_settings))) + .route(web::delete().to(SeqHandler(reset_settings))), + ); +} + +async fn get_settings( + index_scheduler: GuardedData< + ActionPolicy<{ actions::CHATS_SETTINGS_GET }>, + Data, + >, + chats_param: web::Path, +) -> Result { + index_scheduler.features().check_chat_completions("using the /chats/settings route")?; + + let ChatsParam { workspace_uid } = chats_param.into_inner(); + + let mut settings = match index_scheduler.chat_settings(&workspace_uid)? { + Some(settings) => settings, + None => { + return Err(ResponseError::from_msg( + format!("Chat `{workspace_uid}` not found"), + Code::ChatNotFound, + )) + } + }; + settings.hide_secrets(); + Ok(HttpResponse::Ok().json(settings)) +} + +async fn patch_settings( + index_scheduler: GuardedData< + ActionPolicy<{ actions::CHATS_SETTINGS_UPDATE }>, + Data, + >, + chats_param: web::Path, + web::Json(new): web::Json, +) -> Result { + index_scheduler.features().check_chat_completions("using the /chats/settings route")?; + let ChatsParam { workspace_uid } = chats_param.into_inner(); + + let old_settings = index_scheduler.chat_settings(&workspace_uid)?.unwrap_or_default(); + + let prompts = match new.prompts { + Setting::Set(new_prompts) => DbChatCompletionPrompts { + system: match new_prompts.system { + Setting::Set(new_system) => new_system, + Setting::Reset => DEFAULT_CHAT_SYSTEM_PROMPT.to_string(), + Setting::NotSet => old_settings.prompts.system, + }, + search_description: match new_prompts.search_description { + Setting::Set(new_description) => new_description, + Setting::Reset => DEFAULT_CHAT_SEARCH_DESCRIPTION_PROMPT.to_string(), + Setting::NotSet => old_settings.prompts.search_description, + }, + search_q_param: match new_prompts.search_q_param { + Setting::Set(new_description) => new_description, + Setting::Reset => DEFAULT_CHAT_SEARCH_Q_PARAM_PROMPT.to_string(), + Setting::NotSet => old_settings.prompts.search_q_param, + }, + search_index_uid_param: match new_prompts.search_index_uid_param { + Setting::Set(new_description) => new_description, + Setting::Reset => DEFAULT_CHAT_SEARCH_INDEX_UID_PARAM_PROMPT.to_string(), + Setting::NotSet => old_settings.prompts.search_index_uid_param, + }, + }, + Setting::Reset => DbChatCompletionPrompts::default(), + Setting::NotSet => old_settings.prompts, + }; + + let mut settings = ChatCompletionSettings { + source: match new.source { + Setting::Set(new_source) => new_source.into(), + Setting::Reset => DbChatCompletionSource::default(), + Setting::NotSet => old_settings.source, + }, + org_id: match new.org_id { + Setting::Set(new_org_id) => Some(new_org_id), + Setting::Reset => None, + Setting::NotSet => old_settings.org_id, + }, + project_id: match new.project_id { + Setting::Set(new_project_id) => Some(new_project_id), + Setting::Reset => None, + Setting::NotSet => old_settings.project_id, + }, + api_version: match new.api_version { + Setting::Set(new_api_version) => Some(new_api_version), + Setting::Reset => None, + Setting::NotSet => old_settings.api_version, + }, + deployment_id: match new.deployment_id { + Setting::Set(new_deployment_id) => Some(new_deployment_id), + Setting::Reset => None, + Setting::NotSet => old_settings.deployment_id, + }, + base_url: match new.base_url { + Setting::Set(new_base_url) => Some(new_base_url), + Setting::Reset => None, + Setting::NotSet => old_settings.base_url, + }, + api_key: match new.api_key { + Setting::Set(new_api_key) => Some(new_api_key), + Setting::Reset => None, + Setting::NotSet => old_settings.api_key, + }, + prompts, + }; + + // TODO send analytics + // analytics.publish( + // PatchNetworkAnalytics { + // network_size: merged_remotes.len(), + // network_has_self: merged_self.is_some(), + // }, + // &req, + // ); + + settings.validate()?; + index_scheduler.put_chat_settings(&workspace_uid, &settings)?; + + settings.hide_secrets(); + + Ok(HttpResponse::Ok().json(settings)) +} + +async fn reset_settings( + index_scheduler: GuardedData< + ActionPolicy<{ actions::CHATS_SETTINGS_UPDATE }>, + Data, + >, + chats_param: web::Path, +) -> Result { + index_scheduler.features().check_chat_completions("using the /chats/settings route")?; + + let ChatsParam { workspace_uid } = chats_param.into_inner(); + if index_scheduler.chat_settings(&workspace_uid)?.is_some() { + let settings = Default::default(); + index_scheduler.put_chat_settings(&workspace_uid, &settings)?; + Ok(HttpResponse::Ok().json(settings)) + } else { + Err(ResponseError::from_msg( + format!("Chat `{workspace_uid}` not found"), + Code::ChatNotFound, + )) + } +} + +#[derive(Debug, Clone, Deserialize, Deserr, ToSchema)] +#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +#[schema(rename_all = "camelCase")] +pub struct ChatWorkspaceSettings { + #[serde(default)] + #[deserr(default)] + #[schema(value_type = Option)] + pub source: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("dcba4321..."))] + pub org_id: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("4321dcba..."))] + pub project_id: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("2024-02-01"))] + pub api_version: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("1234abcd..."))] + pub deployment_id: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("https://api.mistral.ai/v1"))] + pub base_url: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("abcd1234..."))] + pub api_key: Setting, + #[serde(default)] + #[deserr(default)] + #[schema(inline, value_type = Option)] + pub prompts: Setting, +} + +#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize, Deserr, ToSchema)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] +pub enum ChatCompletionSource { + #[default] + OpenAi, + Mistral, + Gemini, + AzureOpenAi, + VLlm, +} + +impl From for DbChatCompletionSource { + fn from(source: ChatCompletionSource) -> Self { + use ChatCompletionSource::*; + match source { + OpenAi => DbChatCompletionSource::OpenAi, + Mistral => DbChatCompletionSource::Mistral, + Gemini => DbChatCompletionSource::Gemini, + AzureOpenAi => DbChatCompletionSource::AzureOpenAi, + VLlm => DbChatCompletionSource::VLlm, + } + } +} + +#[derive(Debug, Clone, Deserialize, Deserr, ToSchema)] +#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +#[schema(rename_all = "camelCase")] +pub struct ChatPrompts { + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("You are a helpful assistant..."))] + pub system: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("This is the search function..."))] + pub search_description: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("This is query parameter..."))] + pub search_q_param: Setting, + #[serde(default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(value_type = Option, example = json!("This is index you want to search in..."))] + pub search_index_uid_param: Setting, +} diff --git a/crates/meilisearch/src/routes/chats/utils.rs b/crates/meilisearch/src/routes/chats/utils.rs new file mode 100644 index 000000000..61961bd4b --- /dev/null +++ b/crates/meilisearch/src/routes/chats/utils.rs @@ -0,0 +1,253 @@ +use std::cell::RefCell; +use std::sync::RwLock; + +use actix_web_lab::sse::{self, Event}; +use async_openai::types::{ + ChatChoiceStream, ChatCompletionMessageToolCall, ChatCompletionMessageToolCallChunk, + ChatCompletionRequestAssistantMessage, ChatCompletionRequestMessage, + ChatCompletionStreamResponseDelta, ChatCompletionToolType, CreateChatCompletionStreamResponse, + FunctionCall, FunctionCallStream, Role, +}; +use bumpalo::Bump; +use meilisearch_types::error::{Code, ResponseError}; +use meilisearch_types::heed::RoTxn; +use meilisearch_types::milli::index::ChatConfig; +use meilisearch_types::milli::prompt::{Prompt, PromptData}; +use meilisearch_types::milli::update::new::document::DocumentFromDb; +use meilisearch_types::milli::{ + DocumentId, FieldIdMapWithMetadata, GlobalFieldsIdsMap, MetadataBuilder, +}; +use meilisearch_types::{Document, Index}; +use serde::Serialize; +use tokio::sync::mpsc::error::SendError; +use tokio::sync::mpsc::Sender; + +use super::errors::StreamErrorEvent; +use super::MEILI_APPEND_CONVERSATION_MESSAGE_NAME; +use crate::routes::chats::{MEILI_SEARCH_PROGRESS_NAME, MEILI_SEARCH_SOURCES_NAME}; + +pub struct SseEventSender(Sender); + +impl SseEventSender { + pub fn new(sender: Sender) -> Self { + Self(sender) + } + + /// Ask the front-end user to append this tool *call* to the conversation + pub async fn append_tool_call_conversation_message( + &self, + resp: CreateChatCompletionStreamResponse, + call_id: String, + function_name: String, + function_arguments: String, + ) -> Result<(), SendError> { + #[allow(deprecated)] // function_call + let message = + ChatCompletionRequestMessage::Assistant(ChatCompletionRequestAssistantMessage { + content: None, + refusal: None, + name: None, + audio: None, + tool_calls: Some(vec![ChatCompletionMessageToolCall { + id: call_id, + r#type: Some(ChatCompletionToolType::Function), + function: FunctionCall { name: function_name, arguments: function_arguments }, + }]), + function_call: None, + }); + + self.append_conversation_message(resp, &message).await + } + + /// Ask the front-end user to append this tool to the conversation + pub async fn append_conversation_message( + &self, + mut resp: CreateChatCompletionStreamResponse, + message: &ChatCompletionRequestMessage, + ) -> Result<(), SendError> { + let call_text = serde_json::to_string(message).unwrap(); + let tool_call = ChatCompletionMessageToolCallChunk { + index: 0, + id: Some(uuid::Uuid::new_v4().to_string()), + r#type: Some(ChatCompletionToolType::Function), + function: Some(FunctionCallStream { + name: Some(MEILI_APPEND_CONVERSATION_MESSAGE_NAME.to_string()), + arguments: Some(call_text), + }), + }; + + resp.choices[0] = ChatChoiceStream { + index: 0, + #[allow(deprecated)] // function_call + delta: ChatCompletionStreamResponseDelta { + content: None, + function_call: None, + tool_calls: Some(vec![tool_call]), + role: Some(Role::Assistant), + refusal: None, + }, + finish_reason: None, + logprobs: None, + }; + + self.send_json(&resp).await + } + + pub async fn report_search_progress( + &self, + mut resp: CreateChatCompletionStreamResponse, + call_id: &str, + function_name: &str, + function_arguments: &str, + ) -> Result<(), SendError> { + #[derive(Debug, Clone, Serialize)] + /// Provides information about the current Meilisearch search operation. + struct MeiliSearchProgress<'a> { + /// The call ID to track the sources of the search. + call_id: &'a str, + /// The name of the function we are executing. + function_name: &'a str, + /// The arguments of the function we are executing, encoded in JSON. + function_arguments: &'a str, + } + + let progress = MeiliSearchProgress { call_id, function_name, function_arguments }; + let call_text = serde_json::to_string(&progress).unwrap(); + let tool_call = ChatCompletionMessageToolCallChunk { + index: 0, + id: Some(uuid::Uuid::new_v4().to_string()), + r#type: Some(ChatCompletionToolType::Function), + function: Some(FunctionCallStream { + name: Some(MEILI_SEARCH_PROGRESS_NAME.to_string()), + arguments: Some(call_text), + }), + }; + + resp.choices[0] = ChatChoiceStream { + index: 0, + #[allow(deprecated)] // function_call + delta: ChatCompletionStreamResponseDelta { + content: None, + function_call: None, + tool_calls: Some(vec![tool_call]), + role: Some(Role::Assistant), + refusal: None, + }, + finish_reason: None, + logprobs: None, + }; + + self.send_json(&resp).await + } + + pub async fn report_sources( + &self, + mut resp: CreateChatCompletionStreamResponse, + call_id: &str, + documents: &[Document], + ) -> Result<(), SendError> { + #[derive(Debug, Clone, Serialize)] + /// Provides sources of the search. + struct MeiliSearchSources<'a> { + /// The call ID to track the original search associated to those sources. + call_id: &'a str, + /// The documents associated with the search (call_id). + /// Only the displayed attributes of the documents are returned. + sources: &'a [Document], + } + + let sources = MeiliSearchSources { call_id, sources: documents }; + let call_text = serde_json::to_string(&sources).unwrap(); + let tool_call = ChatCompletionMessageToolCallChunk { + index: 0, + id: Some(uuid::Uuid::new_v4().to_string()), + r#type: Some(ChatCompletionToolType::Function), + function: Some(FunctionCallStream { + name: Some(MEILI_SEARCH_SOURCES_NAME.to_string()), + arguments: Some(call_text), + }), + }; + + resp.choices[0] = ChatChoiceStream { + index: 0, + #[allow(deprecated)] // function_call + delta: ChatCompletionStreamResponseDelta { + content: None, + function_call: None, + tool_calls: Some(vec![tool_call]), + role: Some(Role::Assistant), + refusal: None, + }, + finish_reason: None, + logprobs: None, + }; + + self.send_json(&resp).await + } + + pub async fn forward_response( + &self, + resp: &CreateChatCompletionStreamResponse, + ) -> Result<(), SendError> { + self.send_json(resp).await + } + + pub async fn send_error(&self, error: &StreamErrorEvent) -> Result<(), SendError> { + self.send_json(error).await + } + + pub async fn stop(self) -> Result<(), SendError> { + // It is the way OpenAI sends a correct end of stream + // + const DONE_DATA: &str = "[DONE]"; + self.0.send(Event::Data(sse::Data::new(DONE_DATA))).await + } + + async fn send_json(&self, data: &S) -> Result<(), SendError> { + self.0.send(Event::Data(sse::Data::new_json(data).unwrap())).await + } +} + +/// Format documents based on the provided template and maximum bytes. +/// +/// This formatting function is usually used to generate a summary of the documents for LLMs. +pub fn format_documents<'doc>( + rtxn: &RoTxn<'_>, + index: &Index, + doc_alloc: &'doc Bump, + internal_docids: Vec, +) -> Result, ResponseError> { + let ChatConfig { prompt: PromptData { template, max_bytes }, .. } = index.chat_config(rtxn)?; + + let prompt = Prompt::new(template, max_bytes).unwrap(); + let fid_map = index.fields_ids_map(rtxn)?; + let metadata_builder = MetadataBuilder::from_index(index, rtxn)?; + let fid_map_with_meta = FieldIdMapWithMetadata::new(fid_map.clone(), metadata_builder); + let global = RwLock::new(fid_map_with_meta); + let gfid_map = RefCell::new(GlobalFieldsIdsMap::new(&global)); + + let external_ids: Vec = index + .external_id_of(rtxn, internal_docids.iter().copied())? + .into_iter() + .collect::>()?; + + let mut renders = Vec::new(); + for (docid, external_docid) in internal_docids.into_iter().zip(external_ids) { + let document = match DocumentFromDb::new(docid, rtxn, index, &fid_map)? { + Some(doc) => doc, + None => unreachable!("Document with internal ID {docid} not found"), + }; + let text = match prompt.render_document(&external_docid, document, &gfid_map, doc_alloc) { + Ok(text) => text, + Err(err) => { + return Err(ResponseError::from_msg( + err.to_string(), + Code::InvalidChatSettingDocumentTemplate, + )) + } + }; + renders.push(text); + } + + Ok(renders) +} diff --git a/crates/meilisearch/src/routes/features.rs b/crates/meilisearch/src/routes/features.rs index eb8e7ac04..179b9cf68 100644 --- a/crates/meilisearch/src/routes/features.rs +++ b/crates/meilisearch/src/routes/features.rs @@ -53,6 +53,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) { network: Some(false), get_task_documents_route: Some(false), composite_embedders: Some(false), + chat_completions: Some(false), })), (status = 401, description = "The authorization header is missing", body = ResponseError, content_type = "application/json", example = json!( { @@ -97,6 +98,8 @@ pub struct RuntimeTogglableFeatures { pub get_task_documents_route: Option, #[deserr(default)] pub composite_embedders: Option, + #[deserr(default)] + pub chat_completions: Option, } impl From for RuntimeTogglableFeatures { @@ -109,6 +112,7 @@ impl From for RuntimeTogg network, get_task_documents_route, composite_embedders, + chat_completions, } = value; Self { @@ -119,6 +123,7 @@ impl From for RuntimeTogg network: Some(network), get_task_documents_route: Some(get_task_documents_route), composite_embedders: Some(composite_embedders), + chat_completions: Some(chat_completions), } } } @@ -132,6 +137,7 @@ pub struct PatchExperimentalFeatureAnalytics { network: bool, get_task_documents_route: bool, composite_embedders: bool, + chat_completions: bool, } impl Aggregate for PatchExperimentalFeatureAnalytics { @@ -148,6 +154,7 @@ impl Aggregate for PatchExperimentalFeatureAnalytics { network: new.network, get_task_documents_route: new.get_task_documents_route, composite_embedders: new.composite_embedders, + chat_completions: new.chat_completions, }) } @@ -173,6 +180,7 @@ impl Aggregate for PatchExperimentalFeatureAnalytics { network: Some(false), get_task_documents_route: Some(false), composite_embedders: Some(false), + chat_completions: Some(false), })), (status = 401, description = "The authorization header is missing", body = ResponseError, content_type = "application/json", example = json!( { @@ -214,6 +222,7 @@ async fn patch_features( .0 .composite_embedders .unwrap_or(old_features.composite_embedders), + chat_completions: new_features.0.chat_completions.unwrap_or(old_features.chat_completions), }; // explicitly destructure for analytics rather than using the `Serialize` implementation, because @@ -227,6 +236,7 @@ async fn patch_features( network, get_task_documents_route, composite_embedders, + chat_completions, } = new_features; analytics.publish( @@ -238,6 +248,7 @@ async fn patch_features( network, get_task_documents_route, composite_embedders, + chat_completions, }, &req, ); diff --git a/crates/meilisearch/src/routes/indexes/mod.rs b/crates/meilisearch/src/routes/indexes/mod.rs index 48ed1cfb1..04b3e12c4 100644 --- a/crates/meilisearch/src/routes/indexes/mod.rs +++ b/crates/meilisearch/src/routes/indexes/mod.rs @@ -172,7 +172,7 @@ pub async fn list_indexes( debug!(parameters = ?paginate, "List indexes"); let filters = index_scheduler.filters(); let (total, indexes) = - index_scheduler.get_paginated_indexes_stats(filters, *paginate.offset, *paginate.limit)?; + index_scheduler.paginated_indexes_stats(filters, *paginate.offset, *paginate.limit)?; let indexes = indexes .into_iter() .map(|(name, stats)| IndexView { diff --git a/crates/meilisearch/src/routes/indexes/settings.rs b/crates/meilisearch/src/routes/indexes/settings.rs index 92b018c8c..a4b7a5219 100644 --- a/crates/meilisearch/src/routes/indexes/settings.rs +++ b/crates/meilisearch/src/routes/indexes/settings.rs @@ -5,8 +5,9 @@ use index_scheduler::IndexScheduler; use meilisearch_types::deserr::DeserrJsonError; use meilisearch_types::error::ResponseError; use meilisearch_types::index_uid::IndexUid; +use meilisearch_types::milli::update::Setting; use meilisearch_types::settings::{ - settings, SecretPolicy, SettingEmbeddingSettings, Settings, Unchecked, + settings, ChatSettings, SecretPolicy, SettingEmbeddingSettings, Settings, Unchecked, }; use meilisearch_types::tasks::KindWithContent; use tracing::debug; @@ -508,6 +509,17 @@ make_setting_routes!( camelcase_attr: "prefixSearch", analytics: PrefixSearchAnalytics }, + { + route: "/chat", + update_verb: put, + value_type: ChatSettings, + err_type: meilisearch_types::deserr::DeserrJsonError< + meilisearch_types::error::deserr_codes::InvalidSettingsIndexChat, + >, + attr: chat, + camelcase_attr: "chat", + analytics: ChatAnalytics + }, ); #[utoipa::path( @@ -597,6 +609,7 @@ pub async fn update_all( ), facet_search: FacetSearchAnalytics::new(new_settings.facet_search.as_ref().set()), prefix_search: PrefixSearchAnalytics::new(new_settings.prefix_search.as_ref().set()), + chat: ChatAnalytics::new(new_settings.chat.as_ref().set()), }, &req, ); @@ -651,7 +664,11 @@ pub async fn get_all( let index = index_scheduler.index(&index_uid)?; let rtxn = index.read_txn()?; - let new_settings = settings(&index, &rtxn, SecretPolicy::HideSecrets)?; + let mut new_settings = settings(&index, &rtxn, SecretPolicy::HideSecrets)?; + if index_scheduler.features().check_chat_completions("showing index `chat` settings").is_err() { + new_settings.chat = Setting::NotSet; + } + debug!(returns = ?new_settings, "Get all settings"); Ok(HttpResponse::Ok().json(new_settings)) } @@ -741,5 +758,9 @@ fn validate_settings( } } + if let Setting::Set(_chat) = &settings.chat { + features.check_chat_completions("setting `chat` in the index settings")?; + } + Ok(settings.validate()?) } diff --git a/crates/meilisearch/src/routes/indexes/settings_analytics.rs b/crates/meilisearch/src/routes/indexes/settings_analytics.rs index 41df91966..1b8d0e244 100644 --- a/crates/meilisearch/src/routes/indexes/settings_analytics.rs +++ b/crates/meilisearch/src/routes/indexes/settings_analytics.rs @@ -10,8 +10,8 @@ use meilisearch_types::locales::{Locale, LocalizedAttributesRuleView}; use meilisearch_types::milli::update::Setting; use meilisearch_types::milli::FilterableAttributesRule; use meilisearch_types::settings::{ - FacetingSettings, PaginationSettings, PrefixSearchSettings, ProximityPrecisionView, - RankingRuleView, SettingEmbeddingSettings, TypoSettings, + ChatSettings, FacetingSettings, PaginationSettings, PrefixSearchSettings, + ProximityPrecisionView, RankingRuleView, SettingEmbeddingSettings, TypoSettings, }; use serde::Serialize; @@ -39,6 +39,7 @@ pub struct SettingsAnalytics { pub non_separator_tokens: NonSeparatorTokensAnalytics, pub facet_search: FacetSearchAnalytics, pub prefix_search: PrefixSearchAnalytics, + pub chat: ChatAnalytics, } impl Aggregate for SettingsAnalytics { @@ -198,6 +199,7 @@ impl Aggregate for SettingsAnalytics { set: new.prefix_search.set | self.prefix_search.set, value: new.prefix_search.value.or(self.prefix_search.value), }, + chat: ChatAnalytics { set: new.chat.set | self.chat.set }, }) } @@ -676,3 +678,18 @@ impl PrefixSearchAnalytics { SettingsAnalytics { prefix_search: self, ..Default::default() } } } + +#[derive(Serialize, Default)] +pub struct ChatAnalytics { + pub set: bool, +} + +impl ChatAnalytics { + pub fn new(settings: Option<&ChatSettings>) -> Self { + Self { set: settings.is_some() } + } + + pub fn into_settings(self) -> SettingsAnalytics { + SettingsAnalytics { chat: self, ..Default::default() } + } +} diff --git a/crates/meilisearch/src/routes/mod.rs b/crates/meilisearch/src/routes/mod.rs index 2c71fa68b..cc62e43c3 100644 --- a/crates/meilisearch/src/routes/mod.rs +++ b/crates/meilisearch/src/routes/mod.rs @@ -52,6 +52,7 @@ const PAGINATION_DEFAULT_LIMIT_FN: fn() -> usize = || 20; mod api_key; pub mod batches; +pub mod chats; mod dump; pub mod features; pub mod indexes; @@ -113,7 +114,8 @@ pub fn configure(cfg: &mut web::ServiceConfig) { .service(web::scope("/swap-indexes").configure(swap_indexes::configure)) .service(web::scope("/metrics").configure(metrics::configure)) .service(web::scope("/experimental-features").configure(features::configure)) - .service(web::scope("/network").configure(network::configure)); + .service(web::scope("/network").configure(network::configure)) + .service(web::scope("/chats").configure(chats::configure)); #[cfg(feature = "swagger")] { diff --git a/crates/meilisearch/src/search/mod.rs b/crates/meilisearch/src/search/mod.rs index 1dd16c474..5e543c53f 100644 --- a/crates/meilisearch/src/search/mod.rs +++ b/crates/meilisearch/src/search/mod.rs @@ -16,6 +16,7 @@ use meilisearch_types::error::{Code, ResponseError}; use meilisearch_types::heed::RoTxn; use meilisearch_types::index_uid::IndexUid; use meilisearch_types::locales::Locale; +use meilisearch_types::milli::index::{self, SearchParameters}; use meilisearch_types::milli::score_details::{ScoreDetails, ScoringStrategy}; use meilisearch_types::milli::vector::parsed_vectors::ExplicitVectors; use meilisearch_types::milli::vector::Embedder; @@ -119,9 +120,58 @@ pub struct SearchQuery { pub locales: Option>, } +impl From for SearchQuery { + fn from(parameters: SearchParameters) -> Self { + let SearchParameters { + hybrid, + limit, + sort, + distinct, + matching_strategy, + attributes_to_search_on, + ranking_score_threshold, + } = parameters; + + SearchQuery { + hybrid: hybrid.map(|index::HybridQuery { semantic_ratio, embedder }| HybridQuery { + semantic_ratio: SemanticRatio::try_from(semantic_ratio) + .ok() + .unwrap_or_else(DEFAULT_SEMANTIC_RATIO), + embedder, + }), + limit: limit.unwrap_or_else(DEFAULT_SEARCH_LIMIT), + sort, + distinct, + matching_strategy: matching_strategy.map(MatchingStrategy::from).unwrap_or_default(), + attributes_to_search_on, + ranking_score_threshold: ranking_score_threshold.map(RankingScoreThreshold::from), + q: None, + vector: None, + offset: DEFAULT_SEARCH_OFFSET(), + page: None, + hits_per_page: None, + attributes_to_retrieve: None, + retrieve_vectors: false, + attributes_to_crop: None, + crop_length: DEFAULT_CROP_LENGTH(), + attributes_to_highlight: None, + show_matches_position: false, + show_ranking_score: false, + show_ranking_score_details: false, + filter: None, + facets: None, + highlight_pre_tag: DEFAULT_HIGHLIGHT_PRE_TAG(), + highlight_post_tag: DEFAULT_HIGHLIGHT_POST_TAG(), + crop_marker: DEFAULT_CROP_MARKER(), + locales: None, + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Deserr, ToSchema, Serialize)] #[deserr(try_from(f64) = TryFrom::try_from -> InvalidSearchRankingScoreThreshold)] pub struct RankingScoreThreshold(f64); + impl std::convert::TryFrom for RankingScoreThreshold { type Error = InvalidSearchRankingScoreThreshold; @@ -136,6 +186,14 @@ impl std::convert::TryFrom for RankingScoreThreshold { } } +impl From for RankingScoreThreshold { + fn from(threshold: index::RankingScoreThreshold) -> Self { + let threshold = threshold.as_f64(); + assert!((0.0..=1.0).contains(&threshold)); + RankingScoreThreshold(threshold) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Deserr)] #[deserr(try_from(f64) = TryFrom::try_from -> InvalidSimilarRankingScoreThreshold)] pub struct RankingScoreThresholdSimilar(f64); @@ -279,8 +337,8 @@ impl fmt::Debug for SearchQuery { #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] #[serde(rename_all = "camelCase")] pub struct HybridQuery { - #[deserr(default, error = DeserrJsonError, default)] - #[schema(value_type = f32, default)] + #[deserr(default, error = DeserrJsonError)] + #[schema(default, value_type = f32)] #[serde(default)] pub semantic_ratio: SemanticRatio, #[deserr(error = DeserrJsonError)] @@ -717,6 +775,16 @@ impl From for TermsMatchingStrategy { } } +impl From for MatchingStrategy { + fn from(other: index::MatchingStrategy) -> Self { + match other { + index::MatchingStrategy::Last => Self::Last, + index::MatchingStrategy::All => Self::All, + index::MatchingStrategy::Frequency => Self::Frequency, + } + } +} + #[derive(Debug, Default, Clone, PartialEq, Eq, Deserr)] #[deserr(rename_all = camelCase)] pub enum FacetValuesSort { @@ -882,7 +950,7 @@ pub fn add_search_rules(filter: &mut Option, rules: IndexSearchRules) { } } -fn prepare_search<'t>( +pub fn prepare_search<'t>( index: &'t Index, rtxn: &'t RoTxn, query: &'t SearchQuery, @@ -1260,7 +1328,7 @@ struct HitMaker<'a> { vectors_fid: Option, retrieve_vectors: RetrieveVectors, to_retrieve_ids: BTreeSet, - embedding_configs: Vec, + embedding_configs: Vec, formatter_builder: MatcherBuilder<'a>, formatted_options: BTreeMap, show_ranking_score: bool, diff --git a/crates/meilisearch/tests/auth/api_keys.rs b/crates/meilisearch/tests/auth/api_keys.rs index 0aea7d722..84ed24217 100644 --- a/crates/meilisearch/tests/auth/api_keys.rs +++ b/crates/meilisearch/tests/auth/api_keys.rs @@ -421,7 +421,7 @@ async fn error_add_api_key_invalid_parameters_actions() { meili_snap::snapshot!(code, @"400 Bad Request"); meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###" { - "message": "Unknown value `doc.add` at `.actions[0]`: expected one of `*`, `search`, `documents.*`, `documents.add`, `documents.get`, `documents.delete`, `indexes.*`, `indexes.create`, `indexes.get`, `indexes.update`, `indexes.delete`, `indexes.swap`, `tasks.*`, `tasks.cancel`, `tasks.delete`, `tasks.get`, `settings.*`, `settings.get`, `settings.update`, `stats.*`, `stats.get`, `metrics.*`, `metrics.get`, `dumps.*`, `dumps.create`, `snapshots.*`, `snapshots.create`, `version`, `keys.create`, `keys.get`, `keys.update`, `keys.delete`, `experimental.get`, `experimental.update`, `network.get`, `network.update`", + "message": "Unknown value `doc.add` at `.actions[0]`: expected one of `*`, `search`, `documents.*`, `documents.add`, `documents.get`, `documents.delete`, `indexes.*`, `indexes.create`, `indexes.get`, `indexes.update`, `indexes.delete`, `indexes.swap`, `tasks.*`, `tasks.cancel`, `tasks.delete`, `tasks.get`, `settings.*`, `settings.get`, `settings.update`, `stats.*`, `stats.get`, `metrics.*`, `metrics.get`, `dumps.*`, `dumps.create`, `snapshots.*`, `snapshots.create`, `version`, `keys.create`, `keys.get`, `keys.update`, `keys.delete`, `experimental.get`, `experimental.update`, `network.get`, `network.update`, `chatCompletions`, `chats.*`, `chats.get`, `chats.delete`, `chatsSettings.*`, `chatsSettings.get`, `chatsSettings.update`", "code": "invalid_api_key_actions", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_api_key_actions" @@ -849,11 +849,27 @@ async fn list_api_keys() { "expiresAt": null, "createdAt": "[ignored]", "updatedAt": "[ignored]" + }, + { + "name": "Default Chat API Key", + "description": "Use it to chat and search from the frontend", + "key": "[ignored]", + "uid": "[ignored]", + "actions": [ + "chatCompletions", + "search" + ], + "indexes": [ + "*" + ], + "expiresAt": null, + "createdAt": "[ignored]", + "updatedAt": "[ignored]" } ], "offset": 0, "limit": 20, - "total": 3 + "total": 4 } "###); meili_snap::snapshot!(code, @"200 OK"); diff --git a/crates/meilisearch/tests/auth/errors.rs b/crates/meilisearch/tests/auth/errors.rs index 0e8968ef0..ebe2e53fa 100644 --- a/crates/meilisearch/tests/auth/errors.rs +++ b/crates/meilisearch/tests/auth/errors.rs @@ -93,7 +93,7 @@ async fn create_api_key_bad_actions() { snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Unknown value `doggo` at `.actions[0]`: expected one of `*`, `search`, `documents.*`, `documents.add`, `documents.get`, `documents.delete`, `indexes.*`, `indexes.create`, `indexes.get`, `indexes.update`, `indexes.delete`, `indexes.swap`, `tasks.*`, `tasks.cancel`, `tasks.delete`, `tasks.get`, `settings.*`, `settings.get`, `settings.update`, `stats.*`, `stats.get`, `metrics.*`, `metrics.get`, `dumps.*`, `dumps.create`, `snapshots.*`, `snapshots.create`, `version`, `keys.create`, `keys.get`, `keys.update`, `keys.delete`, `experimental.get`, `experimental.update`, `network.get`, `network.update`", + "message": "Unknown value `doggo` at `.actions[0]`: expected one of `*`, `search`, `documents.*`, `documents.add`, `documents.get`, `documents.delete`, `indexes.*`, `indexes.create`, `indexes.get`, `indexes.update`, `indexes.delete`, `indexes.swap`, `tasks.*`, `tasks.cancel`, `tasks.delete`, `tasks.get`, `settings.*`, `settings.get`, `settings.update`, `stats.*`, `stats.get`, `metrics.*`, `metrics.get`, `dumps.*`, `dumps.create`, `snapshots.*`, `snapshots.create`, `version`, `keys.create`, `keys.get`, `keys.update`, `keys.delete`, `experimental.get`, `experimental.update`, `network.get`, `network.update`, `chatCompletions`, `chats.*`, `chats.get`, `chats.delete`, `chatsSettings.*`, `chatsSettings.get`, `chatsSettings.update`", "code": "invalid_api_key_actions", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_api_key_actions" diff --git a/crates/meilisearch/tests/dumps/mod.rs b/crates/meilisearch/tests/dumps/mod.rs index 3ba3c20eb..3d3bc01db 100644 --- a/crates/meilisearch/tests/dumps/mod.rs +++ b/crates/meilisearch/tests/dumps/mod.rs @@ -2187,7 +2187,8 @@ async fn import_dump_v6_containing_experimental_features() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); @@ -2312,7 +2313,8 @@ async fn import_dump_v6_containing_batches_and_enqueued_tasks() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); @@ -2417,7 +2419,8 @@ async fn generate_and_import_dump_containing_vectors() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); diff --git a/crates/meilisearch/tests/features/mod.rs b/crates/meilisearch/tests/features/mod.rs index 34cd40e38..d0d457d3e 100644 --- a/crates/meilisearch/tests/features/mod.rs +++ b/crates/meilisearch/tests/features/mod.rs @@ -24,7 +24,8 @@ async fn experimental_features() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); @@ -39,7 +40,8 @@ async fn experimental_features() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); @@ -54,7 +56,8 @@ async fn experimental_features() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); @@ -70,7 +73,8 @@ async fn experimental_features() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); @@ -86,7 +90,8 @@ async fn experimental_features() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); } @@ -109,7 +114,8 @@ async fn experimental_feature_metrics() { "containsFilter": false, "network": false, "getTaskDocumentsRoute": false, - "compositeEmbedders": false + "compositeEmbedders": false, + "chatCompletions": false } "###); @@ -156,7 +162,7 @@ async fn errors() { meili_snap::snapshot!(code, @"400 Bad Request"); meili_snap::snapshot!(meili_snap::json_string!(response), @r###" { - "message": "Unknown field `NotAFeature`: expected one of `metrics`, `logsRoute`, `editDocumentsByFunction`, `containsFilter`, `network`, `getTaskDocumentsRoute`, `compositeEmbedders`", + "message": "Unknown field `NotAFeature`: expected one of `metrics`, `logsRoute`, `editDocumentsByFunction`, `containsFilter`, `network`, `getTaskDocumentsRoute`, `compositeEmbedders`, `chatCompletions`", "code": "bad_request", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#bad_request" diff --git a/crates/meilisearch/tests/index/get_index.rs b/crates/meilisearch/tests/index/get_index.rs index a436b649b..b07b7821b 100644 --- a/crates/meilisearch/tests/index/get_index.rs +++ b/crates/meilisearch/tests/index/get_index.rs @@ -1,8 +1,8 @@ -use crate::json; use meili_snap::{json_string, snapshot}; use serde_json::Value; use crate::common::{shared_does_not_exists_index, Server}; +use crate::json; #[actix_rt::test] async fn create_and_get_index() { diff --git a/crates/meilisearch/tests/search/errors.rs b/crates/meilisearch/tests/search/errors.rs index 2b63a07b1..7490544bf 100644 --- a/crates/meilisearch/tests/search/errors.rs +++ b/crates/meilisearch/tests/search/errors.rs @@ -1,10 +1,9 @@ use meili_snap::*; +use super::test_settings_documents_indexing_swapping_and_search; use crate::common::{shared_does_not_exists_index, Server, DOCUMENTS, NESTED_DOCUMENTS}; use crate::json; -use super::test_settings_documents_indexing_swapping_and_search; - #[actix_rt::test] async fn search_unexisting_index() { let index = shared_does_not_exists_index().await; diff --git a/crates/meilisearch/tests/search/filters.rs b/crates/meilisearch/tests/search/filters.rs index 4219d2ec1..ec80eb63e 100644 --- a/crates/meilisearch/tests/search/filters.rs +++ b/crates/meilisearch/tests/search/filters.rs @@ -3,10 +3,10 @@ use meilisearch::Opt; use tempfile::TempDir; use super::test_settings_documents_indexing_swapping_and_search; -use crate::{ - common::{default_settings, shared_index_with_documents, Server, DOCUMENTS, NESTED_DOCUMENTS}, - json, +use crate::common::{ + default_settings, shared_index_with_documents, Server, DOCUMENTS, NESTED_DOCUMENTS, }; +use crate::json; #[actix_rt::test] async fn search_with_filter_string_notation() { diff --git a/crates/meilisearch/tests/search/geo.rs b/crates/meilisearch/tests/search/geo.rs index a314ca241..eda02e440 100644 --- a/crates/meilisearch/tests/search/geo.rs +++ b/crates/meilisearch/tests/search/geo.rs @@ -2,11 +2,10 @@ use meili_snap::{json_string, snapshot}; use meilisearch_types::milli::constants::RESERVED_GEO_FIELD_NAME; use once_cell::sync::Lazy; +use super::test_settings_documents_indexing_swapping_and_search; use crate::common::{Server, Value}; use crate::json; -use super::test_settings_documents_indexing_swapping_and_search; - static DOCUMENTS: Lazy = Lazy::new(|| { json!([ { diff --git a/crates/meilisearch/tests/settings/get_settings.rs b/crates/meilisearch/tests/settings/get_settings.rs index 5c0f89ed3..e4c58cbcd 100644 --- a/crates/meilisearch/tests/settings/get_settings.rs +++ b/crates/meilisearch/tests/settings/get_settings.rs @@ -181,6 +181,16 @@ test_setting_routes!( update_verb: patch, default_value: {"enabled": true, "minWordSizeForTypos": {"oneTypo": 5, "twoTypos": 9}, "disableOnWords": [], "disableOnAttributes": [], "disableOnNumbers": false} }, + { + setting: chat, + update_verb: put, + default_value: { + "description": "", + "documentTemplate": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }}\n{% endif %}{% endfor %}", + "documentTemplateMaxBytes": 400, + "searchParameters": {} + } + }, ); #[actix_rt::test] diff --git a/crates/milli/src/database_stats.rs b/crates/milli/src/database_stats.rs index 7da1fbd2b..381408621 100644 --- a/crates/milli/src/database_stats.rs +++ b/crates/milli/src/database_stats.rs @@ -1,9 +1,6 @@ use std::mem; -use heed::Database; -use heed::DatabaseStat; -use heed::RoTxn; -use heed::Unspecified; +use heed::{Database, DatabaseStat, RoTxn, Unspecified}; use serde::{Deserialize, Serialize}; use crate::BEU32; diff --git a/crates/milli/src/disabled_typos_terms.rs b/crates/milli/src/disabled_typos_terms.rs index 7ae35f828..c5acad7cd 100644 --- a/crates/milli/src/disabled_typos_terms.rs +++ b/crates/milli/src/disabled_typos_terms.rs @@ -1,10 +1,9 @@ -use heed::{ - types::{SerdeJson, Str}, - RoTxn, RwTxn, -}; +use heed::types::{SerdeJson, Str}; +use heed::{RoTxn, RwTxn}; use serde::{Deserialize, Serialize}; -use crate::{index::main_key, Index}; +use crate::index::main_key; +use crate::Index; #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)] #[serde(rename_all = "camelCase")] diff --git a/crates/milli/src/error.rs b/crates/milli/src/error.rs index 237a895d3..2136ec97e 100644 --- a/crates/milli/src/error.rs +++ b/crates/milli/src/error.rs @@ -1,5 +1,4 @@ -use std::collections::BTreeSet; -use std::collections::HashMap; +use std::collections::{BTreeSet, HashMap}; use std::convert::Infallible; use std::fmt::Write; use std::{io, str}; @@ -387,6 +386,8 @@ and can not be more than 511 bytes.", .document_id.to_string() DocumentEditionRuntimeError(Box), #[error("Document edition runtime error encountered while compiling the function: {0}")] DocumentEditionCompilationError(rhai::ParseError), + #[error("`.chat.documentTemplateMaxBytes`: `documentTemplateMaxBytes` cannot be zero")] + InvalidChatSettingsDocumentTemplateMaxBytes, #[error("{0}")] DocumentEmbeddingError(String), } diff --git a/crates/milli/src/external_documents_ids.rs b/crates/milli/src/external_documents_ids.rs index 755b801ec..598465e5f 100644 --- a/crates/milli/src/external_documents_ids.rs +++ b/crates/milli/src/external_documents_ids.rs @@ -32,13 +32,13 @@ impl ExternalDocumentsIds { &self, rtxn: &RoTxn<'_>, external_id: A, - ) -> heed::Result> { + ) -> heed::Result> { self.0.get(rtxn, external_id.as_ref()) } /// An helper function to debug this type, returns an `HashMap` of both, /// soft and hard fst maps, combined. - pub fn to_hash_map(&self, rtxn: &RoTxn<'_>) -> heed::Result> { + pub fn to_hash_map(&self, rtxn: &RoTxn<'_>) -> heed::Result> { let mut map = HashMap::default(); for result in self.0.iter(rtxn)? { let (external, internal) = result?; diff --git a/crates/milli/src/fields_ids_map.rs b/crates/milli/src/fields_ids_map.rs index 9a016e7bd..d2abd840c 100644 --- a/crates/milli/src/fields_ids_map.rs +++ b/crates/milli/src/fields_ids_map.rs @@ -7,6 +7,7 @@ use crate::FieldId; mod global; pub mod metadata; pub use global::GlobalFieldsIdsMap; +pub use metadata::{FieldIdMapWithMetadata, MetadataBuilder}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FieldsIdsMap { diff --git a/crates/milli/src/filterable_attributes_rules.rs b/crates/milli/src/filterable_attributes_rules.rs index 53af30fd6..ae1a9755a 100644 --- a/crates/milli/src/filterable_attributes_rules.rs +++ b/crates/milli/src/filterable_attributes_rules.rs @@ -1,13 +1,12 @@ +use std::collections::{BTreeSet, HashSet}; + use deserr::{DeserializeError, Deserr, ValuePointerRef}; use serde::{Deserialize, Serialize}; -use std::collections::{BTreeSet, HashSet}; use utoipa::ToSchema; -use crate::{ - attribute_patterns::{match_distinct_field, match_field_legacy, PatternMatch}, - constants::RESERVED_GEO_FIELD_NAME, - AttributePatterns, -}; +use crate::attribute_patterns::{match_distinct_field, match_field_legacy, PatternMatch}; +use crate::constants::RESERVED_GEO_FIELD_NAME; +use crate::AttributePatterns; #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, ToSchema)] #[serde(untagged)] diff --git a/crates/milli/src/index.rs b/crates/milli/src/index.rs index d0cd5c862..e9e63a853 100644 --- a/crates/milli/src/index.rs +++ b/crates/milli/src/index.rs @@ -1,14 +1,18 @@ use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; +use std::error::Error; +use std::fmt; use std::fs::File; use std::path::Path; +use deserr::Deserr; use heed::types::*; use heed::{CompactionOption, Database, DatabaseStat, RoTxn, RwTxn, Unspecified, WithoutTls}; use indexmap::IndexMap; use roaring::RoaringBitmap; use rstar::RTree; use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; use crate::constants::{self, RESERVED_GEO_FIELD_NAME, RESERVED_VECTORS_FIELD_NAME}; use crate::database_stats::DatabaseStats; @@ -23,7 +27,9 @@ use crate::heed_codec::facet::{ use crate::heed_codec::version::VersionCodec; use crate::heed_codec::{BEU16StrCodec, FstSetCodec, StrBEU16Codec, StrRefCodec}; use crate::order_by_map::OrderByMap; +use crate::prompt::PromptData; use crate::proximity::ProximityPrecision; +use crate::update::new::StdResult; use crate::vector::{ArroyStats, ArroyWrapper, Embedding, EmbeddingConfig}; use crate::{ default_criteria, CboRoaringBitmapCodec, Criterion, DocumentId, ExternalDocumentsIds, @@ -79,6 +85,7 @@ pub mod main_key { pub const PREFIX_SEARCH: &str = "prefix_search"; pub const DOCUMENTS_STATS: &str = "documents_stats"; pub const DISABLED_TYPOS_TERMS: &str = "disabled_typos_terms"; + pub const CHAT: &str = "chat"; } pub mod db_name { @@ -1691,6 +1698,25 @@ impl Index { self.main.remap_key_type::().delete(txn, main_key::FACET_SEARCH) } + pub fn chat_config(&self, txn: &RoTxn<'_>) -> heed::Result { + self.main + .remap_types::>() + .get(txn, main_key::CHAT) + .map(|o| o.unwrap_or_default()) + } + + pub(crate) fn put_chat_config( + &self, + txn: &mut RwTxn<'_>, + val: &ChatConfig, + ) -> heed::Result<()> { + self.main.remap_types::>().put(txn, main_key::CHAT, &val) + } + + pub(crate) fn delete_chat_config(&self, txn: &mut RwTxn<'_>) -> heed::Result { + self.main.remap_key_type::().delete(txn, main_key::CHAT) + } + pub fn localized_attributes_rules( &self, rtxn: &RoTxn<'_>, @@ -1917,13 +1943,99 @@ pub struct IndexEmbeddingConfig { pub user_provided: RoaringBitmap, } +#[derive(Debug, Default, Deserialize, Serialize)] +pub struct ChatConfig { + pub description: String, + /// Contains the document template and max template length. + pub prompt: PromptData, + pub search_parameters: SearchParameters, +} + +#[derive(Debug, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SearchParameters { + #[serde(skip_serializing_if = "Option::is_none")] + pub hybrid: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub sort: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub distinct: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub matching_strategy: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub attributes_to_search_on: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub ranking_score_threshold: Option, +} + +#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Deserr, ToSchema)] +#[deserr(try_from(f64) = TryFrom::try_from -> InvalidSettingsRankingScoreThreshold)] +pub struct RankingScoreThreshold(f64); + +impl RankingScoreThreshold { + pub fn as_f64(&self) -> f64 { + self.0 + } +} + +impl TryFrom for RankingScoreThreshold { + type Error = InvalidSettingsRankingScoreThreshold; + + fn try_from(value: f64) -> StdResult { + if !(0.0..=1.0).contains(&value) { + Err(InvalidSettingsRankingScoreThreshold) + } else { + Ok(RankingScoreThreshold(value)) + } + } +} + +#[derive(Debug)] +pub struct InvalidSettingsRankingScoreThreshold; + +impl Error for InvalidSettingsRankingScoreThreshold {} + +impl fmt::Display for InvalidSettingsRankingScoreThreshold { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "the value of `rankingScoreThreshold` is invalid, expected a float between `0.0` and `1.0`." + ) + } +} + +#[derive(Debug, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct HybridQuery { + pub semantic_ratio: f32, + pub embedder: String, +} + #[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] pub struct PrefixSettings { pub prefix_count_threshold: usize, pub max_prefix_length: usize, pub compute_prefixes: PrefixSearch, } +/// This is unfortunately a duplication of the struct in . +/// The reason why it is duplicated is because milli cannot depend on meilisearch. It would be cyclic imports. +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Deserr, ToSchema, Serialize, Deserialize)] +#[deserr(rename_all = camelCase)] +#[serde(rename_all = "camelCase")] +pub enum MatchingStrategy { + /// Remove query words from last to first + #[default] + Last, + /// All query words are mandatory + All, + /// Remove query words from the most frequent to the least + Frequency, +} + #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)] #[serde(rename_all = "camelCase")] pub enum PrefixSearch { diff --git a/crates/milli/src/lib.rs b/crates/milli/src/lib.rs index 47d3dc75c..504b4c68d 100644 --- a/crates/milli/src/lib.rs +++ b/crates/milli/src/lib.rs @@ -52,18 +52,19 @@ pub use search::new::{ }; use serde_json::Value; pub use thread_pool_no_abort::{PanicCatched, ThreadPoolNoAbort, ThreadPoolNoAbortBuilder}; -pub use {charabia as tokenizer, heed, rhai}; +pub use {arroy, charabia as tokenizer, heed, rhai}; pub use self::asc_desc::{AscDesc, AscDescError, Member, SortError}; -pub use self::attribute_patterns::AttributePatterns; -pub use self::attribute_patterns::PatternMatch; +pub use self::attribute_patterns::{AttributePatterns, PatternMatch}; pub use self::criterion::{default_criteria, Criterion, CriterionError}; pub use self::error::{ Error, FieldIdMapMissingEntry, InternalError, SerializationError, UserError, }; pub use self::external_documents_ids::ExternalDocumentsIds; pub use self::fieldids_weights_map::FieldidsWeightsMap; -pub use self::fields_ids_map::{FieldsIdsMap, GlobalFieldsIdsMap}; +pub use self::fields_ids_map::{ + FieldIdMapWithMetadata, FieldsIdsMap, GlobalFieldsIdsMap, MetadataBuilder, +}; pub use self::filterable_attributes_rules::{ FilterFeatures, FilterableAttributesFeatures, FilterableAttributesPatterns, FilterableAttributesRule, @@ -84,8 +85,6 @@ pub use self::search::{ }; pub use self::update::ChannelCongestion; -pub use arroy; - pub type Result = std::result::Result; pub type Attribute = u32; diff --git a/crates/milli/src/progress.rs b/crates/milli/src/progress.rs index 75dafa8ec..fa651e17f 100644 --- a/crates/milli/src/progress.rs +++ b/crates/milli/src/progress.rs @@ -1,4 +1,3 @@ -use enum_iterator::Sequence; use std::any::TypeId; use std::borrow::Cow; use std::marker::PhantomData; @@ -6,6 +5,7 @@ use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::{Arc, RwLock}; use std::time::{Duration, Instant}; +use enum_iterator::Sequence; use indexmap::IndexMap; use itertools::Itertools; use serde::Serialize; diff --git a/crates/milli/src/prompt/mod.rs b/crates/milli/src/prompt/mod.rs index d40fcd27f..a8288f83d 100644 --- a/crates/milli/src/prompt/mod.rs +++ b/crates/milli/src/prompt/mod.rs @@ -64,7 +64,7 @@ fn default_template() -> liquid::Template { new_template(default_template_text()).unwrap() } -fn default_template_text() -> &'static str { +pub fn default_template_text() -> &'static str { "{% for field in fields %}\ {% if field.is_searchable and field.value != nil %}\ {{ field.name }}: {{ field.value }}\n\ diff --git a/crates/milli/src/search/mod.rs b/crates/milli/src/search/mod.rs index 37b1aaf09..62183afc3 100644 --- a/crates/milli/src/search/mod.rs +++ b/crates/milli/src/search/mod.rs @@ -10,6 +10,7 @@ pub use self::facet::{FacetDistribution, Filter, OrderBy, DEFAULT_VALUES_PER_FAC pub use self::new::matches::{FormatOptions, MatchBounds, MatcherBuilder, MatchingWords}; use self::new::{execute_vector_search, PartialSearchResult, VectorStoreStats}; use crate::filterable_attributes_rules::{filtered_matching_patterns, matching_features}; +use crate::index::MatchingStrategy; use crate::score_details::{ScoreDetails, ScoringStrategy}; use crate::vector::Embedder; use crate::{ @@ -364,6 +365,16 @@ impl Default for TermsMatchingStrategy { } } +impl From for TermsMatchingStrategy { + fn from(other: MatchingStrategy) -> Self { + match other { + MatchingStrategy::Last => Self::Last, + MatchingStrategy::All => Self::All, + MatchingStrategy::Frequency => Self::Frequency, + } + } +} + fn get_first(s: &str) -> &str { match s.chars().next() { Some(c) => &s[..c.len_utf8()], diff --git a/crates/milli/src/search/new/geo_sort.rs b/crates/milli/src/search/new/geo_sort.rs index 663599553..3e7fe3458 100644 --- a/crates/milli/src/search/new/geo_sort.rs +++ b/crates/milli/src/search/new/geo_sort.rs @@ -1,8 +1,9 @@ +use std::collections::VecDeque; + use heed::types::{Bytes, Unit}; use heed::{RoPrefix, RoTxn}; use roaring::RoaringBitmap; use rstar::RTree; -use std::collections::VecDeque; use super::facet_string_values; use super::ranking_rules::{RankingRule, RankingRuleOutput, RankingRuleQueryTrait}; diff --git a/crates/milli/src/search/new/mod.rs b/crates/milli/src/search/new/mod.rs index 6e794ef53..86d0816ba 100644 --- a/crates/milli/src/search/new/mod.rs +++ b/crates/milli/src/search/new/mod.rs @@ -47,8 +47,7 @@ use sort::Sort; use self::distinct::facet_string_values; use self::geo_sort::GeoSort; -pub use self::geo_sort::Parameter as GeoSortParameter; -pub use self::geo_sort::Strategy as GeoSortStrategy; +pub use self::geo_sort::{Parameter as GeoSortParameter, Strategy as GeoSortStrategy}; use self::graph_based_ranking_rule::Words; use self::interner::Interned; use self::vector_sort::VectorSort; diff --git a/crates/milli/src/update/chat.rs b/crates/milli/src/update/chat.rs new file mode 100644 index 000000000..2f364894d --- /dev/null +++ b/crates/milli/src/update/chat.rs @@ -0,0 +1,182 @@ +use std::error::Error; +use std::fmt; + +use deserr::errors::JsonError; +use deserr::Deserr; +use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; + +use crate::index::{self, ChatConfig, MatchingStrategy, RankingScoreThreshold, SearchParameters}; +use crate::prompt::{default_max_bytes, PromptData}; +use crate::update::Setting; + +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Deserr, ToSchema)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +#[deserr(error = JsonError, deny_unknown_fields, rename_all = camelCase)] +pub struct ChatSettings { + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option)] + pub description: Setting, + + /// A liquid template used to render documents to a text that can be embedded. + /// + /// Meillisearch interpolates the template for each document and sends the resulting text to the embedder. + /// The embedder then generates document vectors based on this text. + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option)] + pub document_template: Setting, + + /// Rendered texts are truncated to this size. Defaults to 400. + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option)] + pub document_template_max_bytes: Setting, + + /// The search parameters to use for the LLM. + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option)] + pub search_parameters: Setting, +} + +impl From for ChatSettings { + fn from(config: ChatConfig) -> Self { + let ChatConfig { + description, + prompt: PromptData { template, max_bytes }, + search_parameters, + } = config; + ChatSettings { + description: Setting::Set(description), + document_template: Setting::Set(template), + document_template_max_bytes: Setting::Set( + max_bytes.unwrap_or(default_max_bytes()).get(), + ), + search_parameters: Setting::Set({ + let SearchParameters { + hybrid, + limit, + sort, + distinct, + matching_strategy, + attributes_to_search_on, + ranking_score_threshold, + } = search_parameters; + + let hybrid = hybrid.map(|index::HybridQuery { semantic_ratio, embedder }| { + HybridQuery { semantic_ratio: SemanticRatio(semantic_ratio), embedder } + }); + + ChatSearchParams { + hybrid: Setting::some_or_not_set(hybrid), + limit: Setting::some_or_not_set(limit), + sort: Setting::some_or_not_set(sort), + distinct: Setting::some_or_not_set(distinct), + matching_strategy: Setting::some_or_not_set(matching_strategy), + attributes_to_search_on: Setting::some_or_not_set(attributes_to_search_on), + ranking_score_threshold: Setting::some_or_not_set(ranking_score_threshold), + } + }), + } + } +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Deserr, ToSchema)] +#[serde(deny_unknown_fields, rename_all = "camelCase")] +#[deserr(error = JsonError, deny_unknown_fields, rename_all = camelCase)] +pub struct ChatSearchParams { + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option)] + pub hybrid: Setting, + + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default = Setting::Set(20))] + #[schema(value_type = Option)] + pub limit: Setting, + + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option>)] + pub sort: Setting>, + + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option)] + pub distinct: Setting, + + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option)] + pub matching_strategy: Setting, + + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option>)] + pub attributes_to_search_on: Setting>, + + #[serde(default, skip_serializing_if = "Setting::is_not_set")] + #[deserr(default)] + #[schema(value_type = Option)] + pub ranking_score_threshold: Setting, +} + +#[derive(Debug, Clone, Default, Deserr, ToSchema, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[deserr(error = JsonError, rename_all = camelCase, deny_unknown_fields)] +pub struct HybridQuery { + #[deserr(default)] + #[serde(default)] + #[schema(default, value_type = f32)] + pub semantic_ratio: SemanticRatio, + #[schema(value_type = String)] + pub embedder: String, +} + +#[derive(Debug, Clone, Copy, Deserr, ToSchema, PartialEq, Serialize, Deserialize)] +#[deserr(try_from(f32) = TryFrom::try_from -> InvalidSearchSemanticRatio)] +pub struct SemanticRatio(f32); + +impl Default for SemanticRatio { + fn default() -> Self { + SemanticRatio(0.5) + } +} + +impl std::convert::TryFrom for SemanticRatio { + type Error = InvalidSearchSemanticRatio; + + fn try_from(f: f32) -> Result { + // the suggested "fix" is: `!(0.0..=1.0).contains(&f)`` which is allegedly less readable + #[allow(clippy::manual_range_contains)] + if f > 1.0 || f < 0.0 { + Err(InvalidSearchSemanticRatio) + } else { + Ok(SemanticRatio(f)) + } + } +} + +#[derive(Debug)] +pub struct InvalidSearchSemanticRatio; + +impl Error for InvalidSearchSemanticRatio {} + +impl fmt::Display for InvalidSearchSemanticRatio { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "the value of `semanticRatio` is invalid, expected a float between `0.0` and `1.0`." + ) + } +} + +impl std::ops::Deref for SemanticRatio { + type Target = f32; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/crates/milli/src/update/mod.rs b/crates/milli/src/update/mod.rs index 9a783ffd2..5acb00113 100644 --- a/crates/milli/src/update/mod.rs +++ b/crates/milli/src/update/mod.rs @@ -1,4 +1,5 @@ pub use self::available_ids::AvailableIds; +pub use self::chat::ChatSettings; pub use self::clear_documents::ClearDocuments; pub use self::concurrent_available_ids::ConcurrentAvailableIds; pub use self::facet::bulk::FacetsUpdateBulk; @@ -13,6 +14,7 @@ pub use self::words_prefix_integer_docids::WordPrefixIntegerDocids; pub use self::words_prefixes_fst::WordsPrefixesFst; mod available_ids; +mod chat; mod clear_documents; mod concurrent_available_ids; pub(crate) mod del_add; diff --git a/crates/milli/src/update/new/extract/faceted/facet_document.rs b/crates/milli/src/update/new/extract/faceted/facet_document.rs index e74131402..ff15f146d 100644 --- a/crates/milli/src/update/new/extract/faceted/facet_document.rs +++ b/crates/milli/src/update/new/extract/faceted/facet_document.rs @@ -4,6 +4,7 @@ use serde_json::Value; use crate::attribute_patterns::PatternMatch; use crate::fields_ids_map::metadata::Metadata; +use crate::filterable_attributes_rules::match_faceted_field; use crate::update::new::document::Document; use crate::update::new::extract::geo::extract_geo_coordinates; use crate::update::new::extract::perm_json_p; @@ -11,8 +12,6 @@ use crate::{ FieldId, FilterableAttributesRule, GlobalFieldsIdsMap, InternalError, Result, UserError, }; -use crate::filterable_attributes_rules::match_faceted_field; - #[allow(clippy::too_many_arguments)] pub fn extract_document_facets<'doc>( document: impl Document<'doc>, diff --git a/crates/milli/src/update/new/extract/mod.rs b/crates/milli/src/update/new/extract/mod.rs index a8264ba4a..2abefb098 100644 --- a/crates/milli/src/update/new/extract/mod.rs +++ b/crates/milli/src/update/new/extract/mod.rs @@ -18,7 +18,8 @@ pub use vectors::EmbeddingExtractor; pub mod perm_json_p { use serde_json::{Map, Value}; - use crate::{attribute_patterns::PatternMatch, Result}; + use crate::attribute_patterns::PatternMatch; + use crate::Result; const SPLIT_SYMBOL: char = '.'; /// Returns `true` if the `selector` match the `key`. diff --git a/crates/milli/src/update/settings.rs b/crates/milli/src/update/settings.rs index fce2989b1..05607d7a5 100644 --- a/crates/milli/src/update/settings.rs +++ b/crates/milli/src/update/settings.rs @@ -11,22 +11,23 @@ use roaring::RoaringBitmap; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use time::OffsetDateTime; +use super::chat::ChatSearchParams; use super::del_add::{DelAdd, DelAddOperation}; use super::index_documents::{IndexDocumentsConfig, Transform}; -use super::IndexerConfig; +use super::{ChatSettings, IndexerConfig}; use crate::attribute_patterns::PatternMatch; use crate::constants::RESERVED_GEO_FIELD_NAME; use crate::criterion::Criterion; use crate::disabled_typos_terms::DisabledTyposTerms; -use crate::error::UserError; +use crate::error::UserError::{self, InvalidChatSettingsDocumentTemplateMaxBytes}; use crate::fields_ids_map::metadata::{FieldIdMapWithMetadata, MetadataBuilder}; use crate::filterable_attributes_rules::match_faceted_field; use crate::index::{ - IndexEmbeddingConfig, PrefixSearch, DEFAULT_MIN_WORD_LEN_ONE_TYPO, - DEFAULT_MIN_WORD_LEN_TWO_TYPOS, + ChatConfig, IndexEmbeddingConfig, PrefixSearch, SearchParameters, + DEFAULT_MIN_WORD_LEN_ONE_TYPO, DEFAULT_MIN_WORD_LEN_TWO_TYPOS, }; use crate::order_by_map::OrderByMap; -use crate::prompt::default_max_bytes; +use crate::prompt::{default_max_bytes, default_template_text, PromptData}; use crate::proximity::ProximityPrecision; use crate::update::index_documents::IndexDocumentsMethod; use crate::update::{IndexDocuments, UpdateIndexingStep}; @@ -185,6 +186,7 @@ pub struct Settings<'a, 't, 'i> { localized_attributes_rules: Setting>, prefix_search: Setting, facet_search: Setting, + chat: Setting, } impl<'a, 't, 'i> Settings<'a, 't, 'i> { @@ -223,6 +225,7 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> { localized_attributes_rules: Setting::NotSet, prefix_search: Setting::NotSet, facet_search: Setting::NotSet, + chat: Setting::NotSet, indexer_config, } } @@ -453,6 +456,14 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> { self.facet_search = Setting::Reset; } + pub fn set_chat(&mut self, value: ChatSettings) { + self.chat = Setting::Set(value); + } + + pub fn reset_chat(&mut self) { + self.chat = Setting::Reset; + } + #[tracing::instrument( level = "trace" skip(self, progress_callback, should_abort, settings_diff), @@ -1238,6 +1249,112 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> { Ok(()) } + fn update_chat_config(&mut self) -> Result { + match &mut self.chat { + Setting::Set(ChatSettings { + description: new_description, + document_template: new_document_template, + document_template_max_bytes: new_document_template_max_bytes, + search_parameters: new_search_parameters, + }) => { + let ChatConfig { description, prompt, search_parameters } = + self.index.chat_config(self.wtxn)?; + + let description = match new_description { + Setting::Set(new) => new.clone(), + Setting::Reset => Default::default(), + Setting::NotSet => description, + }; + + let prompt = PromptData { + template: match new_document_template { + Setting::Set(new) => new.clone(), + Setting::Reset => default_template_text().to_string(), + Setting::NotSet => prompt.template.clone(), + }, + max_bytes: match new_document_template_max_bytes { + Setting::Set(m) => Some( + NonZeroUsize::new(*m) + .ok_or(InvalidChatSettingsDocumentTemplateMaxBytes)?, + ), + Setting::Reset => Some(default_max_bytes()), + Setting::NotSet => prompt.max_bytes, + }, + }; + + let search_parameters = match new_search_parameters { + Setting::Set(sp) => { + let ChatSearchParams { + hybrid, + limit, + sort, + distinct, + matching_strategy, + attributes_to_search_on, + ranking_score_threshold, + } = sp; + + SearchParameters { + hybrid: match hybrid { + Setting::Set(hybrid) => Some(crate::index::HybridQuery { + semantic_ratio: *hybrid.semantic_ratio, + embedder: hybrid.embedder.clone(), + }), + Setting::Reset => None, + Setting::NotSet => search_parameters.hybrid.clone(), + }, + limit: match limit { + Setting::Set(limit) => Some(*limit), + Setting::Reset => None, + Setting::NotSet => search_parameters.limit, + }, + sort: match sort { + Setting::Set(sort) => Some(sort.clone()), + Setting::Reset => None, + Setting::NotSet => search_parameters.sort.clone(), + }, + distinct: match distinct { + Setting::Set(distinct) => Some(distinct.clone()), + Setting::Reset => None, + Setting::NotSet => search_parameters.distinct.clone(), + }, + matching_strategy: match matching_strategy { + Setting::Set(matching_strategy) => Some(*matching_strategy), + Setting::Reset => None, + Setting::NotSet => search_parameters.matching_strategy, + }, + attributes_to_search_on: match attributes_to_search_on { + Setting::Set(attributes_to_search_on) => { + Some(attributes_to_search_on.clone()) + } + Setting::Reset => None, + Setting::NotSet => { + search_parameters.attributes_to_search_on.clone() + } + }, + ranking_score_threshold: match ranking_score_threshold { + Setting::Set(rst) => Some(*rst), + Setting::Reset => None, + Setting::NotSet => search_parameters.ranking_score_threshold, + }, + } + } + Setting::Reset => Default::default(), + Setting::NotSet => search_parameters, + }; + + self.index.put_chat_config( + self.wtxn, + &ChatConfig { description, prompt, search_parameters }, + )?; + + Ok(true) + } + Setting::Reset => self.index.delete_chat_config(self.wtxn).map_err(Into::into), + Setting::NotSet => Ok(false), + } + } + pub fn execute(mut self, progress_callback: FP, should_abort: FA) -> Result<()> where FP: Fn(UpdateIndexingStep) + Sync, @@ -1275,6 +1392,7 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> { self.update_facet_search()?; self.update_localized_attributes_rules()?; self.update_disabled_typos_terms()?; + self.update_chat_config()?; let embedding_config_updates = self.update_embedding_configs()?; diff --git a/crates/milli/src/update/test_settings.rs b/crates/milli/src/update/test_settings.rs index 2b9ee3a5e..e78765cfb 100644 --- a/crates/milli/src/update/test_settings.rs +++ b/crates/milli/src/update/test_settings.rs @@ -897,6 +897,7 @@ fn test_correct_settings_init() { prefix_search, facet_search, disable_on_numbers, + chat, } = settings; assert!(matches!(searchable_fields, Setting::NotSet)); assert!(matches!(displayed_fields, Setting::NotSet)); @@ -925,6 +926,7 @@ fn test_correct_settings_init() { assert!(matches!(prefix_search, Setting::NotSet)); assert!(matches!(facet_search, Setting::NotSet)); assert!(matches!(disable_on_numbers, Setting::NotSet)); + assert!(matches!(chat, Setting::NotSet)); }) .unwrap(); } diff --git a/crates/milli/src/vector/settings.rs b/crates/milli/src/vector/settings.rs index 3948ad4d8..712c1faa5 100644 --- a/crates/milli/src/vector/settings.rs +++ b/crates/milli/src/vector/settings.rs @@ -33,6 +33,7 @@ pub struct EmbeddingSettings { /// /// - Defaults to `openAi` pub source: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -55,6 +56,7 @@ pub struct EmbeddingSettings { /// - For source `openAi`, defaults to `text-embedding-3-small` /// - For source `huggingFace`, defaults to `BAAI/bge-base-en-v1.5` pub model: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -75,6 +77,7 @@ pub struct EmbeddingSettings { /// - When `model` is set to default, defaults to `617ca489d9e86b49b8167676d8220688b99db36e` /// - Otherwise, defaults to `null` pub revision: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -96,6 +99,7 @@ pub struct EmbeddingSettings { /// /// - Embedders created before this parameter was available default to `forceMean` to preserve the existing behavior. pub pooling: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -118,6 +122,7 @@ pub struct EmbeddingSettings { /// /// - This setting is partially hidden when returned by the settings pub api_key: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -141,6 +146,7 @@ pub struct EmbeddingSettings { /// - For source `openAi`, the dimensions is the maximum allowed by the model. /// - For sources `ollama` and `rest`, the dimensions are inferred by embedding a sample text. pub dimensions: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -167,6 +173,7 @@ pub struct EmbeddingSettings { /// first enabling it. If you are unsure of whether the performance-relevancy tradeoff is right for you, /// we recommend to use this parameter on a test index first. pub binary_quantized: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -183,6 +190,7 @@ pub struct EmbeddingSettings { /// /// - 🏗️ When modified, embeddings are regenerated for documents whose rendering through the template produces a different text. pub document_template: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -201,6 +209,7 @@ pub struct EmbeddingSettings { /// /// - Defaults to 400 pub document_template_max_bytes: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -219,6 +228,7 @@ pub struct EmbeddingSettings { /// - 🌱 When modified for source `openAi`, embeddings are never regenerated /// - 🏗️ When modified for sources `ollama` and `rest`, embeddings are always regenerated pub url: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -236,6 +246,7 @@ pub struct EmbeddingSettings { /// /// - 🏗️ Changing the value of this parameter always regenerates embeddings pub request: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option)] @@ -253,6 +264,7 @@ pub struct EmbeddingSettings { /// /// - 🏗️ Changing the value of this parameter always regenerates embeddings pub response: Setting, + #[serde(default, skip_serializing_if = "Setting::is_not_set")] #[deserr(default)] #[schema(value_type = Option>)]