diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dadd0789..7d8532c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -123,7 +123,7 @@ jobs: run: make install-tools - name: Start services - run: docker compose -f docker/docker-compose.dev.yml up -d + run: docker compose -f docker/compose.yaml up -d - name: Wait for services run: | @@ -138,7 +138,7 @@ jobs: - name: Stop services if: always() - run: docker compose -f docker/docker-compose.dev.yml down -v + run: docker compose -f docker/compose.yaml down -v docs: name: Docs diff --git a/CHANGELOG.md b/CHANGELOG.md index b62c6854..728d716f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **nvisy-s3** - First-party S3-compatible blob storage (files, audits, avatars) - **nvisy-object-store** - External tenant object-store providers (S3, Azure, GCS) - **nvisy-file-service** - OAuth-based cloud file-service providers (Google Drive, Dropbox) -- **nvisy-inference** - LLM inference providers (OpenAI, Ollama, Anthropic) +- **nvisy-assistant** - LLM assistant engine and providers (OpenAI, Ollama, Anthropic) - **nvisy-webhook** - Webhook delivery types and traits - **nvisy-server** - HTTP handlers, middleware, pipeline, and services diff --git a/Cargo.lock b/Cargo.lock index cac941cc..dcb7bff3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -210,7 +210,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -221,7 +221,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -291,9 +291,9 @@ checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "arrow" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cfdd0833e32a9874d2b55089333ad310c0be208aafa277385ce2461dec90be3" +checksum = "c943b9bec582e47f8394e44713c3cbfbe645fd049e3a7771585f54849c710fe6" dependencies = [ "arrow-arith", "arrow-array", @@ -312,9 +312,9 @@ dependencies = [ [[package]] name = "arrow-arith" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a41203398f0eaa6f7ec8e62c0da742a21abf282c148fc157f6c35c90e29981a" +checksum = "8b13b85a6a547a1669114e418f6ab3c3e39c2edb1b8be5ab2889e5739a433ae9" dependencies = [ "arrow-array", "arrow-buffer", @@ -326,9 +326,9 @@ dependencies = [ [[package]] name = "arrow-array" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae33dad492b7df00a217563a7b0ef2874df68a0deea1b1a3acf628152f7f7a69" +checksum = "7b11eb61b95868592ad6edbd537465a6940eb3c81a875addecec24283301b267" dependencies = [ "ahash", "arrow-buffer", @@ -345,9 +345,9 @@ dependencies = [ [[package]] name = "arrow-buffer" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9552f96391c005e6ab449fa941420935e7e062489b12b8b1b08879b2163f5b5" +checksum = "53ee609a07eb721c2e4a7669d7bb88e2106c560e7dec1219096fecf5eae356d1" dependencies = [ "bytes", "half", @@ -357,9 +357,9 @@ dependencies = [ [[package]] name = "arrow-cast" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8a327c9649f30d8406995f27642b68df354713cca3baaaf100f076f18d5f34" +checksum = "9575323ffeb4bc6955f39bf8716f734671a32780f1fac9ba6c2891048fc0ea1f" dependencies = [ "arrow-array", "arrow-buffer", @@ -379,9 +379,9 @@ dependencies = [ [[package]] name = "arrow-csv" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af0dd6d90d1955e9f9a014c1e563ee8aeffc21909085d25623e1da44d96eca26" +checksum = "50659e76e264937e967167e08d76b1d50b1c162f723c5a3c0527d28c4cdf0d56" dependencies = [ "arrow-array", "arrow-cast", @@ -394,9 +394,9 @@ dependencies = [ [[package]] name = "arrow-data" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b24852db04738907e06c04ea61e42fe7fda962a34513022dc0d0e754fb7976b" +checksum = "10791765e6927cdd8ace5bf0e51a69f38a1c3aded2db93561b003c332d02ee2a" dependencies = [ "arrow-buffer", "arrow-schema", @@ -407,9 +407,9 @@ dependencies = [ [[package]] name = "arrow-ipc" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a908a11fcfb3fb2f6730f4ac15e367bc644e419155e96238f68cf3adde572b" +checksum = "165051f1f996f19b50c4d2cdb7ed02ddd400d8d984b422bf6848507eee099c3d" dependencies = [ "arrow-array", "arrow-buffer", @@ -423,9 +423,9 @@ dependencies = [ [[package]] name = "arrow-json" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a96aed3931c076adee39ec2a40d8219fc7f09e79bcdaca1df16272993e1e14" +checksum = "a0efe21cd317f22e6b8d7eecc4ed71a043e7269a7bc313a8827c7fb8733866ca" dependencies = [ "arrow-array", "arrow-buffer", @@ -448,9 +448,9 @@ dependencies = [ [[package]] name = "arrow-ord" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63a083ec750f5c043f02946b4baf05fcdbb55f4560a3277055caca5cc99f3eb0" +checksum = "908a1b5aeefce5c6eb2a0a4e98f4ccacbd441fe0ed23fb799e634cd0135821e5" dependencies = [ "arrow-array", "arrow-buffer", @@ -461,9 +461,9 @@ dependencies = [ [[package]] name = "arrow-row" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514ba0ef0d4c5896202dae736251ce415abb43a950bed570fb7981b8716c0e4c" +checksum = "5383b1676492a509032f06fa4ca9522c886036aec4ebe8261bebfbce904af667" dependencies = [ "arrow-array", "arrow-buffer", @@ -474,9 +474,9 @@ dependencies = [ [[package]] name = "arrow-schema" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21ca356ad6425cecb6eb7b28e4f659f1ee7880fbb1a16127de7dd62901efee9e" +checksum = "8506ad465ebb9483bb6efa1e2e78a313549122c6dd67dc2f7087297b762eaede" dependencies = [ "bitflags 2.13.2", "serde_core", @@ -485,9 +485,9 @@ dependencies = [ [[package]] name = "arrow-select" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58da39eb3d8350ad4a549e5c2bc49284dac554016c69829310350f1731b0aad" +checksum = "fd0f0a0d641356ae2df829af5d635ed9fb93fbeb0d39f3239487cb5fdb37a6ef" dependencies = [ "ahash", "arrow-array", @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "arrow-string" -version = "58.4.0" +version = "58.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6789b388467525e3271326b6b4915666ecfdf5142aef09779445c954b67543c" +checksum = "bd245a358d52e77bfcb99dc3e21f04b947383271b7a0b9ca8feec43e9039234d" dependencies = [ "arrow-array", "arrow-buffer", @@ -781,9 +781,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.18.2" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faac5829c2b74c28f830747e7818ccfb684261b5f48a1118b1e2a13d36dfab13" +checksum = "048006790404103c488e6c5616b3e7e702a71292aadda08e8f7698a9e0d2eb53" dependencies = [ "aws-lc-sys", "untrusted 0.7.1", @@ -792,9 +792,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.46.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1622d8446a2d4b2ce0c7eefc73dd43a99779028d5ee5c2dd8073a658ba8a2bc" +checksum = "8bfbe32ac36b3c428696ce315464181bc4029d689fd58e3f2a4e58c252242f52" dependencies = [ "cc", "cmake", @@ -831,9 +831,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.155.0" +version = "1.156.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a542f0e9261b9ce56708d591a62062079fa3c58a362ffbf49a2e48a4f6ced16" +checksum = "1072c9aa20159b9b417115342d38c4c53108fc98e5359fcb86b7d4575747eb59" dependencies = [ "arc-swap", "aws-credential-types", @@ -867,9 +867,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.117.0" +version = "1.118.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5316813498fa9c403877007934ae448aa44b18136f58051f8fa3c5b79b44bdc6" +checksum = "b4a89786db8ee6dff2c9302a354ef081354fcb0f527e16ee3cb249a6a5cb6df7" dependencies = [ "arc-swap", "aws-credential-types", @@ -892,9 +892,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.119.0" +version = "1.120.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31db35e5662787b786daba15f431e4393c7ea512b70fa112bd048d1f3ecf877a" +checksum = "521c6a11a25f1244efddf947523f277a51a63f0a7ec228f0f62d826e88106366" dependencies = [ "arc-swap", "aws-credential-types", @@ -917,9 +917,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.122.0" +version = "1.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a10491638d9e560db90c484dbc77d73b8ad202780cdc9b9e92180603acb07ada" +checksum = "8754d38d29448bd1d4aa4a6312ed010dfa296b3436eb2c551cc6e42fc6a66a38" dependencies = [ "arc-swap", "aws-credential-types", @@ -943,9 +943,9 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.6.3" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d3d48355cb86b15ccbb38b8bc6b87500c824ee4ed8cbc10a961b435242b5e16" +checksum = "f385da9b7757ed4c8214797ad663ff534fb622006143530aa80e21f8e06ff85c" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", @@ -953,7 +953,7 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "bytes", - "crypto-bigint 0.5.5", + "crypto-bigint 0.7.10", "ecdsa 0.17.0", "form_urlencoded", "hex", @@ -1013,9 +1013,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.64.2" +version = "0.64.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba8960956e0ee0ca3f3161e62913a61bc65a7ef638ca3ef1d4c7159f8443e398" +checksum = "19af609dd5edf8b056cd0bb001c706c8b3b1458055328b334ec13d7f46f6aaa8" dependencies = [ "aws-smithy-eventstream", "aws-smithy-runtime-api", @@ -1034,9 +1034,9 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeca69f65362f7375891008ea525fd440ad6db1836458ac188c87b126804114e" +checksum = "859a81364f8185349c584fb41cd8765a400cf982f447adada590cf008a9f3b85" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -1058,9 +1058,9 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.65.0" +version = "0.65.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f6835fb38bc6fc8c91e584b0366eb4ff595e5c485134dbf4f0bdeaa18856666" +checksum = "b45f9fc77ffe92c92c341165a01a565bd30c39ecf5aa8c0719b41719009604f9" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-schema", @@ -1091,9 +1091,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cef0c41e8ca40f74f68ed8ee4d1ddbde12bb847b95ef9b3c025681ddfae58a" +checksum = "4cb80fb19c084da5fca9d797845735e184445e5b958599440d67529bf6ef1b64" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -1114,9 +1114,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.19.1" +version = "1.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06788004dea79018413f381891da6dcca23196acd79c4d51b767fbdacc76eae4" +checksum = "8c4e85cffe9944b10d576b075432bd8f98dbc081e8681cb37d5b2d87dc27bc84" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api-macros", @@ -1131,9 +1131,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api-macros" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221eaa237ddf1ca79b60d1372aad77e47f9c0ea5b3ce5099da8c61d027dc77b3" +checksum = "ce237f890a2283c9b328955c3b0918d2d5bf66a1cb6ceccd36a0047246fbc6e6" dependencies = [ "proc-macro2", "quote", @@ -1153,9 +1153,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55752025c39c0e094962fd73f1c57014b191f678612e517f219468e575af9822" +checksum = "cf183d70774ea2cfcc101ca74a8884e4c76be8b9df65cd303f6a1175c88e8f80" dependencies = [ "base64-simd", "bytes", @@ -1176,9 +1176,9 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.64.0" +version = "0.64.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6581618a2fd006159016d1c36881d94d61b4a017f4a8d631310875e18252413" +checksum = "590fdc1a70546b2f7f2061c42eaf173fb6f26d935330d069edc04dbd8f01d924" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-schema", @@ -1409,11 +1409,13 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bentoml" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c65f4e07f4eac57a9e81aa97cf1c9d297cc01aad185767b613c1bcf112c469d8" +checksum = "088d618c291427e7e498ff7aa19fc1cac42a935b3ffd010a529d58477885426b" dependencies = [ + "async-trait", "bytes", + "http", "jiff", "reqwest 0.13.5", "reqwest-middleware", @@ -1421,6 +1423,7 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.21", + "tokio", "tracing", "url", ] @@ -1647,13 +1650,13 @@ dependencies = [ [[package]] name = "brotli" -version = "9.0.0" +version = "9.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8b851b75c23ca7873623d612fe49bd1989aeb03d08fb9432187eb253d3d4c6b" +checksum = "627b7cfb0578f0eafce087a90fcd40add1231900b69e4d4de2d456260a4f5d81" dependencies = [ "alloc-no-stdlib 3.0.0", "alloc-stdlib 0.3.0", - "brotli-decompressor 6.0.1", + "brotli-decompressor 6.2.0", ] [[package]] @@ -1668,9 +1671,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "6.0.1" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941cd9bd4ddab83cb46fa5a2d428f1c857b24ac78cb876cf7beb710840934bd7" +checksum = "34c6783f42c21c952ad7112b354f0ba2f10760e9decea5b1b60523d6e270faaf" dependencies = [ "alloc-no-stdlib 3.0.0", "alloc-stdlib 0.3.0", @@ -2010,7 +2013,7 @@ version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cae36683101b2899f48bd31f8db9839437356188e3b1ff23096e73dab09ba8fe" dependencies = [ - "brotli 9.0.0", + "brotli 9.1.1", "compression-core", "flate2", "memchr", @@ -2302,9 +2305,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.6" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb08299a6046833a879ace115697f12fd2bd6c8d3e93c909ffc9e0738e7cae0" +checksum = "9c035cb64cba03dad2fb921f3e218785e8cf9a41790da5eb3a1400f62fa2be11" dependencies = [ "cpubits", "ctutils", @@ -2369,9 +2372,9 @@ dependencies = [ [[package]] name = "ctutils" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d28fb6aa7dd680b3ffd1a3e64e115c177bdba63c0ae7f9cd48129ff05c4fa0" +checksum = "fe3e9d21d39e6f39ff46e03d5b621424f88ee23d8a1672c6bfc9ccc7f2da4f6a" dependencies = [ "cmov", "subtle", @@ -3275,9 +3278,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" +checksum = "6a996a108feb8b427a6e12fcf6af4aa83409b79d72c15337d7741368131ee004" dependencies = [ "const-oid 0.10.2", "pem-rfc7468 1.0.0", @@ -3483,7 +3486,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3575,9 +3578,9 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ - "der 0.8.2", + "der 0.8.3", "digest 0.11.3", - "elliptic-curve 0.14.1", + "elliptic-curve 0.14.3", "rfc6979 0.6.0", "signature 3.0.0", "spki 0.8.1", @@ -3630,7 +3633,7 @@ checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be" [[package]] name = "elide" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "elide-audio", @@ -3656,7 +3659,7 @@ dependencies = [ [[package]] name = "elide-audio" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "bytes", @@ -3673,7 +3676,7 @@ dependencies = [ [[package]] name = "elide-backend" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "elide-core", @@ -3686,7 +3689,7 @@ dependencies = [ [[package]] name = "elide-bentoml" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide-runtime?branch=main#64df75803eb531c7b8b14c90dfb71ce6dadab2bd" +source = "git+https://github.com/nvisycom/elide-runtime?rev=eb23876f773e01f532d8d327b2883347e17465fa#3cd6903f98843ab7ea6e5c1754d846810648860d" dependencies = [ "async-trait", "base64 0.23.1", @@ -3698,12 +3701,13 @@ dependencies = [ "hipstr", "serde", "thiserror 2.0.21", + "uuid", ] [[package]] name = "elide-codec" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "bytes", @@ -3715,7 +3719,7 @@ dependencies = [ [[package]] name = "elide-context" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "elide-core", @@ -3726,7 +3730,7 @@ dependencies = [ [[package]] name = "elide-core" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "blake3", @@ -3744,7 +3748,7 @@ dependencies = [ [[package]] name = "elide-deployment" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide-runtime?branch=main#64df75803eb531c7b8b14c90dfb71ce6dadab2bd" +source = "git+https://github.com/nvisycom/elide-runtime?rev=eb23876f773e01f532d8d327b2883347e17465fa#3cd6903f98843ab7ea6e5c1754d846810648860d" dependencies = [ "elide", "hipstr", @@ -3756,7 +3760,7 @@ dependencies = [ [[package]] name = "elide-detection" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "elide-core", @@ -3769,7 +3773,7 @@ dependencies = [ [[package]] name = "elide-engine" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "bytes", "elide-audio", @@ -3791,7 +3795,7 @@ dependencies = [ [[package]] name = "elide-export" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide-runtime?branch=main#64df75803eb531c7b8b14c90dfb71ce6dadab2bd" +source = "git+https://github.com/nvisycom/elide-runtime?rev=eb23876f773e01f532d8d327b2883347e17465fa#3cd6903f98843ab7ea6e5c1754d846810648860d" dependencies = [ "csv", "elide", @@ -3803,7 +3807,7 @@ dependencies = [ [[package]] name = "elide-fake" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "elide-core", @@ -3815,7 +3819,7 @@ dependencies = [ [[package]] name = "elide-format" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "elide-audio", "elide-codec", @@ -3829,7 +3833,7 @@ dependencies = [ [[package]] name = "elide-image" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "bytes", @@ -3847,7 +3851,7 @@ dependencies = [ [[package]] name = "elide-lingua" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "elide-core", @@ -3858,7 +3862,7 @@ dependencies = [ [[package]] name = "elide-llm" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "base64 0.23.1", @@ -3880,7 +3884,7 @@ dependencies = [ [[package]] name = "elide-ner" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "elide-core", @@ -3893,7 +3897,7 @@ dependencies = [ [[package]] name = "elide-office" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "bytes", @@ -3908,7 +3912,7 @@ dependencies = [ [[package]] name = "elide-operator" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "aes-gcm", "async-trait", @@ -3932,7 +3936,7 @@ dependencies = [ [[package]] name = "elide-pattern" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "aho-corasick", "async-trait", @@ -3953,7 +3957,7 @@ dependencies = [ [[package]] name = "elide-pdf" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "bytes", @@ -3968,7 +3972,7 @@ dependencies = [ [[package]] name = "elide-pipeline" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide-runtime?branch=main#64df75803eb531c7b8b14c90dfb71ce6dadab2bd" +source = "git+https://github.com/nvisycom/elide-runtime?rev=eb23876f773e01f532d8d327b2883347e17465fa#3cd6903f98843ab7ea6e5c1754d846810648860d" dependencies = [ "bytes", "elide", @@ -3989,7 +3993,7 @@ dependencies = [ [[package]] name = "elide-plain" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "async-trait", "bytes", @@ -4004,7 +4008,7 @@ dependencies = [ [[package]] name = "elide-provider" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide-runtime?branch=main#64df75803eb531c7b8b14c90dfb71ce6dadab2bd" +source = "git+https://github.com/nvisycom/elide-runtime?rev=eb23876f773e01f532d8d327b2883347e17465fa#3cd6903f98843ab7ea6e5c1754d846810648860d" dependencies = [ "elide", "elide-bentoml", @@ -4021,7 +4025,7 @@ dependencies = [ [[package]] name = "elide-redaction" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#16171779944e3c74ccc175e9d076abff0bbd1b61" +source = "git+https://github.com/nvisycom/elide?branch=main#b363aa28d792fc68e2b852b7ed4165e80a42a444" dependencies = [ "elide-core", "hipstr", @@ -4031,7 +4035,7 @@ dependencies = [ [[package]] name = "elide-review" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide-runtime?branch=main#64df75803eb531c7b8b14c90dfb71ce6dadab2bd" +source = "git+https://github.com/nvisycom/elide-runtime?rev=eb23876f773e01f532d8d327b2883347e17465fa#3cd6903f98843ab7ea6e5c1754d846810648860d" dependencies = [ "elide", "elide-schema", @@ -4043,7 +4047,7 @@ dependencies = [ [[package]] name = "elide-schema" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide-runtime?branch=main#64df75803eb531c7b8b14c90dfb71ce6dadab2bd" +source = "git+https://github.com/nvisycom/elide-runtime?rev=eb23876f773e01f532d8d327b2883347e17465fa#3cd6903f98843ab7ea6e5c1754d846810648860d" dependencies = [ "elide", "hipstr", @@ -4056,7 +4060,7 @@ dependencies = [ [[package]] name = "elide-template" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide-runtime?branch=main#64df75803eb531c7b8b14c90dfb71ce6dadab2bd" +source = "git+https://github.com/nvisycom/elide-runtime?rev=eb23876f773e01f532d8d327b2883347e17465fa#3cd6903f98843ab7ea6e5c1754d846810648860d" dependencies = [ "elide-core", "elide-operator", @@ -4092,12 +4096,12 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" +checksum = "900f37e7e18d74a2347389af6cd69e3a30d5cc9e697f40004865679aa75e9c7c" dependencies = [ "base16ct 1.0.0", - "crypto-bigint 0.7.6", + "crypto-bigint 0.7.10", "crypto-common 0.2.2", "digest 0.11.3", "ff 0.14.0", @@ -4209,9 +4213,9 @@ checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" [[package]] name = "erased-serde" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +checksum = "1e59b668157f32d3459d4bd634861a06ffa2503a461ca5f0916b9f0252605e66" dependencies = [ "serde", "serde_core", @@ -4225,7 +4229,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5749,7 +5753,7 @@ dependencies = [ "jiff", "nom 8.0.0", "num-traits", - "ordered-float 5.5.0", + "ordered-float 5.5.1", "rand 0.9.5", "serde", "serde_json", @@ -6613,9 +6617,9 @@ dependencies = [ [[package]] name = "lopdf" -version = "0.45.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfffda0fe1ab0157e1a13c14bebd3f28671f2fccb7922f0722ec53926e6922d3" +checksum = "d43f64cb8c0d673ff84245a6de9e0172c0cc05dc5dd9d263660b5b4a02b6c4ae" dependencies = [ "aes", "bitflags 2.13.2", @@ -7068,7 +7072,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -7203,6 +7207,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "nvisy-assistant" +version = "0.1.0" +dependencies = [ + "async-stream", + "futures", + "rig 0.45.0", + "schemars 1.2.3", + "serde", + "serde_json", + "thiserror 2.0.21", + "tokio", + "tracing", +] + [[package]] name = "nvisy-cli" version = "0.1.0" @@ -7260,21 +7279,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "nvisy-inference" -version = "0.1.0" -dependencies = [ - "async-stream", - "futures", - "rig 0.45.0", - "schemars 1.2.3", - "serde", - "serde_json", - "thiserror 2.0.21", - "tokio", - "tracing", -] - [[package]] name = "nvisy-nats" version = "0.1.0" @@ -7401,9 +7405,9 @@ dependencies = [ "jiff", "jsonwebtoken", "mime_guess", + "nvisy-assistant", "nvisy-core", "nvisy-file-service", - "nvisy-inference", "nvisy-nats", "nvisy-object-store", "nvisy-postgres", @@ -7465,7 +7469,7 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" dependencies = [ - "base64 0.22.1", + "base64 0.21.7", "chrono", "getrandom 0.2.17", "http", @@ -7639,9 +7643,9 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +checksum = "7e036b411754132fd6b74e94b74e9a13c5cf606fa93d1885c35860d3060820b1" [[package]] name = "option-ext" @@ -7660,9 +7664,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.5.0" +version = "5.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c9e0d9b23589f26070720bac724174bfec1083e82f7854cdd0267518343c0" +checksum = "7f59006ce1e204c30956638535b74d317bca99477b9356dfaec54c37f6f600ab" dependencies = [ "num-traits", ] @@ -7721,7 +7725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2c9239b2dbc807adbbe147e8cf72ea7450c3a0aabe62cb8e75ff4ec22e1f72a" dependencies = [ "ecdsa 0.17.0", - "elliptic-curve 0.14.1", + "elliptic-curve 0.14.3", "primefield", "primeorder 0.14.0", "sha2 0.11.1", @@ -7994,7 +7998,7 @@ dependencies = [ "regex-cache", "serde", "serde_derive", - "strum 0.27.2", + "strum 0.26.3", "thiserror 2.0.21", ] @@ -8057,7 +8061,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ - "der 0.8.2", + "der 0.8.3", "spki 0.8.1", ] @@ -8219,7 +8223,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" dependencies = [ - "crypto-bigint 0.7.6", + "crypto-bigint 0.7.10", "crypto-common 0.2.2", "ff 0.14.0", "rand_core 0.10.1", @@ -8242,7 +8246,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ - "elliptic-curve 0.14.1", + "elliptic-curve 0.14.3", "once_cell", "primefield", "serdect", @@ -8302,8 +8306,8 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" dependencies = [ - "heck 0.5.0", - "itertools 0.14.0", + "heck 0.4.1", + "itertools 0.10.5", "log", "multimap", "petgraph", @@ -8322,7 +8326,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", - "itertools 0.14.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.119", @@ -8483,7 +8487,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8639,14 +8643,13 @@ dependencies = [ [[package]] name = "random_word" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47a395bdb55442b883c89062d6bcff25dc90fa5f8369af81e0ac6d49d78cf81" +checksum = "a624195e0ebed209339a96296c5cee20400354f834b49cc5a7da4f4c38b14d88" dependencies = [ "ahash", - "brotli 8.0.4", - "paste", - "rand 0.9.5", + "brotli 9.1.1", + "rand 0.10.3", "unicase", ] @@ -9036,7 +9039,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ - "crypto-bigint 0.7.6", + "crypto-bigint 0.7.10", "hmac 0.13.0", ] @@ -9163,7 +9166,7 @@ dependencies = [ "http", "mime", "mime_guess", - "ordered-float 5.5.0", + "ordered-float 5.5.1", "rig-derive 0.44.0", "rig-http 0.44.0", "schemars 1.2.3", @@ -9193,7 +9196,7 @@ dependencies = [ "indexmap 2.14.2", "mime", "mime_guess", - "ordered-float 5.5.0", + "ordered-float 5.5.1", "rig-derive 0.45.0", "rig-http 0.45.0", "rig-reqwest 0.45.0", @@ -9530,15 +9533,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +checksum = "e5e76742e5294153d4dde1207dbec5bdd81eef6fabdc0d2118babadabfd858aa" dependencies = [ "bitflags 2.13.2", "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -9597,7 +9600,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -9733,7 +9736,7 @@ checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct 1.0.0", "ctutils", - "der 0.8.2", + "der 0.8.3", "hybrid-array", "subtle", "zeroize", @@ -10190,9 +10193,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.16.3" +version = "1.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" +checksum = "d0d5d4b1981b8bbbb7aed204cae5726d683d5d6ac7e74ec54122ea28f315e7c8" [[package]] name = "snafu" @@ -10218,7 +10221,7 @@ version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "proc-macro2", "quote", "syn 2.0.119", @@ -10230,7 +10233,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "287f59010008f0d7cf5e3b03196d666c1acc46c8d3e9cf34c28a1a7157601e72" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "proc-macro2", "quote", "syn 2.0.119", @@ -10243,7 +10246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -10289,7 +10292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef958a98b9d5da290cfc78946e9f3e61e1e62a18db0d92cac0b83cc161491a9" dependencies = [ "base64ct", - "der 0.8.2", + "der 0.8.3", ] [[package]] @@ -10626,10 +10629,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -11035,9 +11038,9 @@ checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" [[package]] name = "tonic" -version = "0.14.6" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" +checksum = "cd1fa9b1a51188f3266a823208078315811269d06d272c3a61be0b9a194194ff" dependencies = [ "async-trait", "axum", @@ -11056,6 +11059,7 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-stream", + "tokio-util", "tower", "tower-layer", "tower-service", @@ -11064,9 +11068,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.6" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" +checksum = "f63c616ffaa648f7c5dd5657e97d9a285fcb44ff3b70da761d436f5a13ff7be6" dependencies = [ "bytes", "prost", @@ -11291,9 +11295,9 @@ dependencies = [ [[package]] name = "typed-path" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ec2755506471f54baf5e4bb5499d8e510cc1caf271270e778a736bd2d7336c" +checksum = "9ce898823d8cd0f028662d2f349694b1af0a5cc9be83f1d213a00d3147445e1e" [[package]] name = "typeid" @@ -11387,9 +11391,9 @@ checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-width" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +checksum = "ca718471876992059f251e33aafc334346ada08042b7661dd1fe313a9bced557" [[package]] name = "unicode-xid" @@ -11820,7 +11824,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -12124,9 +12128,9 @@ dependencies = [ [[package]] name = "xattr" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +checksum = "963d6fab92d5504b971dc8bd90ca743c2575e590bc8071ea5bc571598667ae08" dependencies = [ "libc", "rustix", @@ -12275,16 +12279,18 @@ dependencies = [ [[package]] name = "zip" -version = "9.0.5" +version = "9.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e04976da629d3b04204ba8105b396a193af8ad2583b2c79bfb3ab8af580a11e" +checksum = "1156b39d142a34b999c2310a50455e0cb3760bf7efad0122f796d813bee26ccb" dependencies = [ "crc32fast", "flate2", + "getrandom 0.4.3", "indexmap 2.14.2", "memchr", "nix", "typed-path", + "windows-sys 0.61.2", "zopfli", ] diff --git a/Cargo.toml b/Cargo.toml index 58abd507..31531cc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ "./crates/nvisy-cli", "./crates/nvisy-core", "./crates/nvisy-nats", - "./crates/nvisy-inference", + "./crates/nvisy-assistant", "./crates/nvisy-object-store", "./crates/nvisy-file-service", "./crates/nvisy-s3", @@ -47,12 +47,12 @@ debug = true # See for more details: https://github.com/rust-lang/cargo/issues/11329 # Elide crates -elide-pipeline = { git = "https://github.com/nvisycom/elide-runtime", branch = "main", default-features = false } +elide-pipeline = { git = "https://github.com/nvisycom/elide-runtime", rev = "eb23876f773e01f532d8d327b2883347e17465fa", default-features = false } # Internal crates nvisy-core = { path = "./crates/nvisy-core", version = "0.1.0" } nvisy-nats = { path = "./crates/nvisy-nats", version = "0.1.0" } -nvisy-inference = { path = "./crates/nvisy-inference", version = "0.1.0" } +nvisy-assistant = { path = "./crates/nvisy-assistant", version = "0.1.0" } nvisy-object-store = { path = "./crates/nvisy-object-store", version = "0.1.0" } nvisy-file-service = { path = "./crates/nvisy-file-service", version = "0.1.0" } nvisy-postgres = { path = "./crates/nvisy-postgres", version = "0.1.0" } diff --git a/Makefile b/Makefile index c93eadc9..5a0bc5ba 100644 --- a/Makefile +++ b/Makefile @@ -105,17 +105,27 @@ clear-migrations: ## Reverts all database migrations. .PHONY: reset reset: ## Resets Docker containers (down -v, then up -d). @$(call log,Stopping and removing Docker containers and volumes...) - @docker compose -f ./docker/docker-compose.dev.yml down -v + @docker compose -f ./docker/compose.yaml down -v @$(call log,Starting Docker containers...) - @docker compose -f ./docker/docker-compose.dev.yml up -d + @docker compose -f ./docker/compose.yaml up -d @$(call log,Docker containers reset successfully.) +# `NER=1` also starts the GLiNER2 NER service and points the server at the NER +# engine config. Set by the `run` recipe below. +ifdef NER +RUN_ENGINE_ENV := ENGINE_CONFIG_FILEPATH="$$engine_config" +endif + .PHONY: run -run: ## Runs the server with .env loaded (starts Postgres, NATS, and RustFS first). +run: ## Runs the server (NATS, Postgres, RustFS first). Pass NER=1 to also start the GLiNER2 NER service. @$(call log,Starting Postgres, NATS, and RustFS...) - @docker compose -f ./docker/docker-compose.dev.yml up -d --wait postgres nats rustfs + @docker compose -f ./docker/compose.yaml up -d --wait postgres nats rustfs @$(call log,Provisioning the blob store bucket...) - @docker compose -f ./docker/docker-compose.dev.yml up --exit-code-from rustfs-init rustfs-init + @docker compose -f ./docker/compose.yaml up --exit-code-from rustfs-init rustfs-init +ifdef NER + @$(call log,Starting the NER service (first run downloads the model)...) + @docker compose -f ./docker/compose.yaml --profile ner up -d --wait ner +endif @$(call log,Starting server... (output also written to latest.log)) @# Tee via process substitution rather than a pipe: a pipe would put `tee` @# in the foreground process group, so Ctrl+C (SIGINT) kills `tee` first and @@ -123,7 +133,7 @@ run: ## Runs the server with .env loaded (starts Postgres, NATS, and RustFS firs @# then lost and, under `pipefail`, the recipe reports exit 130. With `> >(tee)` @# the server owns the terminal and receives the signal directly; its shutdown @# runs and is logged, and the process exits cleanly. - @bash -c 'cargo run --features dotenv --bin nvisy-cli > >(tee latest.log) 2>&1' + @bash -c 'engine_config=$$(mktemp); trap "rm -f \"$$engine_config\"" EXIT; sed "s|\$${ELIDE_NER_PORT:-3200}|$${ELIDE_NER_PORT:-3200}|g" docker/engine.dev.toml > "$$engine_config"; $(RUN_ENGINE_ENV) cargo run --features dotenv --bin nvisy-cli > >(tee latest.log) 2>&1' .PHONY: generate-all generate-all: generate-env generate-keys generate-migrations diff --git a/README.md b/README.md index ae75a585..b6e6d404 100644 --- a/README.md +++ b/README.md @@ -54,10 +54,15 @@ server locally: make install-all # Install tools and make scripts executable make generate-all # Generate .env, auth keys, and apply migrations -docker compose -f docker/docker-compose.dev.yml up -d # Start Postgres, NATS, RustFS +docker compose -f docker/compose.yaml up -d # Start Postgres, NATS, RustFS make run # Run the server ``` +To run with the GLiNER2 NER service (pattern recognition otherwise runs alone), +pass `make run NER=1` — it also starts the `ner` compose profile and points the +server at `docker/engine.dev.toml`. The first run downloads the model (~1.2 GB) +into a cached volume. + The API then serves interactive OpenAPI docs (Scalar UI) at the running server's docs path. For self-hosted deployments, see [`docker/`](docker/) for compose files and infrastructure requirements, and [`.env.example`](.env.example) for diff --git a/crates/nvisy-inference/Cargo.toml b/crates/nvisy-assistant/Cargo.toml similarity index 86% rename from crates/nvisy-inference/Cargo.toml rename to crates/nvisy-assistant/Cargo.toml index 283dfffe..e4af827a 100644 --- a/crates/nvisy-inference/Cargo.toml +++ b/crates/nvisy-assistant/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "nvisy-inference" -description = "LLM inference providers (OpenAI, Ollama, Anthropic) for Nvisy" +name = "nvisy-assistant" +description = "LLM assistant engine and providers (OpenAI, Ollama, Anthropic) for Nvisy" readme = "./README.md" -keywords = ["nvisy", "llm", "openai", "ollama", "anthropic"] +keywords = ["nvisy", "assistant", "llm", "openai", "anthropic"] categories = ["api-bindings"] version = { workspace = true } diff --git a/crates/nvisy-inference/README.md b/crates/nvisy-assistant/README.md similarity index 89% rename from crates/nvisy-inference/README.md rename to crates/nvisy-assistant/README.md index fcaf8f86..c2fad8d0 100644 --- a/crates/nvisy-inference/README.md +++ b/crates/nvisy-assistant/README.md @@ -1,12 +1,12 @@ -# nvisy-inference +# nvisy-assistant [![Build](https://img.shields.io/github/actions/workflow/status/nvisycom/server/build.yml?branch=main&label=build%20%26%20test&style=flat-square)](https://github.com/nvisycom/server/actions/workflows/build.yml) -LLM inference provider configuration and clients for the Nvisy platform. +The LLM assistant engine and its provider clients for the Nvisy platform. ## Overview -A provider-agnostic inference layer over +A provider-agnostic LLM layer over [`rig`](https://crates.io/crates/rig), supporting `OpenAI`, Ollama, and Anthropic behind a single provider-tagged `LlmConfig`. The config carries each provider's credentials and is stored encrypted at rest by a workspace diff --git a/crates/nvisy-inference/src/client/config.rs b/crates/nvisy-assistant/src/client/config.rs similarity index 96% rename from crates/nvisy-inference/src/client/config.rs rename to crates/nvisy-assistant/src/client/config.rs index a4dfe621..a70daa87 100644 --- a/crates/nvisy-inference/src/client/config.rs +++ b/crates/nvisy-assistant/src/client/config.rs @@ -1,4 +1,4 @@ -//! The typed LLM inference connection configuration. +//! The typed LLM connection configuration. use std::fmt; @@ -6,7 +6,7 @@ use std::fmt; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use super::InferenceClient; +use super::AssistantClient; use crate::error::Result; use crate::provider::{ AnthropicProvider, Client, OllamaCredentials, OllamaProvider, OpenAiProvider, @@ -54,7 +54,7 @@ pub struct UnauthenticatedProvider { pub default_model: Option, } -/// A fully-typed LLM inference connection configuration. +/// A fully-typed LLM connection configuration. /// /// The `provider` tag selects the variant and thereby the credential shape, so /// an `OpenAI` connection cannot carry Anthropic credentials. The key-bearing @@ -145,7 +145,7 @@ impl LlmConfig { } } - /// Builds a ready-to-use [`InferenceClient`] for this config. + /// Builds a ready-to-use [`AssistantClient`] for this config. /// /// `model` overrides the configured [`default_model`]; if neither is set, the /// provider's own default applies. @@ -156,7 +156,7 @@ impl LlmConfig { /// /// Returns a `Result` for a stable call-site seam; building a provider client /// from a validated config does not currently fail. - pub fn connect(&self, model: Option<&str>) -> Result { + pub fn connect(&self, model: Option<&str>) -> Result { let model = model.or_else(|| self.default_model()).unwrap_or_default(); let client = match self { Self::OpenAi(p) => { @@ -183,12 +183,12 @@ impl LlmConfig { #[derive(Debug, Clone, Deserialize, Serialize)] #[cfg_attr(feature = "schema", derive(JsonSchema))] #[serde(untagged)] -pub enum InferenceConfig { +pub enum AssistantConfig { /// A language model (chat/completion) connection. Llm(LlmConfig), } -impl InferenceConfig { +impl AssistantConfig { /// The provider identifier for this config, matching the serialized `provider` /// tag and used for the stored `provider` column and for filtering. #[must_use] diff --git a/crates/nvisy-inference/src/client/mod.rs b/crates/nvisy-assistant/src/client/mod.rs similarity index 73% rename from crates/nvisy-inference/src/client/mod.rs rename to crates/nvisy-assistant/src/client/mod.rs index 39f0211f..976fe57c 100644 --- a/crates/nvisy-inference/src/client/mod.rs +++ b/crates/nvisy-assistant/src/client/mod.rs @@ -1,7 +1,7 @@ -//! The client layer: the typed connection config and the runtime inference +//! The client layer: the typed connection config and the runtime assistant //! client. //! -//! [`LlmConfig`] is the stored, provider-tagged configuration; [`InferenceClient`] +//! [`LlmConfig`] is the stored, provider-tagged configuration; [`AssistantClient`] //! is the provider-agnostic runtime handle it builds. mod config; @@ -10,8 +10,8 @@ mod token_stream; mod turn; pub use self::config::{ - AuthenticatedProvider, InferenceConfig, LlmConfig, UnauthenticatedProvider, + AssistantConfig, AuthenticatedProvider, LlmConfig, UnauthenticatedProvider, }; -pub use self::service::InferenceClient; +pub use self::service::AssistantClient; pub use self::token_stream::TokenStream; pub use self::turn::{ChatTurn, Role}; diff --git a/crates/nvisy-inference/src/client/service.rs b/crates/nvisy-assistant/src/client/service.rs similarity index 82% rename from crates/nvisy-inference/src/client/service.rs rename to crates/nvisy-assistant/src/client/service.rs index 3ab06d99..728c1bd2 100644 --- a/crates/nvisy-inference/src/client/service.rs +++ b/crates/nvisy-assistant/src/client/service.rs @@ -1,13 +1,13 @@ -//! Provider-agnostic inference client backed by a rig agent. +//! Provider-agnostic assistant client backed by a rig agent. //! -//! [`InferenceClient`] is a thin, cloneable wrapper around any provider's rig +//! [`AssistantClient`] is a thin, cloneable wrapper around any provider's rig //! [`Agent`] that provides convenience methods for the most common operations — -//! one-shot [`prompt`](InferenceClient::prompt), multi-turn -//! [`chat`](InferenceClient::chat), and streaming -//! [`stream_chat`](InferenceClient::stream_chat). Every public method is +//! one-shot [`prompt`](AssistantClient::prompt), multi-turn +//! [`chat`](AssistantClient::chat), and streaming +//! [`stream_chat`](AssistantClient::stream_chat). Every public method is //! instrumented with [`tracing`] for observability. It plays the same role for -//! inference that `ObjectStoreClient` plays for object storage: one runtime -//! handle callers use regardless of which provider backs it. +//! language-model access that `ObjectStoreClient` plays for object storage: one +//! runtime handle callers use regardless of which provider backs it. use std::sync::Arc; @@ -20,15 +20,15 @@ use rig::streaming::{Item, StreamEvent}; use super::{ChatTurn, TokenStream}; use crate::error::{Error, Result}; -/// Cloneable handle to any inference backend (`OpenAI`, Anthropic, Ollama, ...). +/// Cloneable handle to any language-model backend (`OpenAI`, Anthropic, Ollama, ...). /// /// Wraps a rig [`Agent`] — which erases its provider's completion-model type /// internally — behind a provider-agnostic interface, so callers issue prompts /// without knowing which provider is configured. #[derive(Clone)] -pub struct InferenceClient(Arc); +pub struct AssistantClient(Arc); -impl InferenceClient { +impl AssistantClient { /// Wrap a rig [`Agent`]. pub(crate) fn new(agent: Agent) -> Self { Self(Arc::new(agent)) @@ -40,7 +40,7 @@ impl InferenceClient { /// # Errors /// /// A `Prompt` error if the completion request fails at runtime. - #[tracing::instrument(name = "inference.prompt", skip_all)] + #[tracing::instrument(name = "assistant.prompt", skip_all)] pub async fn prompt(&self, prompt: &str) -> Result { self.0 .prompt(prompt.to_owned()) @@ -56,7 +56,7 @@ impl InferenceClient { /// # Errors /// /// A `Prompt` error if the completion request fails at runtime. - #[tracing::instrument(name = "inference.chat", skip_all, fields(history_len = history.len()))] + #[tracing::instrument(name = "assistant.chat", skip_all, fields(history_len = history.len()))] pub async fn chat(&self, prompt: &str, history: Vec) -> Result { let mut history = to_messages(history); self.0 @@ -74,10 +74,10 @@ impl InferenceClient { /// a failure mid-generation ends the stream with an `Err`. `history` is the /// prior conversation as [`ChatTurn`]s; persist the user prompt and the /// assembled reply on the caller side. - #[tracing::instrument(name = "inference.stream_chat", skip_all, fields(history_len = history.len()))] + #[tracing::instrument(name = "assistant.stream_chat", skip_all, fields(history_len = history.len()))] pub fn stream_chat(&self, prompt: &str, history: Vec) -> TokenStream { // Own the agent handle in the generator so the result is `'static` and - // can outlive this `InferenceClient` (moved into a response body). The + // can outlive this `AssistantClient` (moved into a response body). The // provider stream borrows the owned `Arc`, which the coroutine keeps // alive for the whole stream. let agent = Arc::clone(&self.0); diff --git a/crates/nvisy-inference/src/client/token_stream.rs b/crates/nvisy-assistant/src/client/token_stream.rs similarity index 89% rename from crates/nvisy-inference/src/client/token_stream.rs rename to crates/nvisy-assistant/src/client/token_stream.rs index 59a9088f..c7d3eafd 100644 --- a/crates/nvisy-inference/src/client/token_stream.rs +++ b/crates/nvisy-assistant/src/client/token_stream.rs @@ -14,10 +14,10 @@ use crate::error::Result; /// (`Err`) and ends the stream. Owned and `'static`, so it can be moved into a /// response body outliving the client that produced it. /// -/// Yielded by [`InferenceClient::stream_chat`]. Poll it with the [`Stream`] API +/// Yielded by [`AssistantClient::stream_chat`]. Poll it with the [`Stream`] API /// ([`futures::StreamExt`]). /// -/// [`InferenceClient::stream_chat`]: crate::InferenceClient::stream_chat +/// [`AssistantClient::stream_chat`]: crate::AssistantClient::stream_chat #[must_use = "a token stream does nothing unless polled"] pub struct TokenStream { inner: BoxStream<'static, Result>, diff --git a/crates/nvisy-inference/src/client/turn.rs b/crates/nvisy-assistant/src/client/turn.rs similarity index 100% rename from crates/nvisy-inference/src/client/turn.rs rename to crates/nvisy-assistant/src/client/turn.rs diff --git a/crates/nvisy-inference/src/error.rs b/crates/nvisy-assistant/src/error.rs similarity index 71% rename from crates/nvisy-inference/src/error.rs rename to crates/nvisy-assistant/src/error.rs index 2c996fb7..cd4099bc 100644 --- a/crates/nvisy-inference/src/error.rs +++ b/crates/nvisy-assistant/src/error.rs @@ -1,4 +1,4 @@ -//! Error types for LLM inference operations. +//! Error types for assistant language-model operations. /// A result whose error is the crate [`Error`]. pub type Result = std::result::Result; @@ -9,14 +9,14 @@ pub type Result = std::result::Result; pub enum Error { /// The client could not be constructed from the config (e.g. an invalid /// base URL). - #[error("failed to build the inference client: {0}")] + #[error("failed to build the assistant client: {0}")] Build(String), /// The provider rejected the credentials or was unreachable. - #[error("inference provider verification failed: {0}")] + #[error("provider verification failed: {0}")] Verify(String), /// A completion request against the provider failed at runtime. - #[error("inference request failed: {0}")] + #[error("assistant request failed: {0}")] Prompt(String), } diff --git a/crates/nvisy-inference/src/lib.rs b/crates/nvisy-assistant/src/lib.rs similarity index 73% rename from crates/nvisy-inference/src/lib.rs rename to crates/nvisy-assistant/src/lib.rs index 6455393b..077cdfdc 100644 --- a/crates/nvisy-inference/src/lib.rs +++ b/crates/nvisy-assistant/src/lib.rs @@ -7,7 +7,7 @@ mod error; pub mod provider; pub use client::{ - AuthenticatedProvider, ChatTurn, InferenceClient, InferenceConfig, LlmConfig, Role, + AssistantClient, AssistantConfig, AuthenticatedProvider, ChatTurn, LlmConfig, Role, TokenStream, UnauthenticatedProvider, }; pub use error::{Error, Result}; diff --git a/crates/nvisy-inference/src/provider/anthropic.rs b/crates/nvisy-assistant/src/provider/anthropic.rs similarity index 95% rename from crates/nvisy-inference/src/provider/anthropic.rs rename to crates/nvisy-assistant/src/provider/anthropic.rs index 6c99368a..af1951c3 100644 --- a/crates/nvisy-inference/src/provider/anthropic.rs +++ b/crates/nvisy-assistant/src/provider/anthropic.rs @@ -7,7 +7,7 @@ use rig::providers::anthropic::{self, AnthropicConfig}; use super::{Client, map_verify}; use crate::error::Result; -/// Anthropic-backed inference client. +/// Anthropic-backed assistant client. pub struct AnthropicProvider(anthropic::Anthropic); impl Client for AnthropicProvider { diff --git a/crates/nvisy-inference/src/provider/mod.rs b/crates/nvisy-assistant/src/provider/mod.rs similarity index 83% rename from crates/nvisy-inference/src/provider/mod.rs rename to crates/nvisy-assistant/src/provider/mod.rs index 29678fee..a3d5c691 100644 --- a/crates/nvisy-inference/src/provider/mod.rs +++ b/crates/nvisy-assistant/src/provider/mod.rs @@ -1,4 +1,4 @@ -//! Inference provider clients and the dispatch trait over them. +//! LLM provider clients and the dispatch trait over them. mod anthropic; mod ollama; @@ -12,15 +12,15 @@ use rig::agent::AgentBuilder; use rig::error::ProviderError; use rig::operation::Completion; -use crate::client::InferenceClient; +use crate::client::AssistantClient; use crate::error::{Error, Result}; -/// An inference provider that builds a verifiable, prompt-capable client from +/// An LLM provider that builds a verifiable, prompt-capable client from /// typed credentials. /// /// Each provider is a newtype wrapping its rig client. [`verify`](Client::verify) /// checks its credentials, and [`model`](Client::model) turns it into a -/// provider-agnostic `InferenceClient`. +/// provider-agnostic `AssistantClient`. pub(crate) trait Client: Send + Sync + 'static { /// The credential this provider connects with. A single-secret provider uses /// `str` (the API key); a keyless one (Ollama) uses a unit type. @@ -44,10 +44,10 @@ pub(crate) trait Client: Send + Sync + 'static { /// the agent builder. fn completion_model(&self, model: &str) -> DynModel; - /// Turn this provider client into a provider-agnostic [`InferenceClient`] + /// Turn this provider client into a provider-agnostic [`AssistantClient`] /// bound to `model`. - fn model(&self, model: &str) -> InferenceClient { - InferenceClient::new(AgentBuilder::new(self.completion_model(model)).build()) + fn model(&self, model: &str) -> AssistantClient { + AssistantClient::new(AgentBuilder::new(self.completion_model(model)).build()) } } diff --git a/crates/nvisy-inference/src/provider/ollama.rs b/crates/nvisy-assistant/src/provider/ollama.rs similarity index 92% rename from crates/nvisy-inference/src/provider/ollama.rs rename to crates/nvisy-assistant/src/provider/ollama.rs index 2d5ef7f9..8dc5c5af 100644 --- a/crates/nvisy-inference/src/provider/ollama.rs +++ b/crates/nvisy-assistant/src/provider/ollama.rs @@ -10,7 +10,7 @@ use rig::providers::ollama::{self, OllamaConfig}; use super::{Client, OllamaCredentials, map_verify}; use crate::error::Result; -/// Ollama-backed inference client. +/// Ollama-backed assistant client. pub struct OllamaProvider(ollama::Ollama); impl Client for OllamaProvider { @@ -29,7 +29,7 @@ impl Client for OllamaProvider { /// Ollama is unauthenticated, so there is no credential to check, but the /// daemon still has to be reachable at the configured base URL. Probe it by /// listing models (`GET /api/tags`); an unreachable server or a wrong URL - /// fails here rather than at the first inference request. + /// fails here rather than at the first assistant request. async fn verify(&self) -> Result<()> { map_verify(self.0.list_models().await.map(|_| ())) } diff --git a/crates/nvisy-inference/src/provider/openai.rs b/crates/nvisy-assistant/src/provider/openai.rs similarity index 96% rename from crates/nvisy-inference/src/provider/openai.rs rename to crates/nvisy-assistant/src/provider/openai.rs index 88c70dfb..b8bccb2e 100644 --- a/crates/nvisy-inference/src/provider/openai.rs +++ b/crates/nvisy-assistant/src/provider/openai.rs @@ -9,7 +9,7 @@ use rig::providers::openai::{self, OpenAIConfig}; use super::{Client, map_verify}; use crate::error::Result; -/// OpenAI-backed inference client. +/// OpenAI-backed assistant client. pub struct OpenAiProvider(openai::OpenAI); impl Client for OpenAiProvider { diff --git a/crates/nvisy-server/Cargo.toml b/crates/nvisy-server/Cargo.toml index 39b5e6ff..7702e148 100644 --- a/crates/nvisy-server/Cargo.toml +++ b/crates/nvisy-server/Cargo.toml @@ -63,7 +63,7 @@ elide-pipeline = { workspace = true, features = [ # Internal crates nvisy-core = { workspace = true, features = ["schema"] } nvisy-nats = { workspace = true, features = [] } -nvisy-inference = { workspace = true, features = ["schema"] } +nvisy-assistant = { workspace = true, features = ["schema"] } nvisy-object-store = { workspace = true, features = ["schema"] } nvisy-file-service = { workspace = true, features = ["schema"] } nvisy-postgres = { workspace = true, features = ["schema"] } diff --git a/crates/nvisy-server/src/response/error/inference_error.rs b/crates/nvisy-server/src/response/error/assistant_error.rs similarity index 67% rename from crates/nvisy-server/src/response/error/inference_error.rs rename to crates/nvisy-server/src/response/error/assistant_error.rs index 69ccf6e4..53818e13 100644 --- a/crates/nvisy-server/src/response/error/inference_error.rs +++ b/crates/nvisy-server/src/response/error/assistant_error.rs @@ -1,14 +1,14 @@ -//! Inference error to HTTP error conversion. +//! Assistant error to HTTP error conversion. //! -//! Maps `nvisy_inference::Error` onto an HTTP error. Building the provider +//! Maps `nvisy_assistant::Error` onto an HTTP error. Building the provider //! client or a completion failing at runtime is a server-side fault (the stored //! connection is the operator's config, not the caller's input), so it surfaces //! as an internal error with the provider's own message as context. use super::http_error::{Error as HttpError, ErrorKind}; -impl From for HttpError<'_> { - fn from(error: nvisy_inference::Error) -> Self { +impl From for HttpError<'_> { + fn from(error: nvisy_assistant::Error) -> Self { ErrorKind::InternalServerError .with_message("Language model request failed") .with_context(error.to_string()) diff --git a/crates/nvisy-server/src/response/error/mod.rs b/crates/nvisy-server/src/response/error/mod.rs index ec0f1df6..f84767bb 100644 --- a/crates/nvisy-server/src/response/error/mod.rs +++ b/crates/nvisy-server/src/response/error/mod.rs @@ -2,12 +2,12 @@ //! serialized [`ErrorResponse`] body, plus the `From` conversions that turn each //! infrastructure error into an [`Error`] at the request boundary. +mod assistant_error; mod crypto_error; mod engine_error; mod error_response; mod file_service_error; mod http_error; -mod inference_error; mod nats_error; mod object_error; mod oidc_error; diff --git a/crates/nvisy-server/src/service/integration/provider_config.rs b/crates/nvisy-server/src/service/integration/provider_config.rs index 07997625..53d5d582 100644 --- a/crates/nvisy-server/src/service/integration/provider_config.rs +++ b/crates/nvisy-server/src/service/integration/provider_config.rs @@ -1,6 +1,6 @@ //! Inference-provider configuration. //! -//! A provider's stored config is an [`InferenceConfig`] — the inference family +//! A provider's stored config is an [`AssistantConfig`] — the inference family //! (a language model today, other model kinds later). The outer enum is untagged, //! so on the wire it is flat: the inner config's own `provider` tag is the sole //! discriminator (`{ "provider": "openai", ... }`). This is the inference analog @@ -9,8 +9,8 @@ //! //! [`ConnectionConfig`]: super::ConnectionConfig +use nvisy_assistant::AssistantConfig; use nvisy_core::net::EndpointPolicy; -use nvisy_inference::InferenceConfig; use nvisy_postgres::types::ProviderType; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -21,12 +21,12 @@ use crate::response::{ErrorKind, Result}; /// /// Untagged: the inner config's `provider` tag is the sole discriminator, so the /// stored/wire form is flat. A new inference kind is added as a variant of -/// [`InferenceConfig`] with no change here. +/// [`AssistantConfig`] with no change here. #[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)] #[serde(untagged)] pub enum ProviderConfig { /// An inference connection (an LLM today; other model kinds later). - Inference(InferenceConfig), + Inference(AssistantConfig), } impl ProviderConfig { @@ -45,7 +45,7 @@ impl ProviderConfig { pub fn provider_type(&self) -> ProviderType { match self { Self::Inference(config) => match config { - InferenceConfig::Llm(_) => ProviderType::Llm, + AssistantConfig::Llm(_) => ProviderType::Llm, }, } } @@ -79,7 +79,7 @@ impl ProviderConfig { /// # Errors /// /// Returns the inference error describing the build or verification failure. - pub async fn validate(&self) -> nvisy_inference::Result<()> { + pub async fn validate(&self) -> nvisy_assistant::Result<()> { match self { Self::Inference(config) => config.validate().await, } diff --git a/crates/nvisy-server/src/worker/assistant/worker.rs b/crates/nvisy-server/src/worker/assistant/worker.rs index fa6ccc54..6e85c16c 100644 --- a/crates/nvisy-server/src/worker/assistant/worker.rs +++ b/crates/nvisy-server/src/worker/assistant/worker.rs @@ -11,7 +11,7 @@ use std::num::NonZero; use std::sync::Arc; use std::time::Duration; -use nvisy_inference::{ChatTurn, InferenceClient, InferenceConfig}; +use nvisy_assistant::{AssistantClient, AssistantConfig, ChatTurn}; use nvisy_postgres::model::{NewWorkspaceReviewComment, WorkspaceReview, WorkspaceReviewComment}; use nvisy_postgres::query::{ EventOutboxRepository, WorkspaceProviderRepository, WorkspaceReviewCommentRepository, @@ -321,7 +321,7 @@ impl AssistantWorker { &self, conn: &mut PgConn, workspace_id: Uuid, - ) -> Result { + ) -> Result { let provider = conn .find_provider_by_type(workspace_id, ProviderType::Llm) .await? @@ -335,7 +335,7 @@ impl AssistantWorker { .decrypt_json(workspace_id, &provider.encrypted_data)?; let llm = match config { - ProviderConfig::Inference(InferenceConfig::Llm(llm)) => llm, + ProviderConfig::Inference(AssistantConfig::Llm(llm)) => llm, }; llm.connect(None).map_err(|err| { diff --git a/docker/README.md b/docker/README.md index 5d86821c..c0e592ad 100644 --- a/docker/README.md +++ b/docker/README.md @@ -30,7 +30,7 @@ compose files provision it with a one-shot init container. Start PostgreSQL, NATS, and RustFS for local development: ```bash -docker compose -f docker-compose.dev.yml up -d +docker compose -f compose.yaml up -d ``` This starts the services with development defaults (`postgres:postgres` @@ -43,6 +43,16 @@ make generate-all # .env, keys, migrations cargo run --features dotenv --bin nvisy-cli ``` +#### Optional: NER (GLiNER2) + +The `ner` compose profile adds the GLiNER2 NER/PII service (`elide-ner`), which +the engine config reaches at `http://localhost:3200` by default. Its published +port binds to localhost only. `make run NER=1` brings it up and runs the server +with `engine.dev.toml`, substituting `ELIDE_NER_PORT` into a temporary config so +custom port settings stay in sync; the first start downloads the +model (~1.2 GB) into the `hf_cache` volume via a one-shot `ner-init` warmer. Set +`ELIDE_NER_MODEL`, `ELIDE_NER_PORT`, or `ELIDE_VERSION` to override the defaults. + The API documentation is available at: - Scalar UI: `http://localhost:8080/api/scalar` diff --git a/docker/docker-compose.yml b/docker/compose.prod.yaml similarity index 100% rename from docker/docker-compose.yml rename to docker/compose.prod.yaml diff --git a/docker/docker-compose.dev.yml b/docker/compose.yaml similarity index 51% rename from docker/docker-compose.dev.yml rename to docker/compose.yaml index f8d3d678..e9d30c14 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/compose.yaml @@ -96,10 +96,79 @@ services: networks: - nvisy-dev + # Warms the NER model into the shared Hugging Face cache and exits. The + # elide-ner image carries no weights, so this one-shot `elide_ner.warm` run + # downloads them first (as root, to populate the fresh named volume, which it + # hands to the uid the service runs as); the service gates on it completing. + # Not started by `make run`'s default set — bring NER up with the `ner` + # profile (`make run-ner`). + ner-init: + image: ${ELIDE_NER_IMAGE:-ghcr.io/nvisycom/elide-ner}:${ELIDE_VERSION:-0.1.0-rc.6} + container_name: nvisy-ner-init-dev + profiles: ["ner"] + # The warmer is the one process that must reach the Hub; the service then + # runs offline against the cache it leaves behind. + user: root + environment: + HF_HOME: /cache/huggingface + HF_HUB_OFFLINE: "0" + TRANSFORMERS_OFFLINE: "0" + ELIDE_BENTO_NER_MODEL: ${ELIDE_NER_MODEL:-fastino/gliner2-privacy-filter-PII-multi} + entrypoint: ["python", "-m", "elide_ner.warm"] + volumes: + - hf_cache:/cache/huggingface + networks: + - nvisy-dev + + # GLiNER2 schema-driven NER/PII service. The host-run server reaches it at + # localhost:3200 (ELIDE_NER_PORT); point the engine config's NER recognizer + # there. The host port is 3200, not the service's own 3000, so this coexists + # with a standalone elide-runtime stack (which publishes NER on 3100). The + # service runs as a non-root uid with the cache read-only and HF_HUB_OFFLINE + # on, so request text never reaches the Hub. + ner: + image: ${ELIDE_NER_IMAGE:-ghcr.io/nvisycom/elide-ner}:${ELIDE_VERSION:-0.1.0-rc.6} + container_name: nvisy-ner-dev + profiles: ["ner"] + restart: unless-stopped + ports: + - "127.0.0.1:${ELIDE_NER_PORT:-3200}:3000" + environment: + HF_HOME: /cache/huggingface + HF_HUB_OFFLINE: "1" + TRANSFORMERS_OFFLINE: "1" + ELIDE_BENTO_NER_MODEL: ${ELIDE_NER_MODEL:-fastino/gliner2-privacy-filter-PII-multi} + ELIDE_BENTO_NER_QUANTIZE: ${ELIDE_NER_QUANTIZE:-} + ELIDE_BENTO_NER_MAX_TOKENS: ${ELIDE_NER_MAX_TOKENS:-512} + LOG_LEVEL: ${ELIDE_LOG_LEVEL:-INFO} + volumes: + - hf_cache:/cache/huggingface:ro + # The bentoml image ships no curl/wget, so /readyz is probed with Python. + # The model loads in __init__, so readiness lags liveness; the long + # start_period covers a cold load without flapping. + healthcheck: + test: + - CMD + - python + - -c + - "import urllib.request; urllib.request.urlopen('http://localhost:3000/readyz', timeout=5)" + interval: 10s + timeout: 5s + retries: 5 + start_period: 120s + depends_on: + ner-init: + condition: service_completed_successfully + networks: + - nvisy-dev + volumes: postgres_data: nats_data: rustfs_data: + # Hugging Face cache the NER init container populates and the service mounts + # read-only; keeps the model weights out of the image and off repeat pulls. + hf_cache: networks: nvisy-dev: diff --git a/docker/engine.dev.toml b/docker/engine.dev.toml new file mode 100644 index 00000000..65d03e31 --- /dev/null +++ b/docker/engine.dev.toml @@ -0,0 +1,16 @@ +# Dev engine configuration: NER only. +# +# Point the server at this file with ENGINE_CONFIG_FILEPATH to run the GLiNER2 +# NER recognizer from the `ner` compose profile. The server runs on the host +# (`make run`), so it reaches the service at the published host port, not the +# compose hostname. See docker/engine.example.toml for the full lineup (LLM, +# OCR, STT). + +# GLiNER2 schema-driven NER/PII. Served by the `ner` service in +# docker/compose.yaml (profile `ner`), published on host port 3200 by default. +# `make run NER=1` substitutes ELIDE_NER_PORT when generating this config. +[[recognizers.ner]] +name = "gliner2-ner" +kind = "bento" +base_url = "http://localhost:${ELIDE_NER_PORT:-3200}" +model = "fastino/gliner2-privacy-filter-PII-multi" diff --git a/docker/rustfs/init.sh b/docker/rustfs/init.sh index 09343dd1..78b31420 100755 --- a/docker/rustfs/init.sh +++ b/docker/rustfs/init.sh @@ -1,6 +1,6 @@ #!/bin/sh # Provisions the first-party bucket in RustFS (which does not auto-create -# buckets). Shared by docker-compose.dev.yml and docker-compose.yml, mounted +# buckets). Shared by compose.yaml and compose.prod.yaml, mounted # read-only and run by the rustfs-init container. Idempotent: safe to re-run. # # Configuration comes from the environment (never interpolated into a shell diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 350007c6..d84f55e3 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -30,7 +30,7 @@ The Rust workspace contains these crates, each with a single responsibility: | `nvisy-s3` | First-party blob storage over an S3-compatible backend | | `nvisy-object-store` | Providers for external object stores (S3, Azure, GCS) | | `nvisy-file-service` | OAuth-based cloud file services (Google Drive, ...) | -| `nvisy-inference` | LLM inference provider configuration and clients | +| `nvisy-assistant` | LLM assistant engine and provider clients | | `nvisy-postgres` | PostgreSQL ORM layer using Diesel with async support | | `nvisy-server` | HTTP API handlers, middleware, authentication | | `nvisy-webhook` | Webhook delivery for external event notification |