From c9dc62d9128db712ada5d73b8c52f68f04bd73d2 Mon Sep 17 00:00:00 2001 From: Aaron Friel Date: Sat, 30 Mar 2024 10:10:52 +0000 Subject: [PATCH 1/8] Refactor AICI to use WebAssembly Component Model This is a significant change to the AICI Runtime (host) and AICI Controller (guest) to use WASI components. As part of this change, a significant amount of unsafe code is removed and the protocol is simplified to remove the need for "BLOB" types and side-channels. The protocol is documented in `wit/controller.wit`, and a minimal WASI runtime is provided to AI CI controllers. Some notes: * The AICI runtime now longer directly reads and writes to the guest's memory. Instead, the guest provides a `Runner` resource (using WebAssembly Component terminology), which exposes the low-level protocol to the host as a constructor and trait with methods. * The Blob protocols are removed entirely, replaced by the `Runner` resource. This and other side-channels for communicating with the runtime, e.g. allowed tokens (logit biases) outside of `MidProcessResult`, are removed. * The (Variable) Storage and Tokenizer protocols are separate WebAssembly Components, which can be versioned independently of the runtime. * Types are changed to be consistent with the WebAssembly interface, e.g.: `SeqId` is used in far more places to avoid casts. --- .devcontainer/Dockerfile-prod-vllm | 2 +- .devcontainer/common.dockerfile | 2 +- .github/workflows/aicirt-release.yml | 2 +- .github/workflows/aicirt.yml | 2 +- Cargo.lock | 1978 +++++++++++------ Cargo.toml | 3 + README.md | 20 +- aicirt/Cargo.toml | 6 +- aicirt/src/api.rs | 13 +- aicirt/src/bench.rs | 2 +- aicirt/src/bindings.rs | 2 + aicirt/src/hostimpl.rs | 514 ++--- aicirt/src/lib.rs | 1 + aicirt/src/main.rs | 102 +- aicirt/src/moduleinstance.rs | 221 +- aicirt/src/msgchannel.rs | 5 +- aicirt/src/worker.rs | 18 +- controllers/aici_abi/.cargo/config.toml | 2 +- controllers/aici_abi/Cargo.toml | 5 +- controllers/aici_abi/src/bindings.rs | 1 + controllers/aici_abi/src/cfg.rs | 5 +- controllers/aici_abi/src/host.rs | 322 +-- controllers/aici_abi/src/lib.rs | 224 +- controllers/aici_abi/src/recognizer.rs | 143 ++ controllers/aici_abi/src/substring.rs | 1 - controllers/aici_native/src/variables.rs | 5 +- controllers/aici_wasm_guest/Cargo.toml | 8 + controllers/aici_wasm_guest/src/lib.rs | 8 + controllers/aici_wasm_host/Cargo.toml | 9 + controllers/aici_wasm_host/src/lib.rs | 46 + controllers/declctrl/.cargo/config.toml | 2 +- controllers/declctrl/Cargo.toml | 5 +- .../declctrl/src/{declctrl.rs => lib.rs} | 83 +- controllers/declctrl/wasm.sh | 2 +- controllers/guidance_ctrl/src/earley_bench.rs | 11 + controllers/jsctrl/.cargo/config.toml | 2 +- controllers/jsctrl/Cargo.toml | 5 +- controllers/jsctrl/src/{jsctrl.rs => lib.rs} | 82 +- .../llguidance_ctrl/.cargo/config.toml | 2 +- controllers/pyctrl/.cargo/config.toml | 2 +- controllers/pyctrl/Cargo.toml | 5 +- controllers/pyctrl/src/{pyctrl.rs => lib.rs} | 77 +- controllers/pyctrl/wasm.sh | 2 +- controllers/uppercase/.cargo/config.toml | 2 +- controllers/uppercase/README.md | 2 +- controllers/uppercase/src/main.rs | 20 +- controllers/yesno/.cargo/config.toml | 8 + controllers/yesno/Cargo.toml | 17 + .../src/yesno.rs => yesno/src/lib.rs} | 21 +- py/pyaici/cli.py | 21 +- py/tests/conftest.py | 2 +- rllm/llama-cpp-low/Cargo.toml | 8 +- rllm/rllm-base/src/engine.rs | 15 +- rllm/rllm-base/src/exec.rs | 20 +- rllm/rllm-base/src/iface/aici.rs | 0 .../src/{iface.rs => iface/aicirt.rs} | 3 +- rllm/rllm-base/src/iface/mod.rs | 1 + rllm/rllm-base/src/scheduler.rs | 7 +- rllm/rllm-base/src/seq.rs | 6 +- rllm/rllm-base/src/server/mod.rs | 4 +- rllm/rllm-cuda/src/llm/paged/batch_info.rs | 9 +- rllm/rllm-cuda/src/llm/paged/blocks.rs | 2 +- rllm/rllm-cuda/src/llm/tmodel.rs | 4 +- rllm/rllm-llamacpp/src/llamacpp/seqid.rs | 2 +- rllm/rllm-llamacpp/src/llamacpp/tmodel.rs | 8 +- rust-toolchain.toml | 2 + scripts/release.sh | 6 +- scripts/sample-yesno.sh | 2 +- scripts/upload-all.sh | 4 +- wit/controller.wit | 53 + wit/package.wit | 10 + wit/runtime-storage.wit | 5 + wit/runtime.wit | 9 + wit/tokenizer.wit | 11 + 74 files changed, 2208 insertions(+), 2028 deletions(-) create mode 100644 aicirt/src/bindings.rs create mode 100644 controllers/aici_abi/src/bindings.rs create mode 100644 controllers/aici_abi/src/recognizer.rs create mode 100644 controllers/aici_wasm_guest/Cargo.toml create mode 100644 controllers/aici_wasm_guest/src/lib.rs create mode 100644 controllers/aici_wasm_host/Cargo.toml create mode 100644 controllers/aici_wasm_host/src/lib.rs rename controllers/declctrl/src/{declctrl.rs => lib.rs} (95%) create mode 100644 controllers/guidance_ctrl/src/earley_bench.rs rename controllers/jsctrl/src/{jsctrl.rs => lib.rs} (88%) rename controllers/pyctrl/src/{pyctrl.rs => lib.rs} (91%) create mode 100644 controllers/yesno/.cargo/config.toml create mode 100644 controllers/yesno/Cargo.toml rename controllers/{aici_abi/src/yesno.rs => yesno/src/lib.rs} (60%) create mode 100644 rllm/rllm-base/src/iface/aici.rs rename rllm/rllm-base/src/{iface.rs => iface/aicirt.rs} (99%) create mode 100644 rllm/rllm-base/src/iface/mod.rs create mode 100644 rust-toolchain.toml create mode 100644 wit/controller.wit create mode 100644 wit/package.wit create mode 100644 wit/runtime-storage.wit create mode 100644 wit/runtime.wit create mode 100644 wit/tokenizer.wit diff --git a/.devcontainer/Dockerfile-prod-vllm b/.devcontainer/Dockerfile-prod-vllm index bc7d2e06..a2977f26 100644 --- a/.devcontainer/Dockerfile-prod-vllm +++ b/.devcontainer/Dockerfile-prod-vllm @@ -2,7 +2,7 @@ FROM rust:1.75.0-bookworm AS aicirt WORKDIR /workspace -RUN rustup target add wasm32-wasi +RUN rustup target add wasm32-wasip2 RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - RUN apt-get install -y nodejs diff --git a/.devcontainer/common.dockerfile b/.devcontainer/common.dockerfile index ce43aaf8..d9269b8e 100644 --- a/.devcontainer/common.dockerfile +++ b/.devcontainer/common.dockerfile @@ -31,7 +31,7 @@ ENV RUSTUP_HOME=/usr/local/rustup \ RUN curl https://sh.rustup.rs -sSf | sh -s -- \ -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION -RUN rustup target add wasm32-wasi +RUN rustup target add wasm32-wasip2 RUN rustup component add rustfmt # run as root please; note that settings in devcontainer.json are also needed... diff --git a/.github/workflows/aicirt-release.yml b/.github/workflows/aicirt-release.yml index e4304830..a67fe694 100644 --- a/.github/workflows/aicirt-release.yml +++ b/.github/workflows/aicirt-release.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - run: rustup target add wasm32-wasi + - run: rustup target add wasm32-wasip2 - uses: hendrikmuhs/ccache-action@v1.2 - uses: Swatinem/rust-cache@v2 with: diff --git a/.github/workflows/aicirt.yml b/.github/workflows/aicirt.yml index 5558a1b2..f9c44080 100644 --- a/.github/workflows/aicirt.yml +++ b/.github/workflows/aicirt.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - run: rustup target add wasm32-wasi + - run: rustup target add wasm32-wasip2 - uses: hendrikmuhs/ccache-action@v1.2 - uses: Swatinem/rust-cache@v2 with: diff --git a/Cargo.lock b/Cargo.lock index f123a28a..2e345bca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,11 +10,11 @@ checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" [[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.6.0", "bytes", "futures-core", "futures-sink", @@ -27,17 +27,17 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.5.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129d4c88e98860e1758c5de288d1632b07970a16d59bdf7b8d66053d582bb71f" +checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-utils", "ahash", - "base64 0.21.5", - "bitflags 2.4.1", + "base64 0.22.1", + "bitflags 2.6.0", "brotli", "bytes", "bytestring", @@ -61,7 +61,7 @@ dependencies = [ "tokio", "tokio-util", "tracing", - "zstd 0.13.0", + "zstd 0.13.2", ] [[package]] @@ -71,27 +71,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] name = "actix-router" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511" +checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", + "cfg-if", "http", "regex", + "regex-lite", "serde", "tracing", ] [[package]] name = "actix-rt" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" dependencies = [ "futures-core", "tokio", @@ -99,9 +101,9 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" +checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894" dependencies = [ "actix-rt", "actix-service", @@ -137,9 +139,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.4.1" +version = "4.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43428f3bf11dee6d166b00ec2df4e3aa8cc1606aaa0b7433c146852e2f4e03b" +checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" dependencies = [ "actix-codec", "actix-http", @@ -159,6 +161,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", + "impl-more", "itoa", "language-tags", "log", @@ -166,6 +169,7 @@ dependencies = [ "once_cell", "pin-project-lite", "regex", + "regex-lite", "serde", "serde_json", "serde_urlencoded", @@ -177,21 +181,21 @@ dependencies = [ [[package]] name = "actix-web-codegen" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" +checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -202,11 +206,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -228,9 +238,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -239,12 +249,13 @@ dependencies = [ name = "aici_abi" version = "0.1.0" dependencies = [ + "aici_wasm_guest", "anyhow", "bytemuck", "bytemuck_derive", "cfgrammar", "lrtable", - "regex-automata 0.4.6", + "regex-automata 0.4.7", "rustc-hash 2.0.0", "serde", "serde_json", @@ -327,15 +338,41 @@ dependencies = [ "anyhow", ] +[[package]] +name = "aici_wasm_guest" +version = "0.1.0" +dependencies = [ + "serde", + "wit-bindgen", +] + +[[package]] +name = "aici_wasm_host" +version = "0.1.0" +dependencies = [ + "serde", + "toktrie", + "wasmtime", +] + +[[package]] +name = "aici_yesno" +version = "0.1.0" +dependencies = [ + "aici_abi", +] + [[package]] name = "aicirt" version = "0.1.0" dependencies = [ "aici_abi", "aici_native", + "aici_wasm_host", "anyhow", - "base64 0.21.5", + "base64 0.21.7", "bincode", + "bytemuck", "cap", "clap", "hex", @@ -353,6 +390,7 @@ dependencies = [ "ureq", "uuid", "wasmtime", + "wasmtime-wasi", ] [[package]] @@ -376,6 +414,12 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +[[package]] +name = "ambient-authority" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -393,47 +437,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -441,9 +486,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" dependencies = [ "backtrace", ] @@ -460,6 +505,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" +[[package]] +name = "async-trait" +version = "0.1.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.76", +] + [[package]] name = "atty" version = "0.2.14" @@ -473,21 +529,21 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] @@ -500,9 +556,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -521,25 +583,22 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.2" +version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c69fae65a523209d34240b60abe0c42d33d1045d445c0839d8a4894a736e2d" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "cexpr", "clang-sys", - "lazy_static", - "lazycell", + "itertools 0.13.0", "log", - "peeking_take_while", "prettyplease", "proc-macro2", "quote", "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.46", - "which", + "syn 2.0.76", ] [[package]] @@ -550,9 +609,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -565,9 +624,9 @@ dependencies = [ [[package]] name = "brotli" -version = "3.4.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -576,9 +635,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -597,9 +656,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", "serde", @@ -607,25 +666,25 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" +checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" [[package]] name = "bytemuck_derive" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "369cfaf2a5bed5d8f8202073b2e093c9f508251de1551a0deb4253e4c7d80909" +checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] @@ -636,9 +695,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "bytestring" @@ -676,6 +735,83 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f125eb85b84a24c36b02ed1d22c9dd8632f53b3cde6e4d23512f94021030003" +[[package]] +name = "cap-fs-ext" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb23061fc1c4ead4e45ca713080fe768e6234e959f5a5c399c39eb41aa34e56e" +dependencies = [ + "cap-primitives", + "cap-std", + "io-lifetimes", + "windows-sys 0.52.0", +] + +[[package]] +name = "cap-net-ext" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83ae11f116bcbafc5327c6af250341db96b5930046732e1905f7dc65887e0e1" +dependencies = [ + "cap-primitives", + "cap-std", + "rustix", + "smallvec", +] + +[[package]] +name = "cap-primitives" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d00bd8d26c4270d950eaaa837387964a2089a1c3c349a690a1fa03221d29531" +dependencies = [ + "ambient-authority", + "fs-set-times", + "io-extras", + "io-lifetimes", + "ipnet", + "maybe-owned", + "rustix", + "windows-sys 0.52.0", + "winx", +] + +[[package]] +name = "cap-rand" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbcb16a619d8b8211ed61f42bd290d2a1ac71277a69cf8417ec0996fa92f5211" +dependencies = [ + "ambient-authority", + "rand", +] + +[[package]] +name = "cap-std" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19eb8e3d71996828751c1ed3908a439639752ac6bdc874e41469ef7fc15fbd7f" +dependencies = [ + "cap-primitives", + "io-extras", + "io-lifetimes", + "rustix", +] + +[[package]] +name = "cap-time-ext" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61142dc51e25b7acc970ca578ce2c3695eac22bbba46c1073f5f583e78957725" +dependencies = [ + "ambient-authority", + "cap-primitives", + "iana-time-zone", + "once_cell", + "rustix", + "winx", +] + [[package]] name = "caseless" version = "0.2.1" @@ -688,12 +824,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -713,11 +850,11 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfgrammar" -version = "0.13.3" +version = "0.13.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41879646bd1fbd55efdb9e2c1ac85e63856ad951e4e14b2e3086374802a13e9b" +checksum = "6026d8cd82ada8bbcfe337805dd1eb6afdc9e80fa4d57e977b3a36315e0c5525" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.4.0", "lazy_static", "num-traits", "regex", @@ -727,16 +864,16 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -751,9 +888,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", @@ -762,9 +899,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" dependencies = [ "clap_builder", "clap_derive", @@ -772,33 +909,33 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clipboard-win" @@ -813,30 +950,36 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.50" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" dependencies = [ "cc", ] +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] @@ -883,36 +1026,47 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c22542c0b95bd3302f7ed6839869c561f2324bac2fd5e7e99f5cfa65fdc8b92" +checksum = "b80c3a50b9c4c7e5b5f73c0ed746687774fc9e36ef652b110da8daebf0c6e0e6" dependencies = [ "cranelift-entity", ] +[[package]] +name = "cranelift-bitset" +version = "0.111.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38778758c2ca918b05acb2199134e0c561fb577c50574259b26190b6c2d95ded" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "cranelift-codegen" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3db903ef2e9c8a4de2ea6db5db052c7857282952f9df604aa55d169e6000d8" +checksum = "58258667ad10e468bfc13a8d620f50dfcd4bb35d668123e97defa2549b9ad397" dependencies = [ "bumpalo", "cranelift-bforest", + "cranelift-bitset", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-control", @@ -922,49 +1076,51 @@ dependencies = [ "hashbrown 0.14.5", "log", "regalloc2", + "rustc-hash 1.1.0", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6590feb5a1d6438f974bf6a5ac4dddf69fca14e1f07f3265d880f69e61a94463" +checksum = "043f0b702e529dcb07ff92bd7d40e7d5317b5493595172c5eb0983343751ee06" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7239038c56fafe77fddc8788fc8533dd6c474dc5bdc5637216404f41ba807330" +checksum = "7763578888ab53eca5ce7da141953f828e82c2bfadcffc106d10d1866094ffbb" [[package]] name = "cranelift-control" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7dc9c595341404d381d27a3d950160856b35b402275f0c3990cd1ad683c8053" +checksum = "32db15f08c05df570f11e8ab33cb1ec449a64b37c8a3498377b77650bef33d8b" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44e3ee532fc4776c69bcedf7e62f9632cbb3f35776fa9a525cdade3195baa3f7" +checksum = "5289cdb399381a27e7bbfa1b42185916007c3d49aeef70b1d01cb4caa8010130" dependencies = [ + "cranelift-bitset", "serde", "serde_derive", ] [[package]] name = "cranelift-frontend" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a612c94d09e653662ec37681dc2d6fd2b9856e6df7147be0afc9aabb0abf19df" +checksum = "31ba8ab24eb9470477e98ddfa3c799a649ac5a0d9a2042868c4c952133c234e8" dependencies = [ "cranelift-codegen", "log", @@ -974,15 +1130,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85db9830abeb1170b7d29b536ffd55af1d4d26ac8a77570b5d1aca003bf225cc" +checksum = "2b72a3c5c166a70426dcb209bdd0bb71a787c1ea76023dc0974fbabca770e8f9" [[package]] name = "cranelift-native" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301ef0edafeaeda5771a5d2db64ac53e1818ae3111220a185677025fe91db4a1" +checksum = "46a42424c956bbc31fc5c2706073df896156c5420ae8fa2a5d48dbc7b295d71b" dependencies = [ "cranelift-codegen", "libc", @@ -991,14 +1147,14 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.103.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380f0abe8264e4570ac615fc31cef32a3b90a77f7eb97b08331f9dd357b1f500" +checksum = "49778df4289933d735b93c30a345513e030cf83101de0036e19b760f8aa09f68" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", - "itertools 0.10.5", + "itertools 0.12.1", "log", "smallvec", "wasmparser", @@ -1007,43 +1163,37 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.17" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.18" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1073,7 +1223,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9395df0cab995685664e79cc35ad6302bf08fb9c5d82301875a183affe1278b1" dependencies = [ - "half 2.3.1", + "half 2.4.1", ] [[package]] @@ -1096,7 +1246,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -1111,6 +1261,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derive_builder" version = "0.12.0" @@ -1144,15 +1303,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.76", ] [[package]] @@ -1161,11 +1320,11 @@ version = "0.1.0" dependencies = [ "ahash", "anyhow", - "bstr 1.9.1", + "bstr 1.10.0", "bytemuck", "bytemuck_derive", "hashbrown 0.14.5", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", "serde", "toml", ] @@ -1181,13 +1340,22 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys 0.3.7", +] + [[package]] name = "dirs" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ - "dirs-sys", + "dirs-sys 0.4.1", ] [[package]] @@ -1200,6 +1368,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys" version = "0.4.1" @@ -1225,21 +1404,21 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] -name = "embed-doc-image" -version = "0.1.4" +name = "embedded-io" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af36f591236d9d822425cb6896595658fa558fcebf5ee8accac1d4b92c47166e" -dependencies = [ - "base64 0.13.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" [[package]] name = "encode_unicode" @@ -1249,9 +1428,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -1270,9 +1449,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1311,9 +1490,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fd-lock" @@ -1326,25 +1505,35 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "fd-lock" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" +dependencies = [ + "cfg-if", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.8.0", ] [[package]] name = "flexi_logger" -version = "0.28.0" +version = "0.28.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f248c29a6d4bc5d065c9e9068d858761a0dcd796759f7801cc14db35db23abd8" +checksum = "cca927478b3747ba47f98af6ba0ac0daea4f12d12f55e9104071b3dc00276310" dependencies = [ "chrono", "glob", - "is-terminal", "log", "nu-ansi-term", "regex", @@ -1381,6 +1570,17 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs-set-times" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" +dependencies = [ + "io-lifetimes", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "futures" version = "0.3.30" @@ -1437,7 +1637,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] @@ -1491,9 +1691,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -1504,12 +1704,12 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" dependencies = [ "fallible-iterator", - "indexmap 2.1.0", + "indexmap 2.4.0", "stable_deref_trait", ] @@ -1531,7 +1731,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.4.0", "slab", "tokio", "tokio-util", @@ -1540,15 +1740,15 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "half" -version = "2.3.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" dependencies = [ "cfg-if", "crunchy", @@ -1580,6 +1780,7 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", + "serde", ] [[package]] @@ -1588,6 +1789,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1599,9 +1806,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1621,7 +1828,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b780635574b3d92f036890d8373433d6f9fc7abb320ee42a5c25897fc8ed732" dependencies = [ - "dirs", + "dirs 5.0.1", "indicatif", "log", "native-tls", @@ -1650,34 +1857,11 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "hoot" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df22a4d90f1b0e65fe3e0d6ee6a4608cc4d81f4b2eb3e670f44bb6bde711e452" -dependencies = [ - "httparse", - "log", -] - -[[package]] -name = "hootbin" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "354e60868e49ea1a39c44b9562ad207c4259dc6eabf9863bf3b0f058c55cfdb2" -dependencies = [ - "fastrand", - "hoot", - "serde", - "serde_json", - "thiserror", -] - [[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", @@ -1686,9 +1870,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1698,9 +1882,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1719,6 +1903,12 @@ dependencies = [ "cc", ] +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + [[package]] name = "ident_case" version = "1.0.1" @@ -1735,6 +1925,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "impl-more" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" + [[package]] name = "indexmap" version = "1.9.3" @@ -1747,9 +1943,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -1758,9 +1954,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", @@ -1793,76 +1989,102 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-extras" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9f046b9af244f13b3bd939f55d16830ac3a201e8a9ba9661bfcb03e2be72b9b" +dependencies = [ + "io-lifetimes", + "windows-sys 0.52.0", +] + +[[package]] +name = "io-lifetimes" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is-macro" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75828adcb53122ef5ea649a39f50f82d94b754099bf6331b32e255e1891e8fb" +checksum = "2069faacbe981460232f880d26bf3c7634e322d49053aa48c27e3ae642f728f1" dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] -name = "is-terminal" -version = "0.4.10" +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.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ - "hermit-abi 0.3.3", - "rustix", - "windows-sys 0.52.0", + "either", ] [[package]] name = "itertools" -version = "0.10.5" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itertools" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] [[package]] name = "lalrpop-util" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" [[package]] name = "language-tags" @@ -1872,15 +2094,9 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" [[package]] name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -1920,18 +2136,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.151" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.6", ] [[package]] @@ -1942,13 +2158,12 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "libc", - "redox_syscall", ] [[package]] @@ -1971,9 +2186,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "llama_cpp_low" @@ -2030,9 +2245,9 @@ checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2040,15 +2255,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lrtable" -version = "0.13.3" +version = "0.13.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310933a066b41ed437844d548c5972b02b407e63a8254d08204082a05f7a1b34" +checksum = "d42d2752cb50a171efadda0cb6fa97432e8bf05accfff3eed320b87e80a2f69e" dependencies = [ "cfgrammar", "fnv", @@ -2059,18 +2274,18 @@ dependencies = [ [[package]] name = "lz4_flex" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" +checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" dependencies = [ "twox-hash", ] [[package]] -name = "mach" -version = "0.3.2" +name = "mach2" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" dependencies = [ "libc", ] @@ -2093,9 +2308,9 @@ checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568" [[package]] name = "malachite" -version = "0.4.4" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "220cb36c52aa6eff45559df497abe0e2a4c1209f92279a746a399f622d7b95c7" +checksum = "905472e3a4adfc48b7a6eeb8beb7aba09e851b9e74ba53a4b53798e401b2badf" dependencies = [ "malachite-base", "malachite-nz", @@ -2104,11 +2319,13 @@ dependencies = [ [[package]] name = "malachite-base" -version = "0.4.4" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6538136c5daf04126d6be4899f7fe4879b7f8de896dd1b4210fe6de5b94f2555" +checksum = "e5f8d7930df6fcb9c86761ca0999ba484d7b6469c81cee4a7d38da5386440f96" dependencies = [ + "hashbrown 0.14.5", "itertools 0.11.0", + "libm", "ryu", ] @@ -2127,20 +2344,20 @@ dependencies = [ [[package]] name = "malachite-nz" -version = "0.4.4" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0b05577b7a3f09433106460b10304f97fc572f0baabf6640e6cb1e23f5fc52" +checksum = "fa263ca62420c1f65cf6758f55c979a49ad83169f332e602b1890f1e1277a429" dependencies = [ - "embed-doc-image", "itertools 0.11.0", + "libm", "malachite-base", ] [[package]] name = "malachite-q" -version = "0.4.4" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1cfdb4016292e6acd832eaee261175f3af8bbee62afeefe4420ebce4c440cb5" +checksum = "b7619384a5b9b54dd576ae5dd9a8a9438353ada4e50adf737c2e002088ba366e" dependencies = [ "itertools 0.11.0", "malachite-base", @@ -2161,19 +2378,25 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matrixmultiply" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" dependencies = [ "autocfg", "rawpointer", ] +[[package]] +name = "maybe-owned" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" + [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memfd" @@ -2186,9 +2409,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45fd3a57831bf88bc63f8cebc0cf956116276e97fef3966103e96416209f7c92" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" dependencies = [ "libc", ] @@ -2213,9 +2436,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] @@ -2234,30 +2457,40 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "log", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "monostate" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "878c2a1f1c70e5724fa28f101ca787b6a7e8ad5c5e4ae4ca3b0fa4a419fa9075" +checksum = "0d208407d7552cd041d8cdb69a1bc3303e029c598738177a3d87082004dc0e1e" dependencies = [ "monostate-impl", "serde", @@ -2265,22 +2498,21 @@ dependencies = [ [[package]] name = "monostate-impl" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f686d68a09079e63b1d2c64aa305095887ce50565f00a922ebfaeeee0d9ba6ce" +checksum = "a7ce64b975ed4f123575d11afd9491f2e37bbd5813fbfbc0f09ae1fbddea74e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -2339,37 +2571,42 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.49.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c073d3c1930d0751774acf49e66653acecb416c3a54c6ec095a9b11caddb5a68" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2381,7 +2618,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.9", "libc", ] @@ -2414,13 +2651,13 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.2" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "crc32fast", "hashbrown 0.14.5", - "indexmap 2.1.0", + "indexmap 2.4.0", "memchr", ] @@ -2458,7 +2695,7 @@ version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -2475,7 +2712,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] @@ -2520,9 +2757,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2530,15 +2767,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -2554,9 +2791,9 @@ dependencies = [ [[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 = "pbkdf2" @@ -2570,12 +2807,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "percent-encoding" version = "2.3.1" @@ -2622,9 +2853,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2634,9 +2865,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "pmutil" @@ -2651,24 +2882,45 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" + +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "prettyplease" -version = "0.2.16" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] @@ -2707,9 +2959,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.74" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -2732,7 +2984,7 @@ dependencies = [ "cfg-if", "indoc", "libc", - "memoffset 0.9.0", + "memoffset 0.9.1", "parking_lot", "portable-atomic", "pyo3-build-config", @@ -2770,7 +3022,7 @@ dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] @@ -2779,18 +3031,18 @@ version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "pyo3-build-config", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -2859,9 +3111,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -2880,9 +3132,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -2890,18 +3142,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -2923,14 +3175,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -2952,15 +3204,21 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.7.5" @@ -2969,15 +3227,15 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "relative-path" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "result-like" @@ -3003,16 +3261,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3023,10 +3282,10 @@ dependencies = [ "aici_abi", "aicirt", "anyhow", - "base64 0.21.5", + "base64 0.21.7", "clap", "futures", - "half 2.3.1", + "half 2.4.1", "hf-hub", "lazy_static", "libc", @@ -3034,7 +3293,7 @@ dependencies = [ "memmap2", "percent-encoding", "rand", - "safetensors 0.4.1", + "safetensors 0.4.4", "serde", "serde_json", "tokenizers", @@ -3056,7 +3315,7 @@ dependencies = [ "memmap2", "rand", "rllm", - "safetensors 0.4.1", + "safetensors 0.4.4", "serde", "serde_json", "tch", @@ -3103,13 +3362,13 @@ dependencies = [ "convert_case 0.6.0", "fnv", "ident_case", - "indexmap 2.1.0", + "indexmap 2.4.0", "proc-macro-crate", "proc-macro-error", "proc-macro2", "quote", "rquickjs-core", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] @@ -3122,9 +3381,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" @@ -3149,24 +3408,27 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "errno", + "itoa", "libc", "linux-raw-sys", + "once_cell", "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.22.4" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "log", + "once_cell", "ring", "rustls-pki-types", "rustls-webpki", @@ -3176,15 +3438,15 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.2.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a716eb65e3158e90e17cd93d855216e27bde02745ab842f2cab4a39dba1bacf" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring", "rustls-pki-types", @@ -3209,7 +3471,7 @@ version = "0.3.0" source = "git+https://github.com/RustPython/RustPython?rev=317f44945420e#317f44945420e78d8c490cbaa5f7a9a46852a81b" dependencies = [ "ahash", - "bitflags 2.4.1", + "bitflags 2.6.0", "indexmap 1.9.3", "itertools 0.11.0", "log", @@ -3226,7 +3488,7 @@ version = "0.3.0" source = "git+https://github.com/RustPython/RustPython?rev=317f44945420e#317f44945420e78d8c490cbaa5f7a9a46852a81b" dependencies = [ "ascii", - "bitflags 2.4.1", + "bitflags 2.6.0", "bstr 0.2.17", "cfg-if", "itertools 0.11.0", @@ -3261,7 +3523,7 @@ name = "rustpython-compiler-core" version = "0.3.0" source = "git+https://github.com/RustPython/RustPython?rev=317f44945420e#317f44945420e78d8c490cbaa5f7a9a46852a81b" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "itertools 0.11.0", "lz4_flex", "malachite-bigint", @@ -3310,7 +3572,7 @@ name = "rustpython-format" version = "0.3.1" source = "git+https://github.com/RustPython/Parser.git?rev=29c4728dbedc7e69cc2560b9b34058bbba9b1303#29c4728dbedc7e69cc2560b9b34058bbba9b1303" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "itertools 0.11.0", "malachite-bigint", "num-traits", @@ -3379,7 +3641,7 @@ dependencies = [ "ahash", "ascii", "atty", - "bitflags 2.4.1", + "bitflags 2.6.0", "bstr 0.2.17", "caseless", "cfg-if", @@ -3388,7 +3650,7 @@ dependencies = [ "exitcode", "getrandom", "glob", - "half 1.8.2", + "half 1.8.3", "hex", "indexmap 1.9.3", "is-macro", @@ -3446,9 +3708,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rustyline" @@ -3460,7 +3722,7 @@ dependencies = [ "cfg-if", "clipboard-win", "dirs-next", - "fd-lock", + "fd-lock 3.0.13", "libc", "log", "memchr", @@ -3475,9 +3737,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safetensors" @@ -3491,9 +3753,9 @@ dependencies = [ [[package]] name = "safetensors" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1659ef1c27917eb58c2d53664b5506d0b68c9cb9b460d3e0901011cf71269a8e" +checksum = "7725d4d98fa515472f43a6e2bbf956c48e06b89bb50593a040e5945160214450" dependencies = [ "serde", "serde_json", @@ -3516,11 +3778,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -3529,9 +3791,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -3539,47 +3801,51 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] [[package]] name = "serde" -version = "1.0.203" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] name = "serde_json" -version = "1.0.112" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.4.0", "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -3618,6 +3884,15 @@ dependencies = [ "digest", ] +[[package]] +name = "shellexpand" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +dependencies = [ + "dirs 4.0.0", +] + [[package]] name = "shlex" version = "1.3.0" @@ -3626,9 +3901,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -3656,18 +3931,21 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3682,6 +3960,15 @@ dependencies = [ "vob", ] +[[package]] +name = "spdx" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc" +dependencies = [ + "smallvec", +] + [[package]] name = "spin" version = "0.9.8" @@ -3712,7 +3999,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1120e6a8cbd4d85d5532d2e8a245aef2128e1853981f8b6d9943264184843102" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "num_enum", "optional", ] @@ -3741,6 +4028,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" version = "0.24.1" @@ -3753,7 +4046,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -3762,9 +4055,9 @@ dependencies = [ [[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" @@ -3779,9 +4072,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.46" +version = "2.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" +checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" dependencies = [ "proc-macro2", "quote", @@ -3797,11 +4090,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "system-interface" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b858526d22750088a9b3cf2e3c2aacebd5377f13adeec02860c30d09113010a6" +dependencies = [ + "bitflags 2.6.0", + "cap-fs-ext", + "cap-std", + "fd-lock 4.0.2", + "io-lifetimes", + "rustix", + "windows-sys 0.52.0", + "winx", +] + [[package]] name = "target-lexicon" -version = "0.12.12" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tch" @@ -3809,7 +4118,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ed5dddab3812892bf5fb567136e372ea49f31672931e21cec967ca68aec03da" dependencies = [ - "half 2.3.1", + "half 2.4.1", "lazy_static", "libc", "ndarray", @@ -3826,7 +4135,7 @@ version = "0.1.0" dependencies = [ "anyhow", "glob", - "half 2.3.1", + "half 2.4.1", "libc", "num_cpus", "rayon", @@ -3837,15 +4146,24 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", ] [[package]] @@ -3856,22 +4174,22 @@ checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] @@ -3890,9 +4208,9 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -3900,11 +4218,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ + "deranged", "itoa", + "num-conv", + "powerfmt", "serde", "time-core", "time-macros", @@ -3912,16 +4233,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -3942,9 +4264,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -3957,9 +4279,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokenizers" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "062b8a9613d6017633b80fb55fbb33f1aff006c36225a3025630753398034b3c" +checksum = "3dd47962b0ba36e7fd33518fbf1754d136fd1474000162bbf2a8b5fcb2d3654d" dependencies = [ "aho-corasick", "clap", @@ -3968,7 +4290,7 @@ dependencies = [ "getrandom", "hf-hub", "indicatif", - "itertools 0.11.0", + "itertools 0.12.1", "lazy_static", "log", "macro_rules_attribute", @@ -3979,7 +4301,7 @@ dependencies = [ "rayon", "rayon-cond", "regex", - "regex-syntax 0.7.5", + "regex-syntax 0.8.4", "serde", "serde_json", "spm_precompiled", @@ -3991,9 +4313,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.35.1" +version = "1.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" dependencies = [ "backtrace", "bytes", @@ -4003,21 +4325,20 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -4047,21 +4368,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.14", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -4072,22 +4393,22 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.4.0", "toml_datetime", - "winnow 0.5.31", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.4.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.11", + "winnow 0.6.18", ] [[package]] @@ -4110,9 +4431,21 @@ checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.76", +] + [[package]] name = "tracing-core" version = "0.1.32" @@ -4233,9 +4566,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-casing" @@ -4251,9 +4584,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -4269,15 +4602,21 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + +[[package]] +name = "unicode-xid" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" [[package]] name = "unicode_categories" @@ -4287,9 +4626,9 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "unicode_names2" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac64ef2f016dc69dfa8283394a70b057066eb054d5fcb6b9eb17bd2ec5097211" +checksum = "addeebf294df7922a1164f729fb27ebbbcea99cc32b3bf08afab62757f707677" dependencies = [ "phf", "unicode_names2_generator", @@ -4297,15 +4636,14 @@ dependencies = [ [[package]] name = "unicode_names2_generator" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "013f6a731e80f3930de580e55ba41dfa846de4e0fdee4a701f97989cb1597d6a" +checksum = "f444b8bba042fe3c1251ffaca35c603f2dc2ccc08d595c65a8c4f76f3e8426c0" dependencies = [ "getopts", "log", "phf_codegen", "rand", - "time", ] [[package]] @@ -4322,19 +4660,17 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.5" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b52731d03d6bb2fd18289d4028aee361d6c28d44977846793b994b13cdcc64d" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" dependencies = [ - "base64 0.21.5", + "base64 0.22.1", "flate2", - "hootbin", "log", "native-tls", "once_cell", "rustls", "rustls-pki-types", - "rustls-webpki", "serde", "serde_json", "url", @@ -4343,9 +4679,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -4354,15 +4690,15 @@ dependencies = [ [[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 = "uuid" -version = "1.6.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", ] @@ -4375,9 +4711,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[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 = "vob" @@ -4404,34 +4740,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4439,85 +4776,156 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-encoder" -version = "0.38.1" +version = "0.215.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" +checksum = "4fb56df3e06b8e6b77e37d2969a50ba51281029a9aeb3855e76b7f49b6418847" dependencies = [ "leb128", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6bb07c5576b608f7a2a9baa2294c1a3584a249965d695a9814a496cb6d232f" +dependencies = [ + "anyhow", + "indexmap 2.4.0", + "serde", + "serde_derive", + "serde_json", + "spdx", + "wasm-encoder", + "wasmparser", ] [[package]] name = "wasmparser" -version = "0.118.1" +version = "0.215.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" +checksum = "53fbde0881f24199b81cf49b6ff8f9c145ac8eb1b7fc439adb5c099734f7d90e" dependencies = [ - "indexmap 2.1.0", + "ahash", + "bitflags 2.6.0", + "hashbrown 0.14.5", + "indexmap 2.4.0", "semver", + "serde", +] + +[[package]] +name = "wasmprinter" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8e9a325d85053408209b3d2ce5eaddd0dd6864d1cff7a007147ba073157defc" +dependencies = [ + "anyhow", + "termcolor", + "wasmparser", ] [[package]] name = "wasmtime" -version = "16.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8e539fded2495422ea3c4dfa7beeddba45904eece182cf315294009e1a323bf" +checksum = "9a5883d64dfc8423c56e3d8df27cffc44db25336aa468e8e0724fddf30a333d7" dependencies = [ "anyhow", - "bincode", + "async-trait", + "bitflags 2.6.0", "bumpalo", + "cc", "cfg-if", - "indexmap 2.1.0", + "encoding_rs", + "hashbrown 0.14.5", + "indexmap 2.4.0", "libc", + "libm", "log", + "mach2", + "memfd", "object", "once_cell", "paste", + "postcard", + "psm", "rayon", + "rustix", + "semver", "serde", "serde_derive", - "serde_json", + "smallvec", + "sptr", "target-lexicon", "wasmparser", + "wasmtime-asm-macros", + "wasmtime-component-macro", + "wasmtime-component-util", "wasmtime-cranelift", "wasmtime-environ", - "wasmtime-jit", - "wasmtime-runtime", - "windows-sys 0.48.0", + "wasmtime-fiber", + "wasmtime-jit-icache-coherence", + "wasmtime-slab", + "wasmtime-versioned-export-macros", + "wasmtime-winch", + "windows-sys 0.52.0", ] [[package]] name = "wasmtime-asm-macros" -version = "16.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "660ba9143e15a2acd921820df221b73aee256bd3ca2d208d73d8adc9587ccbb9" +checksum = "1c4dc7e2a379c0dd6be5b55857d14c4b277f43a9c429a9e14403eb61776ae3be" dependencies = [ "cfg-if", ] +[[package]] +name = "wasmtime-component-macro" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b07773d1c3dab5f014ec61316ee317aa424033e17e70a63abdf7c3a47e58fcf" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn 2.0.76", + "wasmtime-component-util", + "wasmtime-wit-bindgen", + "wit-parser", +] + +[[package]] +name = "wasmtime-component-util" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e38d735320f4e83478369ce649ad8fe87c6b893220902e798547a225fc0c5874" + [[package]] name = "wasmtime-cranelift" -version = "16.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d648c8b4064a7911093b02237cd5569f71ca171d3a0a486bf80600b19e1cba2" +checksum = "e570d831d0785d93d7d8c722b1eb9a34e0d0c1534317666f65892818358a2da9" dependencies = [ "anyhow", "cfg-if", @@ -4533,142 +4941,167 @@ dependencies = [ "target-lexicon", "thiserror", "wasmparser", - "wasmtime-cranelift-shared", "wasmtime-environ", "wasmtime-versioned-export-macros", ] -[[package]] -name = "wasmtime-cranelift-shared" -version = "16.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290a89027688782da8ff60b12bb95695494b1874e0d0ba2ba387d23dace6d70c" -dependencies = [ - "anyhow", - "cranelift-codegen", - "cranelift-control", - "cranelift-native", - "gimli", - "object", - "target-lexicon", - "wasmtime-environ", -] - [[package]] name = "wasmtime-environ" -version = "16.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61eb64fb3e0da883e2df4a13a81d6282e072336e6cb6295021d0f7ab2e352754" +checksum = "c5fe80dfbd81687431a7d4f25929fae1ae96894786d5c96b14ae41164ee97377" dependencies = [ "anyhow", + "cranelift-bitset", "cranelift-entity", "gimli", - "indexmap 2.1.0", + "indexmap 2.4.0", "log", "object", + "postcard", + "semver", "serde", "serde_derive", "target-lexicon", - "thiserror", + "wasm-encoder", "wasmparser", + "wasmprinter", + "wasmtime-component-util", "wasmtime-types", ] [[package]] -name = "wasmtime-jit" -version = "16.0.0" +name = "wasmtime-fiber" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f485336add49267d8859e8f8084d2d4b9a4b1564496b6f30ba5b168d50c10ceb" +checksum = "0f39043d13c7b58db69dc9a0feb191a961e75a9ec2402aebf42de183c022bb8a" dependencies = [ "anyhow", - "bincode", + "cc", "cfg-if", - "gimli", - "log", - "object", "rustix", - "serde", - "serde_derive", - "target-lexicon", - "wasmtime-environ", - "wasmtime-jit-icache-coherence", - "wasmtime-runtime", - "windows-sys 0.48.0", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.52.0", ] [[package]] name = "wasmtime-jit-icache-coherence" -version = "16.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b6d197fcc34ad32ed440e1f9552fd57d1f377d9699d31dee1b5b457322c1f8a" +checksum = "d15de8429db996f0d17a4163a35eccc3f874cbfb50f29c379951ea1bbb39452e" dependencies = [ + "anyhow", "cfg-if", "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] -name = "wasmtime-runtime" -version = "16.0.0" +name = "wasmtime-slab" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794b2bb19b99ef8322ff0dd9fe1ba7e19c41036dfb260b3f99ecce128c42ff92" -dependencies = [ - "anyhow", - "cc", - "cfg-if", - "indexmap 2.1.0", - "libc", - "log", - "mach", - "memfd", - "memoffset 0.9.0", - "paste", - "psm", - "rustix", - "sptr", - "wasm-encoder", - "wasmtime-asm-macros", - "wasmtime-environ", - "wasmtime-versioned-export-macros", - "wasmtime-wmemcheck", - "windows-sys 0.48.0", -] +checksum = "1f68d38fa6b30c5e1fc7d608263062997306f79e577ebd197ddcd6b0f55d87d1" [[package]] name = "wasmtime-types" -version = "16.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d995db8bb56f2cd8d2dc0ed5ffab94ffb435283b0fe6747f80f7aab40b2d06a1" +checksum = "6634e7079d9c5cfc81af8610ed59b488cc5b7f9777a2f4c1667a2565c2e45249" dependencies = [ + "anyhow", "cranelift-entity", "serde", "serde_derive", - "thiserror", + "smallvec", "wasmparser", ] [[package]] name = "wasmtime-versioned-export-macros" -version = "16.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c5565959287c21dd0f4277ae3518dd2ae62679f655ee2dbc4396e19d210db" +checksum = "3850e3511d6c7f11a72d571890b0ed5f6204681f7f050b9de2690e7f13123fed" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", +] + +[[package]] +name = "wasmtime-wasi" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545ae8298ffce025604f7480f9c7d6948c985bef7ce9aee249ef79307813e83c" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.6.0", + "bytes", + "cap-fs-ext", + "cap-net-ext", + "cap-rand", + "cap-std", + "cap-time-ext", + "fs-set-times", + "futures", + "io-extras", + "io-lifetimes", + "once_cell", + "rustix", + "system-interface", + "thiserror", + "tokio", + "tracing", + "url", + "wasmtime", + "wiggle", + "windows-sys 0.52.0", ] [[package]] -name = "wasmtime-wmemcheck" -version = "16.0.0" +name = "wasmtime-winch" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67761d8f8c0b3c13a5d34356274b10a40baba67fe9cfabbfc379a8b414e45de2" +checksum = "2a25199625effa4c13dd790d64bd56884b014c69829431bfe43991c740bd5bc1" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "object", + "target-lexicon", + "wasmparser", + "wasmtime-cranelift", + "wasmtime-environ", + "winch-codegen", +] + +[[package]] +name = "wasmtime-wit-bindgen" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb331ac7ed1d5ba49cddcdb6b11973752a857148858bb308777d2fc5584121f" +dependencies = [ + "anyhow", + "heck 0.4.1", + "indexmap 2.4.0", + "wit-parser", +] + +[[package]] +name = "wast" +version = "35.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef140f1b49946586078353a453a1d28ba90adfc54dde75710bc1931de204d68" +dependencies = [ + "leb128", +] [[package]] name = "webpki-roots" -version = "0.26.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" dependencies = [ "rustls-pki-types", ] @@ -4691,6 +5124,48 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" +[[package]] +name = "wiggle" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc850ca3c02c5835934d23f28cec4c5a3fb66fe0b4ecd968bbb35609dda5ddc0" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.6.0", + "thiserror", + "tracing", + "wasmtime", + "wiggle-macro", +] + +[[package]] +name = "wiggle-generate" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634b8804a67200bcb43ea8af5f7c53e862439a086b68b16fd333454bc74d5aab" +dependencies = [ + "anyhow", + "heck 0.4.1", + "proc-macro2", + "quote", + "shellexpand", + "syn 2.0.76", + "witx", +] + +[[package]] +name = "wiggle-macro" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474b7cbdb942c74031e619d66c600bba7f73867c5800fc2c2306cf307649be2f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.76", + "wiggle-generate", +] + [[package]] name = "winapi" version = "0.3.9" @@ -4707,12 +5182,38 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winch-codegen" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "073efe897d9ead7fc609874f94580afc831114af5149b6a90ee0a3a39b497fe0" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "regalloc2", + "smallvec", + "target-lexicon", + "wasmparser", + "wasmtime-cranelift", + "wasmtime-environ", +] + [[package]] name = "windows" version = "0.52.0" @@ -4720,7 +5221,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -4729,16 +5230,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", -] - -[[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", + "windows-targets 0.52.6", ] [[package]] @@ -4756,22 +5248,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 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", + "windows-targets 0.52.6", ] [[package]] @@ -4791,25 +5277,20 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -4818,15 +5299,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -4836,15 +5311,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -4854,15 +5323,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -4872,15 +5341,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -4890,15 +5353,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -4908,15 +5365,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -4926,24 +5377,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.31" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" -version = "0.6.11" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c52728401e1dc672a56e81e593e912aa54c78f40246869f78359a2bf24d29d" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -4957,31 +5408,152 @@ dependencies = [ "winapi", ] +[[package]] +name = "winx" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" +dependencies = [ + "bitflags 2.6.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4bac478334a647374ff24a74b66737a4cb586dc8288bc3080a93252cd1105c" +dependencies = [ + "wit-bindgen-rt", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7e3df01cd43cfa1cb52602e4fc05cb2b62217655f6705639b6953eb0a3fed2" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2de7a3b06b9725d129b5cbd1beca968feed919c433305a23da46843185ecdd6" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a767d1a8eb4e908bfc53febc48b87ada545703b16fe0148ee7736a29a01417" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.4.0", + "prettyplease", + "syn 2.0.76", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b185c342d0d27bd83d4080f5a66cf3b4f247fa49d679bceb66e11cc7eb58b99" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.76", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f725e3885fc5890648be5c5cbc1353b755dc932aa5f1aa7de968b912a3280743" +dependencies = [ + "anyhow", + "bitflags 2.6.0", + "indexmap 2.4.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935a97eaffd57c3b413aa510f8f0b550a4a9fe7d59e79cd8b89a83dcb860321f" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.4.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "witx" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e366f27a5cabcddb2706a78296a40b8fcc451e1a6aba2fc1d94b4a01bdaaef4b" +dependencies = [ + "anyhow", + "log", + "thiserror", + "wast", +] + [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.76", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" @@ -5014,11 +5586,11 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" dependencies = [ - "zstd-safe 7.0.0", + "zstd-safe 7.2.1", ] [[package]] @@ -5033,18 +5605,18 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "7.0.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index eb89fe49..8956d5fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,8 @@ members = [ "controllers/toktrie/hf_tokenizers", "controllers/aici_abi", "controllers/aici_native", + "controllers/aici_wasm_host", + "controllers/aici_wasm_guest", "controllers/declctrl", "controllers/pyctrl", "controllers/jsctrl", @@ -13,6 +15,7 @@ members = [ "controllers/llguidance/parser", "controllers/llguidance_ctrl", "controllers/uppercase", + "controllers/yesno", "controllers/derivre", "rllm/rllm-base", "rllm/rllm-cuda", diff --git a/README.md b/README.md index 4c2a4f6a..3b6625db 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Controllers are flexible programs capable of implementing constrained decoding, Controllers incorporate custom logic during the token-by-token decoding and maintain state during an LLM request. This allows diverse Controller strategies, from programmatic or query-based decoding to multi-agent conversations to execute efficiently in tight integration with the LLM itself. **The purpose of AICI is to make it easy to build and experiment with both existing and entirely new Controller strategies for improving LLM generations.** -By abstracting away implementation details of the underlying LLM inference and serving engine, AICI aims to simplify the development of Controllers, make it easier to +By abstracting away implementation details of the underlying LLM inference and serving engine, AICI aims to simplify the development of Controllers, make it easier to write fast Controllers, and ease compatibility across LLM inference and serving engines. AICI is designed for both local and cloud execution, including (eventually) multi-tenant LLM deployments. @@ -56,14 +56,14 @@ To compile AICI components, you need to set up your development environment for > [!NOTE] > **Windows users**: please use WSL2 or the included [devcontainer](https://containers.dev). Adding native Windows support [is tracked here](https://github.com/microsoft/aici/issues/42). -> +> > **MacOS users**: please make sure you have XCode command line tools installed by running `xcode-select -p` and, if not installed, run `xcode-select --install`. > > **CUDA**: the CUDA build relies on specific libtorch installation. It's highly recommended you use the included devcontainer. If you're using devcontainer, you can skip to the [next section](#build-and-start-rllm-server-and-aici-runtime). -Using the system package manager, install the necessary tools for building code in the repository, including `git`, `cmake` and `ccache`. +Using the system package manager, install the necessary tools for building code in the repository, including `git`, `cmake` and `ccache`. For instance in WSL / Ubuntu using `apt`: @@ -79,10 +79,10 @@ Then install **Rust, Rustup and Cargo**, following the instructions provided [he curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh After installation, verify that the `rustup --version` command is accessible by running it from the terminal. If the command isn't recognized, try opening a new terminal session. - -Next install wasm32-wasi Rust component: - - rustup target add wasm32-wasi + +Next install wasm32-wasip2 Rust component: + + rustup target add wasm32-wasip2 If you already had Rust installed, or are getting complaints from Cargo about outdated versions, run: @@ -160,7 +160,7 @@ The following illustrates the relationship between the rLLM server, the AICI run erDiagram Host ||--|{ CPU : "" Host ||--|{ GPU : "" - + CPU ||--|| "rLLM Server" : execute CPU ||--|{ "AICI Runtime" : execute @@ -204,7 +204,7 @@ import pyaici.server as aici # 4. name 4 # 5. name 5 async def main(): - + # This is the prompt we want to run. # Note how the prompt doesn't mention a number of vehicles or how to format the result. prompt = "What are the most popular types of vehicles?\n" @@ -432,7 +432,7 @@ All of these can be easily extended. # Citing this package -If you find the AI Controller Interface and its ideas for defining a new layer in the LLM inference stack useful, please cite the package using the following reference: +If you find the AI Controller Interface and its ideas for defining a new layer in the LLM inference stack useful, please cite the package using the following reference: * Michal Moskal, Madan Musuvathi, Emre Kıcıman. AI Controller Interface, (2024), GitHub repository. https://github.com/microsoft/aici diff --git a/aicirt/Cargo.toml b/aicirt/Cargo.toml index d2b1ce53..a59eceee 100644 --- a/aicirt/Cargo.toml +++ b/aicirt/Cargo.toml @@ -18,7 +18,7 @@ rayon = "1.7.0" serde = { version = "1.0.192", features = ["derive"] } serde_json = { version = "1.0.108", features = ["preserve_order"] } sha2 = "0.10.7" -wasmtime = { version = "16.0.0", default-features = false, features = ["cranelift", "parallel-compilation", "pooling-allocator"] } +wasmtime = { version = "24.0.0", default-features = false, features = ["cranelift", "parallel-compilation", "pooling-allocator", "threads"] } tokenizers = { version = "0.15.0", features = ["http"] } thread-priority = "0.15.1" cap = "0.1.2" @@ -26,10 +26,12 @@ bincode = "1.3.3" uuid = { version = "1.6.1", features = ["v4"] } regex = "1.10.3" ureq = "2.9.5" +wasmtime-wasi = "24.0.0" +bytemuck = "1.16.0" +aici_wasm_host = { version = "0.1.0", path = "../controllers/aici_wasm_host" } [target.'cfg(target_os = "linux")'.dependencies] linux-futex = "0.2.0" [target.'cfg(target_os = "macos")'.dependencies] ulock-sys = "0.1.0" - diff --git a/aicirt/src/api.rs b/aicirt/src/api.rs index d21d8839..3de2e741 100644 --- a/aicirt/src/api.rs +++ b/aicirt/src/api.rs @@ -1,10 +1,10 @@ use crate::{shm::ShmAllocator, HashMap}; -use aici_abi::{ProcessResultOffset, StorageCmd, TokenId}; +use aici_abi::{toktrie, StorageCmd, TokenId}; use anyhow::{anyhow, Result}; use serde::{Deserialize, Serialize}; use serde_json::Value; -pub type ModuleInstId = usize; +pub type ModuleInstId = u64; #[derive(Serialize, Deserialize, Clone)] pub struct InferenceCapabilities { @@ -22,9 +22,16 @@ pub struct AiciMidProcessReq { pub freed: Vec, } +#[derive(Serialize, Deserialize, Debug)] +pub struct RtMidProcessResult { + pub branches: Vec>, +} + +pub type SeqMap = HashMap>; + #[derive(Serialize, Deserialize)] pub struct AiciMidProcessResp { - pub seqs: HashMap>, + pub seqs: SeqMap, pub dtype: String, pub first_mask_byte_offset: usize, pub mask_num_bytes: usize, diff --git a/aicirt/src/bench.rs b/aicirt/src/bench.rs index 3756ddd7..a6b277be 100644 --- a/aicirt/src/bench.rs +++ b/aicirt/src/bench.rs @@ -1,9 +1,9 @@ +use crate::HashMap; use std::{ fmt::{Display, Write}, sync::{Arc, Mutex}, time::{Duration, Instant}, }; -use crate::HashMap; #[derive(PartialEq, Eq)] enum TimerState { diff --git a/aicirt/src/bindings.rs b/aicirt/src/bindings.rs new file mode 100644 index 00000000..b6a9b444 --- /dev/null +++ b/aicirt/src/bindings.rs @@ -0,0 +1,2 @@ + +pub use aici_wasm_host::*; diff --git a/aicirt/src/hostimpl.rs b/aicirt/src/hostimpl.rs index 08f371ba..4e6a6497 100644 --- a/aicirt/src/hostimpl.rs +++ b/aicirt/src/hostimpl.rs @@ -1,17 +1,16 @@ -use crate::worker::{GroupCmd, GroupHandle, GroupResp, RtMidProcessArg}; +use crate::{ + bindings::aici::abi::{self, tokenizer::TokenId}, + worker::{GroupCmd, GroupHandle, GroupResp}, +}; use aici_abi::{ - bytes::{clone_vec_as_bytes, limit_str, vec_from_bytes, U32Pair}, + bytes::limit_str, toktrie::{TokRxInfo, TokTrie}, StorageCmd, }; -use aicirt::{ - api::{BiasType, InferenceCapabilities}, - shm::ShmAllocator, - user_error, -}; -use anyhow::Result; +use aicirt::{api::InferenceCapabilities, bindings::SeqId, user_error}; +use anyhow::{anyhow, Result}; use std::{ - rc::Rc, + ops::Deref, sync::Arc, time::{Duration, Instant}, }; @@ -44,109 +43,52 @@ pub struct ModuleData { printed_log: usize, pub globals: GlobalInfo, pub group_channel: GroupHandle, - pub process_result: Vec, - pub logit_shm: Rc, - pub logit_offsets: Vec, - pub limits: AiciLimits, - pub linker: Arc>, - pub instance: Option, - pub memory: Option, - pub module: wasmtime::Module, pub store_limits: wasmtime::StoreLimits, pub had_error: bool, pub storage_log: Vec, pub start_time: Instant, - blobs: Vec>>, + pub wasi_ctx: wasmtime_wasi::WasiCtx, + pub resource_table: wasmtime_wasi::ResourceTable, } const MAXLOG: usize = 64 * 1024; -pub struct BlobId(u32); - -impl BlobId { - pub const MODULE_ARG: BlobId = BlobId(1); - pub const TOKENIZE: BlobId = BlobId(2); - pub const TOKENS: BlobId = BlobId(3); - pub const PROCESS_ARG: BlobId = BlobId(4); - pub const STORAGE_RESULT: BlobId = BlobId(5); - - pub const MAX_BLOB_ID: u32 = 20; - - // these have special handling: - pub const TRIE: BlobId = BlobId(100); -} - impl ModuleData { pub fn new( id: ModuleInstId, limits: &AiciLimits, - module: &wasmtime::Module, - module_arg: String, - linker: &Arc>, globals: GlobalInfo, group_channel: GroupHandle, - logit_shm: Rc, ) -> Self { let store_limits = wasmtime::StoreLimitsBuilder::new() .memories(1) .memory_size(limits.max_memory_bytes) .tables(2) .table_elements(100000) - .instances(1) + .instances(100) .trap_on_grow_failure(true) .build(); - let mut r = ModuleData { + ModuleData { id, log: Vec::new(), printed_log: 0, globals, group_channel, - module: module.clone(), - limits: limits.clone(), - linker: linker.clone(), - instance: None, - memory: None, store_limits, - process_result: Vec::new(), - logit_shm, - logit_offsets: Vec::new(), had_error: false, storage_log: Vec::new(), start_time: Instant::now(), - blobs: vec![Rc::new(Vec::new()); BlobId::MAX_BLOB_ID as usize], - }; - r.set_blob(BlobId::MODULE_ARG, module_arg.as_bytes().to_vec()); - r - } - - fn clear_blob(&mut self, blob_id: BlobId) { - self.set_blob(blob_id, vec![]) - } - - fn set_blob(&mut self, blob_id: BlobId, bytes: Vec) { - self.blobs[blob_id.0 as usize] = Rc::new(bytes); - } - - pub fn set_process_arg(&mut self, bytes: Vec) { - self.process_result.clear(); - self.set_blob(BlobId::PROCESS_ARG, bytes); - } - - pub fn set_mid_process_data(&mut self, data: RtMidProcessArg) { - let bytes = serde_json::to_vec(&data.op).unwrap(); - self.set_process_arg(bytes); - self.logit_offsets.clear(); + wasi_ctx: wasmtime_wasi::WasiCtxBuilder::new().build(), + resource_table: wasmtime_wasi::ResourceTable::new(), + } } - pub fn tokenize_bytes(&mut self, s: &[u8]) -> Result> { - Ok(self.globals.tok_trie.tokenize_with_greedy_fallback(s, |s| { - self.globals - .hf_tokenizer - .encode(s, false) - .expect("tokenizer error") - .get_ids() - .to_vec() - })) + pub fn tokenize(&mut self, s: &str) -> Result> { + let tokens = self.globals.hf_tokenizer.encode(s, false); + match tokens { + Err(e) => Err(anyhow!(e)), + Ok(tokens) => Ok(Vec::from(tokens.get_ids())), + } } pub fn fatal(&mut self, msg: &str) { @@ -157,11 +99,11 @@ impl ModuleData { // ideally, this should call into the module and cause panic } - pub fn warn(&mut self, msg: &str) { - log::warn!("{}: {}", self.id, msg); - let msg = format!("warning: {}\n", msg); - self.write_log(msg.as_bytes()); - } + // pub fn warn(&mut self, msg: &str) { + // log::warn!("{}: {}", self.id, msg); + // let msg = format!("warning: {}\n", msg); + // self.write_log(msg.as_bytes()); + // } pub fn write_log(&mut self, bytes: &[u8]) { self.log.extend_from_slice(bytes); @@ -202,31 +144,15 @@ impl ModuleData { log::debug!("{}:{}> {}", self.id, name, limit_str(line, 512)); } } +} - pub fn aici_host_storage_cmd(&mut self, m: Vec) -> BlobId { - self.clear_blob(BlobId::STORAGE_RESULT); - match serde_json::from_slice(&m) { - Ok(cmd) => { - let save = match &cmd { - StorageCmd::WriteVar { .. } => Some(cmd.clone()), - StorageCmd::ReadVar { .. } => None, - }; - let res = self.group_channel.send_cmd(GroupCmd::StorageCmd { cmd }); - match res { - Ok(GroupResp::StorageResp { resp }) => { - if let Some(log) = save { - self.storage_log.push(log) - } - let res_bytes = serde_json::to_vec(&resp).unwrap(); - self.set_blob(BlobId::STORAGE_RESULT, res_bytes); - } - // Ok(r) => self.fatal(&format!("storage_cmd invalid resp: {r:?}")), - Err(msg) => self.fatal(&format!("storage_cmd send error: {msg:?}")), - } - } - Err(e) => self.fatal(&format!("storage_cmd error: {e:?}")), - } - BlobId::STORAGE_RESULT +impl wasmtime_wasi::WasiView for ModuleData { + fn table(&mut self) -> &mut wasmtime_wasi::ResourceTable { + &mut self.resource_table + } + + fn ctx(&mut self) -> &mut wasmtime_wasi::WasiCtx { + &mut self.wasi_ctx } } @@ -256,283 +182,117 @@ fn fatal_error(caller: &mut wasmtime::Caller<'_, ModuleData>, msg: &str) { } } -fn read_caller_mem(caller: &wasmtime::Caller<'_, ModuleData>, ptr: u32, len: u32) -> Vec { - let mem = caller.data().memory.unwrap(); - let ptr = ptr as usize; - Vec::from(&mem.data(&caller)[ptr..(ptr + len as usize)]) -} +impl abi::runtime::Host for ModuleData { + fn sequence_id(&mut self) -> wasmtime::Result { + Ok(self.id as SeqId) + } -fn write_caller_mem( - caller: &mut wasmtime::Caller<'_, ModuleData>, - ptr: u32, - len: u32, - src: &[u8], -) -> u32 { - if len > 0 { - let mem = caller.data().memory.unwrap(); - let min_len = std::cmp::min(len as usize, src.len()); - mem.write(caller, ptr as usize, &src[..min_len]).unwrap(); + fn stop(&mut self) -> wasmtime::Result<()> { + Err::<(), _>(user_error!("*** aici_host_stop()")) + } + + fn get_config(&mut self, key: String) -> wasmtime::Result { + let caps = serde_json::to_value(self.globals.inference_caps.clone()).unwrap(); + if caps[&key].as_bool().unwrap_or(false) { + Ok(1) + } else { + Ok(0) + } } - src.len() as u32 } -macro_rules! fake_wasi { - ($linker:ident, $func_name:ident, $($arg_type:ty)+) => { - $linker.func_wrap( - "wasi_snapshot_preview1", - stringify!($func_name), - |$(_: $arg_type),+| -> i32 { - 8 // BADF - // 52 // NOSYS +impl abi::runtime_storage::Host for ModuleData { + fn get(&mut self, name: String) -> wasmtime::Result>> { + let res = self.group_channel.send_cmd(GroupCmd::StorageCmd { + cmd: StorageCmd::ReadVar { name }, + })?; + + match res { + GroupResp::StorageResp { resp } => match resp { + aici_abi::StorageResp::ReadVar { version: _, value } => Ok(Some(value)), + aici_abi::StorageResp::VariableMissing {} => Ok(None), + aici_abi::StorageResp::WriteVar { .. } => Err(anyhow!("unexpected WriteVar")), }, - )?; - }; -} + } + } -pub fn setup_linker(engine: &wasmtime::Engine) -> Result>> { - let mut linker = wasmtime::Linker::::new(engine); - - fake_wasi!(linker, environ_get, i32 i32); - fake_wasi!(linker, path_create_directory, i32 i32 i32); - fake_wasi!(linker, path_filestat_get, i32 i32 i32 i32 i32); - fake_wasi!(linker, path_link, i32 i32 i32 i32 i32 i32 i32); - fake_wasi!(linker, path_open, i32 i32 i32 i32 i32 i64 i64 i32 i32); - fake_wasi!(linker, path_readlink, i32 i32 i32 i32 i32 i32); - fake_wasi!(linker, path_remove_directory, i32 i32 i32); - fake_wasi!(linker, path_rename, i32 i32 i32 i32 i32 i32); - fake_wasi!(linker, path_unlink_file, i32 i32 i32); - fake_wasi!(linker, poll_oneoff, i32 i32 i32 i32); - fake_wasi!(linker, fd_filestat_set_size, i32 i64); - fake_wasi!(linker, fd_read, i32 i32 i32 i32); - fake_wasi!(linker, fd_readdir, i32 i32 i32 i64 i32); - fake_wasi!(linker, fd_close, i32); - fake_wasi!(linker, fd_filestat_get, i32 i32); - fake_wasi!(linker, fd_prestat_get, i32 i32); - fake_wasi!(linker, fd_prestat_dir_name, i32 i32 i32); - fake_wasi!(linker, fd_seek, i32 i64 i32 i32); - fake_wasi!(linker, path_filestat_set_times, i32 i32 i32 i32 i64 i64 i32); - - linker.func_wrap("wasi_snapshot_preview1", "sched_yield", || 0)?; - linker.func_wrap("wasi_snapshot_preview1", "fd_sync", |_: i32| 0)?; - - linker.func_wrap( - "wasi_snapshot_preview1", - "proc_exit", - |code: i32| -> Result<()> { Err(user_error!("proc_exit: {code}")) }, - )?; - - linker.func_wrap( - "wasi_snapshot_preview1", - "fd_fdstat_get", - |mut caller: wasmtime::Caller<'_, ModuleData>, fd: i32, stat_ptr: u32| -> Result { - if fd != 0 && fd != 1 && fd != 2 { - return Ok(8); // BADF - } - // pretend file isatty() - let mut char_device = vec![0u8; 24]; - char_device[0] = 2; - write_caller_mem(&mut caller, stat_ptr, 24, &char_device); - Ok(0) - }, - )?; - - linker.func_wrap( - "wasi_snapshot_preview1", - "clock_time_get", - |mut caller: wasmtime::Caller<'_, ModuleData>, - clock_id: i32, - _precision: i64, - dst_ptr: u32| - -> Result { - if clock_id != 1 { - return Ok(63); // EPERM - } - let res = caller.data().limits.timer_resolution_ns as u64; - let now = std::time::Instant::now(); - let nanos = now.duration_since(caller.data().start_time).as_nanos() as u64; - let nanos = if res == 0 { 0 } else { nanos / res * res }; - let bytes = nanos.to_le_bytes(); - write_caller_mem(&mut caller, dst_ptr, 8, &bytes); - Ok(0) - }, - )?; - - linker.func_wrap( - "wasi_snapshot_preview1", - "fd_write", - |mut caller: wasmtime::Caller<'_, ModuleData>, - fd: i32, - iovs_ptr: u32, - niovs: u32, - nwrittenptr: u32| { - if fd != 1 && fd != 2 { - return 8; // BADF - } - let iovs = read_caller_mem(&caller, iovs_ptr, niovs * 8); - let ptr_lens = vec_from_bytes::(&iovs); - let mut nwr = 0; - for U32Pair(ptr, len) in ptr_lens { - let m = read_caller_mem(&caller, ptr, len); - nwr += m.len(); - caller.data_mut().write_log(&m); - } - if nwrittenptr != 0 { - write_caller_mem(&mut caller, nwrittenptr, 4, &nwr.to_le_bytes()); - } - 0 - }, - )?; - - linker.func_wrap( - "wasi_snapshot_preview1", - "random_get", - |mut caller: wasmtime::Caller<'_, ModuleData>, ptr: u32, len: u32| { - write_caller_mem(&mut caller, ptr, len, &[]); - 0 - }, - )?; - - linker.func_wrap( - "wasi_snapshot_preview1", - "args_sizes_get", - |mut caller: wasmtime::Caller<'_, ModuleData>, p1: u32, p2: u32| { - let z = vec![0u8; 4]; - write_caller_mem(&mut caller, p1, 4, &z); - write_caller_mem(&mut caller, p2, 4, &z); - 0 - }, - )?; - - linker.func_wrap( - "wasi_snapshot_preview1", - "environ_sizes_get", - |mut caller: wasmtime::Caller<'_, ModuleData>, p1: u32, p2: u32| { - let z = vec![0u8; 4]; - write_caller_mem(&mut caller, p1, 4, &z); - write_caller_mem(&mut caller, p2, 4, &z); - 0 - }, - )?; - linker.func_wrap("wasi_snapshot_preview1", "args_get", |_: u32, _: u32| 0)?; - - linker.func_wrap( - "env", - "aici_host_read_blob", - |mut caller: wasmtime::Caller<'_, ModuleData>, blob_id: u32, ptr: u32, len: u32| { - if blob_id == BlobId::TRIE.0 { - let trie_bytes = caller.data().globals.trie_bytes.clone(); - write_caller_mem(&mut caller, ptr, len, &trie_bytes) - } else if blob_id < BlobId::MAX_BLOB_ID { - let blob = caller.data().blobs[blob_id as usize].clone(); - write_caller_mem(&mut caller, ptr, len, &blob) - } else { - fatal_error(&mut caller, "invalid blob_id"); - 0 - } - }, - )?; - - linker.func_wrap("env", "aici_host_module_arg", || BlobId::MODULE_ARG.0)?; - linker.func_wrap("env", "aici_host_process_arg", || BlobId::PROCESS_ARG.0)?; - linker.func_wrap("env", "aici_host_token_trie", || BlobId::TRIE.0)?; - linker.func_wrap("env", "aici_host_tokens", || BlobId::TOKENS.0)?; - - // uint32_t aici_host_tokenize(const uint8_t *src, uint32_t src_size, uint32_t *dst, uint32_t dst_size); - linker.func_wrap( - "env", - "aici_host_tokenize", - |mut caller: wasmtime::Caller<'_, ModuleData>, src: u32, src_size: u32| { - let m = read_caller_mem(&caller, src, src_size); - let tokens = caller.data_mut().tokenize_bytes(&m); - match tokens { - Err(e) => { - caller.data_mut().warn(&format!("tokenize error: {e:?}")); - caller.data_mut().clear_blob(BlobId::TOKENIZE); + fn set(&mut self, name: String, value: Vec) -> wasmtime::Result<()> { + let cmd = StorageCmd::WriteVar { + name, + value, + op: aici_abi::StorageOp::Set, + when_version_is: None, + }; + self.storage_log.push(cmd.clone()); + let res = self.group_channel.send_cmd(GroupCmd::StorageCmd { cmd })?; + match res { + GroupResp::StorageResp { resp } => match resp { + aici_abi::StorageResp::ReadVar { .. } => Err(anyhow!("unexpected ReadVar")), + aici_abi::StorageResp::VariableMissing { .. } => { + Err(anyhow!("unexpected VariableMissing")) } - Ok(tokens) => { - caller - .data_mut() - .set_blob(BlobId::TOKENIZE, clone_vec_as_bytes(&tokens)); + aici_abi::StorageResp::WriteVar { .. } => Ok(()), + }, + } + } + + fn append(&mut self, name: String, value: Vec) -> wasmtime::Result<()> { + let cmd = StorageCmd::WriteVar { + name, + value, + op: aici_abi::StorageOp::Append, + when_version_is: None, + }; + self.storage_log.push(cmd.clone()); + let res = self.group_channel.send_cmd(GroupCmd::StorageCmd { cmd })?; + match res { + GroupResp::StorageResp { resp } => match resp { + aici_abi::StorageResp::ReadVar { .. } => Err(anyhow!("unexpected ReadVar")), + aici_abi::StorageResp::VariableMissing { .. } => { + Err(anyhow!("unexpected VariableMissing")) } - } - BlobId::TOKENIZE.0 - }, - )?; - - linker.func_wrap( - "env", - "aici_host_return_logit_bias", - |mut caller: wasmtime::Caller<'_, ModuleData>, src: u32| { - let data = caller.data(); - - let numtok = data.globals.tokrx_info.vocab_size as usize; - let shm = data.logit_shm.clone(); - let id: u32 = data.id.try_into().unwrap(); - let numbytes = 4 * ((numtok + 31) / 32); - let mem = caller.data().memory.unwrap(); - let sptr = src as usize; - let slice = &mem.data(&caller)[sptr..sptr + numbytes]; - - let bias_type = BiasType::from_u32(shm.elt_type() & 0xf).unwrap(); - let off = shm.alloc(id).unwrap(); - - bias_type.apply_to_shm_allocator(slice, &shm, off); - - let off32: u32 = off.try_into().unwrap(); - caller.data_mut().logit_offsets.push(off32); - off32 - }, - )?; - - linker.func_wrap( - "env", - "aici_host_self_seq_id", - |caller: wasmtime::Caller<'_, ModuleData>| caller.data().id as u32, - )?; - - linker.func_wrap( - "env", - "aici_host_get_config", - |caller: wasmtime::Caller<'_, ModuleData>, name: u32, name_size: u32| { - let m = read_caller_mem(&caller, name, name_size); - let name = String::from_utf8_lossy(&m); - let caps = serde_json::to_value(caller.data().globals.inference_caps.clone()).unwrap(); - if caps[name.as_ref()].as_bool().unwrap_or(false) { - return 1; - } - return 0; - }, - )?; - - linker.func_wrap( - "env", - "aici_host_eos_token", - |caller: wasmtime::Caller<'_, ModuleData>| caller.data().globals.tokrx_info.tok_eos, - )?; - - linker.func_wrap( - "env", - "aici_host_return_process_result", - |mut caller: wasmtime::Caller<'_, ModuleData>, src: u32, src_size: u32| { - let m = read_caller_mem(&caller, src, src_size); - caller.data_mut().process_result = m; - }, - )?; - - linker.func_wrap( - "env", - "aici_host_storage_cmd", - |mut caller: wasmtime::Caller<'_, ModuleData>, src: u32, src_size: u32| { - let m = read_caller_mem(&caller, src, src_size); - let r = caller.data_mut().aici_host_storage_cmd(m); - check_fatal(&mut caller); - r.0 - }, - )?; - - linker.func_wrap("env", "aici_host_stop", || { - Err::<(), _>(user_error!("*** aici_host_stop()")) - })?; + aici_abi::StorageResp::WriteVar { .. } => Ok(()), + }, + } + } +} + +impl ModuleData { + pub fn tokenize_str(&mut self, s: &str) -> Result> { + let tokens = self.globals.hf_tokenizer.encode(s, false); + match tokens { + Err(e) => Err(anyhow!(e)), + Ok(tokens) => Ok(Vec::from(tokens.get_ids())), + } + } +} + +impl abi::tokenizer::Host for ModuleData { + fn eos_token(&mut self) -> wasmtime::Result { + Ok(self.globals.tokrx_info.tok_eos) + } + + fn tokenize(&mut self, s: String) -> wasmtime::Result> { + self.tokenize_str(&s) + } + + fn tokenize_bytes(&mut self, bytes: Vec) -> wasmtime::Result> { + let s = String::from_utf8_lossy(&bytes); + self.tokenize(&s) + } + + fn token_trie_bytes(&mut self) -> wasmtime::Result> { + Ok(self.globals.trie_bytes.deref().clone()) + } +} + +pub fn setup_component_linker( + engine: &wasmtime::Engine, +) -> Result>> { + let mut linker = wasmtime::component::Linker::::new(engine); + + crate::bindings::Aici::add_to_linker(&mut linker, |m| m)?; + wasmtime_wasi::add_to_linker_sync(&mut linker)?; let linker = Arc::new(linker); Ok(linker) diff --git a/aicirt/src/lib.rs b/aicirt/src/lib.rs index f90b9223..b1164dbc 100644 --- a/aicirt/src/lib.rs +++ b/aicirt/src/lib.rs @@ -1,5 +1,6 @@ pub mod api; mod bench; +pub mod bindings; pub mod futexshm; pub mod msgchannel; pub mod semaphore; diff --git a/aicirt/src/main.rs b/aicirt/src/main.rs index 1e02551a..db77f29d 100644 --- a/aicirt/src/main.rs +++ b/aicirt/src/main.rs @@ -12,10 +12,13 @@ use crate::{ TimerSet, }; use aici_abi::{ - bytes::limit_str, toktrie::TokTrie, Branch, MidProcessArg, ProcessResultOffset, SeqId, - TokenizerEnv, + bytes::limit_str, + toktrie::{self, TokTrie}, + SeqId, TokenizerEnv, +}; +use aicirt::{ + bindings::*, bintokens::find_tokenizer, futexshm::ServerChannel, shm::ShmAllocator, *, }; -use aicirt::{bintokens::find_tokenizer, futexshm::ServerChannel, shm::ShmAllocator, *}; use anyhow::{anyhow, ensure, Result}; use base64::{self, Engine as _}; use bintokens::ByteTokenizerEnv; @@ -144,7 +147,7 @@ struct Cli { wasm_max_timeout_steps: usize, /// Maximum time WASM module can execute initialization code in milliseconds - #[arg(long, default_value = "1000")] + #[arg(long, default_value = "10000")] wasm_max_init_time: u64, /// Resolution of timer exposed to WASM modules in microseconds; 0 to disable timer @@ -259,11 +262,12 @@ impl ModuleRegistry { self.cache_path.join(format!("tags/{}.json", tagname)) } - fn compile_module(&self, module_id: &str, force: bool) -> Result<()> { + fn compile_component(&self, module_id: &str, force: bool) -> Result<()> { let module = if force { Err(anyhow!("force")) } else { - self.wasm_ctx.deserialize_module(self.elf_path(module_id)) + self.wasm_ctx + .deserialize_component(self.elf_path(module_id)) }; match module { @@ -273,7 +277,9 @@ impl ModuleRegistry { let compiled = self.forker.lock().unwrap().compile(wasm_bytes)?; fs::write(self.elf_path(module_id), compiled)?; // make sure we can deserialize it - let _ = self.wasm_ctx.deserialize_module(self.elf_path(module_id))?; + let _ = self + .wasm_ctx + .deserialize_component(self.elf_path(module_id))?; } Ok(_) => {} }; @@ -285,7 +291,7 @@ impl ModuleRegistry { fn ensure_module_in_fs(&self, module_id: &str) -> Result { if self.module_needs_check(module_id) { - match self.compile_module(module_id, false) { + match self.compile_component(module_id, false) { Ok(_) => {} Err(e) => { let mut lck = self.modules.lock().unwrap(); @@ -298,7 +304,7 @@ impl ModuleRegistry { Ok(self.elf_path(module_id)) } - fn create_module(&self, wasm_bytes: Vec, auth: AuthInfo) -> Result { + fn create_component(&self, wasm_bytes: Vec, auth: AuthInfo) -> Result { ensure_user!(self.wasm_ctx.limits.module_upload, "module upload disabled"); let timer = Instant::now(); @@ -357,17 +363,17 @@ impl ModuleRegistry { "auth": auth, }), )?; - self.compile_module(module_id, true)? + self.compile_component(module_id, true)? } else { - self.compile_module(module_id, false)? + self.compile_component(module_id, false)? }, ) } - fn mk_module(&self, req: MkModuleReq, auth: AuthInfo) -> Result { + fn mk_component(&self, req: MkModuleReq, auth: AuthInfo) -> Result { let wasm_bytes = base64::engine::general_purpose::STANDARD.decode(req.binary)?; Ok(serde_json::to_value( - &self.create_module(wasm_bytes, auth)?, + &self.create_component(wasm_bytes, auth)?, )?) } @@ -446,7 +452,11 @@ impl ModuleRegistry { Ok(json!(resp)) } - fn resolve_gh_module(&self, module_id: &str, wasm_override: Option>) -> Result { + fn resolve_gh_component( + &self, + module_id: &str, + wasm_override: Option>, + ) -> Result { if !module_id.starts_with("gh:") { return Ok(module_id.to_string()); } @@ -561,7 +571,7 @@ impl ModuleRegistry { .read_to_end(&mut wasm_bytes)?; log::info!("downloaded {} bytes", wasm_bytes.len()); } - let resp = self.create_module( + let resp = self.create_component( wasm_bytes, AuthInfo { user: wasm_url.to_string(), @@ -573,7 +583,7 @@ impl ModuleRegistry { } fn instantiate(&mut self, mut req: InstantiateReq) -> Result { - req.module_id = self.resolve_gh_module(&req.module_id, None)?; + req.module_id = self.resolve_gh_component(&req.module_id, None)?; if valid_tagname(&req.module_id) { let taginfo = self.read_tag(&req.module_id)?; req.module_id = taginfo.module_id; @@ -718,7 +728,7 @@ impl Stepper { fn aici_mid_process(&mut self, req: AiciMidProcessReq) -> Result { let block_elts = self.globals.tokrx_info.vocab_size as usize; - let mut outputs = HashMap::default(); + let mut outputs: SeqMap = HashMap::default(); // first, execute forks let mut parents = HashMap::default(); @@ -769,7 +779,7 @@ impl Stepper { .get(&par) .unwrap() .iter() - .map(|id| SeqId(*id as u32)) + .map(|id| *id as SeqId) .collect::>(); let op = RtMidProcessArg { op: MidProcessArg { @@ -848,29 +858,59 @@ impl Stepper { } if let Some(r) = &mut data.result { - r.branches = r + let branches = r .branches .iter() .map(|b| { - b.map_mask(|off| { - let idx = (*off - first_mask_byte_offset) / mask_num_bytes; - assert!(idx * mask_num_bytes + first_mask_byte_offset == *off); - max_offset = std::cmp::max(max_offset, *off); + b.map_mask(|vob| { + let shm = self.shm.clone(); + let off = shm.alloc(id.try_into().unwrap()).unwrap(); + let bias_type = + BiasType::from_u32(shm.elt_type() & 0xf).unwrap(); + + bias_type.apply_to_shm_allocator(bytemuck::cast_slice(&vob.data), &shm, off); + + let idx = (off - first_mask_byte_offset) / mask_num_bytes; + assert!(idx * mask_num_bytes + first_mask_byte_offset == off); + max_offset = std::cmp::max(max_offset, off); max_idx = std::cmp::max(max_idx, idx); idx }) }) .collect(); + + outputs.insert( + id, + SequenceResult { + result: Some(RtMidProcessResult { branches }), + error: String::new(), + storage: vec![], + logs: String::new(), + micros: start_time.elapsed().as_micros() as u64, + }, + ); + } else { + outputs.insert( + id, + SequenceResult { + result: Some(RtMidProcessResult { + branches: vec![toktrie::Branch::noop()], + }), + error: String::new(), + storage: vec![], + logs: String::new(), + micros: start_time.elapsed().as_micros() as u64, + }, + ); } - outputs.insert(id, data); } Err(e) => { if e.to_string() == "timeout" && prev_timeout < self.limits.max_timeout_steps { outputs.insert( id, SequenceResult { - result: Some(ProcessResultOffset { - branches: vec![Branch::noop()], + result: Some(RtMidProcessResult { + branches: vec![toktrie::Branch::noop()], }), error: String::new(), storage: vec![], @@ -915,8 +955,8 @@ impl Stepper { fn worker_error( &mut self, - instid: usize, - map: &mut HashMap>, + instid: ModuleInstId, + map: &mut HashMap>, e: anyhow::Error, ) { let err = format!("Worker: {e:?}"); @@ -948,7 +988,7 @@ impl Exec for ModuleRegistry { match json["op"].as_str() { Some("set_tags") => self.set_tags(serde_json::from_value(json)?, auth), Some("get_tags") => self.get_tags(serde_json::from_value(json)?), - Some("mk_module") => self.mk_module(serde_json::from_value(json)?, auth), + Some("mk_module") => self.mk_component(serde_json::from_value(json)?, auth), Some("instantiate") => self.instantiate(serde_json::from_value(json)?), _ => return Err(anyhow!("bad op")), } @@ -1191,10 +1231,10 @@ fn install_from_cmdline(cli: &Cli, wasm_ctx: WasmContext, shm: Rc) let module_id = if name.ends_with(".wasm") { let wasm_bytes = fs::read(name).unwrap(); if let Some(gh) = &cli.gh_module { - reg.resolve_gh_module(gh, Some(wasm_bytes)).unwrap() + reg.resolve_gh_component(gh, Some(wasm_bytes)).unwrap() } else { let json = reg - .create_module(wasm_bytes, AuthInfo::admin_user()) + .create_component(wasm_bytes, AuthInfo::admin_user()) .unwrap(); json.module_id } diff --git a/aicirt/src/moduleinstance.rs b/aicirt/src/moduleinstance.rs index b46e7305..53cd45e9 100644 --- a/aicirt/src/moduleinstance.rs +++ b/aicirt/src/moduleinstance.rs @@ -1,34 +1,40 @@ use crate::{ api::ModuleInstId, - hostimpl::{setup_linker, AiciLimits, GlobalInfo, ModuleData}, + hostimpl::{AiciLimits, GlobalInfo, ModuleData}, + setup_component_linker, + shm::Shm, worker::{GroupHandle, RtMidProcessArg}, TimerSet, UserError, }; -use aici_abi::{toktrie::TokTrie, InitPromptArg, InitPromptResult, ProcessResultOffset, TokenId}; +use aici_abi::toktrie::TokTrie; use aicirt::{ api::{InferenceCapabilities, SequenceResult}, - bail_user, + bindings::{self, aici::abi::tokenizer::Host, exports::aici::abi::controller::*, InitPromptResult}, bintokens::ByteTokenizer, shm::ShmAllocator, user_error, }; -use anyhow::{anyhow, ensure, Result}; -use serde::Deserialize; +use anyhow::{bail, ensure, Result}; use std::{path::PathBuf, rc::Rc, sync::Arc, time::Instant}; use wasmtime; #[derive(Clone)] pub struct WasmContext { pub engine: wasmtime::Engine, - pub linker: Arc>, + pub component_linker: Arc>, pub globals: GlobalInfo, pub limits: AiciLimits, pub timers: TimerSet, } impl WasmContext { - pub fn deserialize_module(&self, path: PathBuf) -> Result { - unsafe { wasmtime::Module::deserialize_file(&self.engine, path) } + pub fn deserialize_component( + &self, + path: PathBuf, + ) -> Result { + // TODO: Use type safety to ensure that the input is derived from `Component::serialize` or + // `Engine::precompile_component`. + unsafe { wasmtime::component::Component::deserialize_file(&self.engine, path) } } pub fn new( @@ -47,6 +53,7 @@ impl WasmContext { .wasm_threads(false) .wasm_simd(true) .wasm_relaxed_simd(false) + .wasm_component_model(true) .wasm_bulk_memory(true) .wasm_multi_value(true) .wasm_memory64(false) @@ -58,14 +65,14 @@ impl WasmContext { cfg.macos_use_mach_ports(false); // disable stuff we don't need - cfg.wasm_backtrace_details(wasmtime::WasmBacktraceDetails::Disable) - .wasm_reference_types(false); + cfg.wasm_backtrace_details(wasmtime::WasmBacktraceDetails::Disable); // compilation in Speed mode seems to be ~10% slower but the generated code is 20-30% faster cfg.cranelift_opt_level(wasmtime::OptLevel::Speed); let engine = wasmtime::Engine::new(&cfg)?; - let linker = setup_linker(&engine)?; + // let linker = setup_linker(&engine)?; + let component_linker = setup_component_linker(&engine)?; let tokens = tokenizer.token_bytes(); let trie = TokTrie::from(&tokenizer.tokrx_info(), &tokens); @@ -90,7 +97,7 @@ impl WasmContext { Ok(Self { engine, - linker, + component_linker, globals, limits, timers: TimerSet::new(), @@ -100,124 +107,36 @@ impl WasmContext { pub struct ModuleInstance { store: wasmtime::Store, - memory: wasmtime::Memory, - instance: wasmtime::Instance, - handle: WasmAici, + aici: bindings::Aici, + runner: bindings::Runner, #[allow(dead_code)] limits: AiciLimits, } -type WasmPtr = u32; -type WasmAici = u32; - -impl ModuleInstance { - fn call_func(&mut self, name: &str, params: Params) -> Result - where - Params: wasmtime::WasmParams, - Results: wasmtime::WasmResults, - { - if self.store.data().had_error { - bail_user!("Previous WASM Error"); - } - let f = self - .instance - .get_typed_func::(&mut self.store, name)?; - let r = f.call(&mut self.store, params); - let ctx = self.store.data_mut(); - ctx.flush_logs(name); - match r { - Ok(r) => Ok(r), - Err(e) => { - ctx.had_error = true; - if let Some(e) = e.downcast_ref::() { - Err(user_error!("{}\n{}", ctx.string_log(), e)) - } else if let Some(bt) = e.downcast_ref::() { - Err(user_error!( - "{}\n{}\n\n{}", - ctx.string_log(), - bt, - e.root_cause() - )) - } else { - Err(anyhow!("{:?}\n\n{}", e, ctx.string_log())) - } - } - } - } - - #[allow(dead_code)] - fn write_mem(&mut self, src: &[T], ptr: WasmPtr) -> Result<()> { - let len = src.len(); - let numbytes = len * std::mem::size_of::(); - - let dest_slice = &mut self.memory.data_mut(&mut self.store)[ptr as usize..]; - - ensure!(dest_slice.len() >= numbytes); - - unsafe { - std::ptr::copy_nonoverlapping( - src.as_ptr() as *const u8, - dest_slice.as_mut_ptr(), - numbytes, - ); - } - - Ok(()) - } - - #[allow(dead_code)] - fn read_mem(&self, ptr: WasmPtr, target: &mut [T]) -> Result<()> { - let numbytes = target.len() * std::mem::size_of::(); - let src_slice = &self.memory.data(&self.store)[ptr as usize..]; - ensure!(src_slice.len() >= numbytes); - unsafe { - std::ptr::copy_nonoverlapping( - src_slice.as_ptr(), - target.as_mut_ptr() as *mut u8, - numbytes, - ) - } - Ok(()) - } -} impl ModuleInstance { pub fn new( id: ModuleInstId, ctx: WasmContext, - module: wasmtime::Module, + component: wasmtime::component::Component, module_arg: String, group_channel: GroupHandle, - shm: Rc, ) -> Result { - let engine = module.engine(); - let mut store = wasmtime::Store::new( - engine, - ModuleData::new( - id, - &ctx.limits, - &module, - module_arg, - &ctx.linker, - ctx.globals, - group_channel, - shm, - ), + &ctx.engine.clone(), + ModuleData::new(id, &ctx.limits, ctx.globals, group_channel), ); store.limiter(|state| &mut state.store_limits); - let instance = ctx.linker.instantiate(&mut store, &module)?; - let memory = instance - .get_memory(&mut store, "memory") - .ok_or_else(|| anyhow!("memory missing"))?; - store.data_mut().instance = Some(instance); - store.data_mut().memory = Some(memory); + let aici = bindings::Aici::instantiate(&mut store, &component, &ctx.component_linker)?; + let runner = aici + .aici_abi_controller() + .runner() + .call_constructor(&mut store, &module_arg)?; Ok(ModuleInstance { - handle: 0, store, - memory, - instance, + aici, + runner, limits: ctx.limits, }) } @@ -226,64 +145,20 @@ impl ModuleInstance { self.store.data_mut().id = id; } - fn run_init(&mut self) -> Result<()> { - self.call_func::<(), ()>("aici_init", ())?; - Ok(()) - } - - pub fn run_main(&mut self) -> Result<()> { - self.run_init()?; - let t0 = Instant::now(); - if self - .instance - .get_export(&mut self.store, "aici_main") - .is_some() - { - self.call_func::("aici_main", self.handle)?; - } else { - let _ = self.call_func::<(i32, i32), i32>("main", (0, 0))?; - } - //println!("{}\n", self.store.data_mut().string_log()); - println!("time: {:?}", t0.elapsed()); - Ok(()) - } - pub fn group_channel(&self) -> &GroupHandle { &self.store.data().group_channel } - fn proc_result Deserialize<'a>>(&self) -> Result { - let bytes = &self.store.data().process_result; - if bytes.len() == 0 { - Err(anyhow!("aici_host_return_process_result not called")) - } else { - serde_json::from_slice::(bytes).map_err(|e| e.into()) - } - } - fn do_mid_process(&mut self, op: RtMidProcessArg) -> Result { - self.store.data_mut().set_mid_process_data(op); - self.call_func::("aici_mid_process", self.handle)?; - let res: ProcessResultOffset = self.proc_result()?; - let offs = &self.store.data().logit_offsets; - let res = ProcessResultOffset { - branches: res - .branches - .iter() - .map(|b| { - b.map_mask(|o| { - let o32 = *o as u32; - if !offs.contains(&o32) { - panic!("logit offset not found: {}", o); - } - *o - }) - }) - .collect(), - }; - Ok(res) + fn do_mid_process(&mut self, arg: RtMidProcessArg) -> Result { + self.aici.aici_abi_controller().runner().call_mid_process( + &mut self.store, + self.runner, + &arg.op, + ) } + fn seq_result(&mut self, lbl: &str, t0: Instant, res: Result) -> SequenceResult { // 10us accuracy for Spectre mitigation let micros = (t0.elapsed().as_micros() as u64 / 10) * 10; @@ -313,7 +188,7 @@ impl ModuleInstance { } } - pub fn mid_process(&mut self, op: RtMidProcessArg) -> SequenceResult { + pub fn mid_process(&mut self, op: RtMidProcessArg) -> SequenceResult { let t0 = Instant::now(); let res = self.do_mid_process(op); // log::info!("mid_process: {:?}", t0.elapsed()); @@ -321,20 +196,16 @@ impl ModuleInstance { } pub fn tokenize(&mut self, s: &str) -> Result> { - self.store.data_mut().tokenize_bytes(s.as_bytes()) + self.store.data_mut().tokenize_str(s) } fn setup_inner(&mut self, prompt: Vec) -> Result { - self.run_init()?; - - self.handle = self.call_func::<(), WasmAici>("aici_create", ())?; - - self.store - .data_mut() - .set_process_arg(serde_json::to_vec(&InitPromptArg { prompt })?); - self.call_func::("aici_init_prompt", self.handle)?; - let res: InitPromptResult = self.proc_result()?; - Ok(res) + let res = self.aici.aici_abi_controller().runner().call_init_prompt( + &mut self.store, + self.runner, + &InitPromptArg { prompt }, + )?; + Ok(res.into()) } pub fn setup(&mut self, prompt: Vec) -> SequenceResult { diff --git a/aicirt/src/msgchannel.rs b/aicirt/src/msgchannel.rs index ce7f7fa2..e48ff67b 100644 --- a/aicirt/src/msgchannel.rs +++ b/aicirt/src/msgchannel.rs @@ -1,4 +1,7 @@ -use crate::{semaphore::Semaphore, shm::{Shm, Unlink}}; +use crate::{ + semaphore::Semaphore, + shm::{Shm, Unlink}, +}; use anyhow::Result; use std::time::Duration; diff --git a/aicirt/src/worker.rs b/aicirt/src/worker.rs index 95fd5b70..7efb9297 100644 --- a/aicirt/src/worker.rs +++ b/aicirt/src/worker.rs @@ -1,16 +1,16 @@ use crate::{ api::ModuleInstId, + bindings::MidProcessArg, hostimpl::AiciLimits, moduleinstance::{ModuleInstance, WasmContext}, setup_bg_worker_pool, shm::Shm, InstantiateReq, UserError, }; -use aici_abi::{ - InitPromptResult, MidProcessArg, ProcessResultOffset, StorageCmd, StorageResp, TokenId, -}; +use aici_abi::{toktrie, StorageCmd, StorageOp, StorageResp}; use aicirt::{ api::SequenceResult, + bindings::*, futexshm::{TypedClient, TypedClientHandle, TypedServer}, set_max_priority, shm::{ShmAllocator, Unlink}, @@ -329,7 +329,7 @@ impl SeqCtx { SeqCmd::Compile { wasm } => { let inp_len = wasm.len(); let start_time = Instant::now(); - let binary = self.wasm_ctx.engine.precompile_module(&wasm)?; + let binary = self.wasm_ctx.engine.precompile_component(&wasm)?; log::info!( "WASM compile done; {}k -> {}k; {:?}", inp_len / 1024, @@ -360,16 +360,15 @@ impl SeqCtx { prompt_str, prompt_toks, } => { - let module = self.wasm_ctx.deserialize_module(module_path).unwrap(); + let component = self.wasm_ctx.deserialize_component(module_path)?; let _ = module_id; let ch = std::mem::take(&mut self.query); let mut inst = ModuleInstance::new( 424242, self.wasm_ctx.clone(), - module, + component, module_arg, ch.unwrap(), - self.shm.clone(), )?; let prompt_toks = if let Some(t) = prompt_toks { t @@ -401,7 +400,8 @@ impl SeqCtx { }) } SeqCmd::RunMain {} => { - self.mutinst().run_main()?; + // TODO + // self.mutinst().run_main()?; ok() } } @@ -519,7 +519,7 @@ impl SeqWorkerHandle { Ok(()) } - pub fn check_process(&self, timeout: Duration) -> Result> { + pub fn check_process(&self, timeout: Duration) -> Result> { match self .handle .seq_recv_with_timeout("r-process", Timeout::Speculative(timeout)) diff --git a/controllers/aici_abi/.cargo/config.toml b/controllers/aici_abi/.cargo/config.toml index e0b0d22a..774e91b1 100644 --- a/controllers/aici_abi/.cargo/config.toml +++ b/controllers/aici_abi/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasi" +target = "wasm32-wasip2" [profile.dev] strip = "debuginfo" diff --git a/controllers/aici_abi/Cargo.toml b/controllers/aici_abi/Cargo.toml index c91546c6..190067b8 100644 --- a/controllers/aici_abi/Cargo.toml +++ b/controllers/aici_abi/Cargo.toml @@ -19,12 +19,9 @@ vob = { version = "3.0.3", optional = true } rustc-hash = { version = "2.0.0", optional = true } bytemuck = "1.16.0" bytemuck_derive = "1.6.0" +aici_wasm_guest = { version = "0.1.0", path = "../aici_wasm_guest" } [features] default = ["cfg", "rx"] cfg = ["dep:cfgrammar", "dep:lrtable", "dep:vob", "dep:rustc-hash"] rx = ["dep:regex-automata"] - -[[bin]] -name = "yesno" -path = "src/yesno.rs" diff --git a/controllers/aici_abi/src/bindings.rs b/controllers/aici_abi/src/bindings.rs new file mode 100644 index 00000000..4e92bca9 --- /dev/null +++ b/controllers/aici_abi/src/bindings.rs @@ -0,0 +1 @@ +pub use aici_wasm_guest::*; diff --git a/controllers/aici_abi/src/cfg.rs b/controllers/aici_abi/src/cfg.rs index c0fb412e..74137b81 100644 --- a/controllers/aici_abi/src/cfg.rs +++ b/controllers/aici_abi/src/cfg.rs @@ -1,6 +1,6 @@ -use crate::host::host_trie; use crate::lex::{Lexer, LexerState, StateID, VobIdx, VobSet}; use crate::{ + tokenizer, toktrie::{Recognizer, SpecialToken}, SimpleVob, }; @@ -12,6 +12,7 @@ use cfgrammar::{ use lrtable::{from_yacc, Action, Minimiser, StIdx, StateTable}; use rustc_hash::FxHashMap; use std::{cell::RefCell, vec}; +use toktrie::TokTrie; use vob::{vob, Vob}; type StorageT = u32; @@ -507,7 +508,7 @@ pub fn cfg_test() -> Result<()> { let sample = include_bytes!("../grammars/sample.c"); if true { - let trie = host_trie(); + let trie = TokTrie::from_bytes(&tokenizer::token_trie_bytes()); let toks = trie.greedy_tokenize(sample); #[cfg(not(target_arch = "wasm32"))] diff --git a/controllers/aici_abi/src/host.rs b/controllers/aici_abi/src/host.rs index 222666e8..5d9e5589 100644 --- a/controllers/aici_abi/src/host.rs +++ b/controllers/aici_abi/src/host.rs @@ -1,233 +1,7 @@ -use crate::{bytes::vec_from_bytes, toktrie::TokTrie, SeqId, SimpleVob, TokenId}; use serde::{Deserialize, Serialize}; -use toktrie::TokenizerEnv; -#[repr(transparent)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -struct BlobId(u32); +use crate::runtime; -#[allow(dead_code)] -extern "C" { - // Read binary blob. - // Always returns the size of the blob, will write up to `size` bytes to `dst`. - fn aici_host_read_blob(blob: BlobId, dst: *mut u8, size: u32) -> u32; - - // Return the ID of TokTrie binary representation. - fn aici_host_token_trie() -> BlobId; - - // Return the ID of argument passed by the user. - fn aici_host_module_arg() -> BlobId; - - // Return the ID of argument passed to the process() function. - // It's a JSON serialization of Pre/Mid/PostProcessArg. - fn aici_host_process_arg() -> BlobId; - - // Tokenize given UTF8 string. The result is only valid until next call to this function. - fn aici_host_tokenize(src: *const u8, src_size: u32) -> BlobId; - - // Set logit bias based on bit-mask in src. - fn aici_host_return_logit_bias(src: *const u32) -> u32; - - fn aici_host_self_seq_id() -> u32; - - fn aici_host_return_process_result(res: *const u8, res_size: u32); - - fn aici_host_storage_cmd(cmd: *const u8, cmd_size: u32) -> BlobId; - - // This can be also obtained from the TokTrie. - fn aici_host_eos_token() -> TokenId; - - // Get value of configuration parameters, like "fork". - fn aici_host_get_config(src: *const u8, src_size: u32) -> i32; - - // Stop the program - any error info is assumed to have been printed already. - // Backtraces will be limited. - fn aici_host_stop(); -} - -// TODO: add -fn read_blob(blob: BlobId, prefetch_size: usize) -> Vec { - let mut buffer = vec![0u8; prefetch_size]; - let prefetch_size = prefetch_size as u32; - let size = unsafe { aici_host_read_blob(blob, buffer.as_mut_ptr(), prefetch_size) }; - buffer.resize(size as usize, 0); - if size > prefetch_size { - // didn't read everything; retry - unsafe { aici_host_read_blob(blob, buffer.as_mut_ptr(), size) }; - } - buffer -} - -#[cfg(target_arch = "wasm32")] -fn init_panic() { - std::panic::set_hook(Box::new(|info| { - // skip 'run with `RUST_BACKTRACE=1`' message (not relevant for remote running) - println!("{}", info); - })) -} - -#[cfg(target_arch = "wasm32")] -#[no_mangle] -pub extern "C" fn aici_init() { - init_panic(); - set_host(Box::new(WasmHost {})); -} - -pub struct WasmTokenizerEnv { - toktrie: TokTrie, -} - -impl Default for WasmTokenizerEnv { - fn default() -> Self { - WasmTokenizerEnv { - toktrie: host_trie(), - } - } -} - -impl TokenizerEnv for WasmTokenizerEnv { - fn stop(&self) -> ! { - aici_stop() - } - - fn tok_trie(&self) -> &TokTrie { - &self.toktrie - } - - fn tokenize_bytes(&self, s: &[u8]) -> Vec { - tokenize_bytes(s) - } -} - -/** - * This is normally implemented straightforwardly by wasm callbacks. - * It can be overridden with set_host() when compiling to native. - */ -pub trait HostInterface { - fn arg_bytes(&self) -> Vec; - fn trie_bytes(&self) -> Vec; - fn return_logit_bias(&self, vob: &SimpleVob) -> u32; - fn process_arg_bytes(&self) -> Vec; - fn return_process_result(&self, res: &[u8]); - fn storage_cmd(&self, cmd: StorageCmd) -> StorageResp; - fn tokenize_bytes(&self, s: &[u8]) -> Vec; - fn self_seq_id(&self) -> SeqId; - fn eos_token(&self) -> TokenId; - fn get_config(&self, name: &str) -> i32; - fn stop(&self) -> !; -} - -static mut HOST: Option> = None; - -struct WasmHost {} -impl HostInterface for WasmHost { - fn arg_bytes(&self) -> Vec { - read_blob(unsafe { aici_host_module_arg() }, 1024) - } - - fn trie_bytes(&self) -> Vec { - read_blob(unsafe { aici_host_token_trie() }, 0) - } - - fn return_logit_bias(&self, vob: &SimpleVob) -> u32 { - assert!(vob.len() > 0); - unsafe { aici_host_return_logit_bias(vob.as_ptr()) } - } - - fn process_arg_bytes(&self) -> Vec { - read_blob(unsafe { aici_host_process_arg() }, 1024) - } - - fn return_process_result(&self, res: &[u8]) { - unsafe { - aici_host_return_process_result(res.as_ptr(), res.len() as u32); - } - } - - fn storage_cmd(&self, cmd: StorageCmd) -> StorageResp { - let cmd_bytes = serde_json::to_vec(&cmd).unwrap(); - let res_id = unsafe { aici_host_storage_cmd(cmd_bytes.as_ptr(), cmd_bytes.len() as u32) }; - let resp_bytes = read_blob(res_id, 1024); - serde_json::from_slice(&resp_bytes).unwrap() - } - - fn stop(&self) -> ! { - unsafe { aici_host_stop() }; - panic!("didn't stop") - } - - fn tokenize_bytes(&self, s: &[u8]) -> Vec { - let id = unsafe { aici_host_tokenize(s.as_ptr(), s.len() as u32) }; - let r = read_blob(id, 4 * (s.len() / 3 + 10)); - let res = vec_from_bytes(&r); - // println!( - // "tokenize_bytes: {:?} -> {:?}", - // String::from_utf8_lossy(s), - // res - // ); - res - } - - fn self_seq_id(&self) -> SeqId { - unsafe { SeqId(aici_host_self_seq_id()) } - } - - fn eos_token(&self) -> TokenId { - unsafe { aici_host_eos_token() } - } - - fn get_config(&self, name: &str) -> i32 { - let name_bytes = name.as_bytes(); - let res = unsafe { aici_host_get_config(name_bytes.as_ptr(), name_bytes.len() as u32) }; - res - } -} - -fn get_host() -> &'static Box { - unsafe { HOST.as_ref().unwrap() } -} - -pub fn set_host(host: Box) { - unsafe { - assert!(HOST.is_none()); - HOST = Some(host); - } -} - -pub fn arg_bytes() -> Vec { - get_host().arg_bytes() - - // #[cfg(not(target_arch = "wasm32"))] - // return std::fs::read("arg.json").unwrap(); -} - -pub fn arg_string() -> String { - String::from_utf8_lossy(&arg_bytes()).to_string() -} - -pub fn host_trie() -> TokTrie { - TokTrie::from_bytes(&get_host().trie_bytes()) - // #[cfg(not(target_arch = "wasm32"))] - // return std::fs::read("tokenizer.bin").unwrap(); -} - -pub fn return_logit_bias(vob: &SimpleVob) -> u32 { - get_host().return_logit_bias(vob) -} - -pub fn process_arg_bytes() -> Vec { - get_host().process_arg_bytes() -} - -pub fn return_process_result(res: &[u8]) { - unsafe { - aici_host_return_process_result(res.as_ptr(), res.len() as u32); - } -} - -pub fn get_config(name: &str) -> i32 { - get_host().get_config(name) -} #[derive(Serialize, Deserialize, Debug, Clone)] pub enum StorageOp { @@ -235,27 +9,12 @@ pub enum StorageOp { Append, } -#[allow(dead_code)] -pub mod bin_string { - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - - pub fn serialize(v: &Vec, s: S) -> Result { - let binstr = String::from_iter(v.iter().map(|b| *b as char)); - String::serialize(&binstr, s) - } - - pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { - let binstr = String::deserialize(d)?; - Ok(binstr.chars().map(|c| c as u8).collect()) - } -} - pub mod hex_string { use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::bytes::{from_hex_string, to_hex_string}; - pub fn serialize(v: &Vec, s: S) -> Result { + pub fn serialize(v: &[u8], s: S) -> Result { let hexstr = to_hex_string(v); String::serialize(&hexstr, s) } @@ -300,84 +59,11 @@ pub enum StorageResp { WriteVar { version: u64 }, } -pub fn storage_cmd(cmd: StorageCmd) -> StorageResp { - let cmd_bytes = serde_json::to_vec(&cmd).unwrap(); - let res_id = unsafe { aici_host_storage_cmd(cmd_bytes.as_ptr(), cmd_bytes.len() as u32) }; - let resp_bytes = read_blob(res_id, 1024); - serde_json::from_slice(&resp_bytes).unwrap() -} // Public APIs -pub struct VariableStorage { - // no fields (yet?) -} - -impl VariableStorage { - /// Create a new instance of VariableStorage. It currently has no fields. - pub fn new() -> Self { - VariableStorage {} - } - - /// Read variable. Returns None if the variable is unset. - pub fn get(&self, name: &str) -> Option> { - self.get_with_version(name).map(|x| x.1) - } - - /// Write specified value to variable. - pub fn set(&self, name: &str, value: Vec) { - let _ver = self.write_var(name, value, StorageOp::Set); - } - - /// Append specified value to variable. - pub fn append(&self, name: &str, value: Vec) { - let _ver = self.write_var(name, value, StorageOp::Append); - } - - fn write_var(&self, name: &str, value: Vec, op: StorageOp) -> u64 { - match storage_cmd(StorageCmd::WriteVar { - name: name.to_string(), - value, - op, - when_version_is: None, - }) { - StorageResp::WriteVar { version } => version, - _ => panic!("unexpected response to write var"), - } - } - - fn get_with_version(&self, name: &str) -> Option<(u64, Vec)> { - match storage_cmd(StorageCmd::ReadVar { - name: name.to_string(), - }) { - StorageResp::ReadVar { version, value } => Some((version, value)), - StorageResp::VariableMissing {} => None, - StorageResp::WriteVar { .. } => panic!("unexpected response to read var"), - } - } -} - -/// Tokenize given byte string. -pub fn tokenize_bytes(s: &[u8]) -> Vec { - get_host().tokenize_bytes(s) -} - -/// Tokenize given UTF8 string. -pub fn tokenize(s: &str) -> Vec { - get_host().tokenize_bytes(s.as_bytes()) -} - -/// Return the ID of the current process. -pub fn self_seq_id() -> SeqId { - get_host().self_seq_id() -} - -/// Return the ID of the EOS token. -pub fn eos_token() -> TokenId { - get_host().eos_token() -} - /// Stop the program - any error info is assumed to have been printed already. pub fn aici_stop() -> ! { - get_host().stop(); + runtime::stop(); + panic!("didn't stop"); } diff --git a/controllers/aici_abi/src/lib.rs b/controllers/aici_abi/src/lib.rs index 362a9a44..4a218f3c 100644 --- a/controllers/aici_abi/src/lib.rs +++ b/controllers/aici_abi/src/lib.rs @@ -2,7 +2,20 @@ pub use toktrie; pub use toktrie::{bytes, recognizer, rng}; pub use toktrie::{SimpleVob, TokenizerEnv}; -use serde::{Deserialize, Serialize}; +use std::sync::{Arc, Mutex}; + +mod bindings; + +pub use bindings::{controller::*, runtime, runtime_storage, tokenizer}; + +#[macro_export] +macro_rules! export { + ($ty:ident) => { + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + $crate::bindings::export!($ty with_types_in $crate::bindings); + }; +} mod host; @@ -18,53 +31,56 @@ pub mod dlex; pub mod substring; -pub type TokenId = toktrie::TokenId; +pub use host::{aici_stop, StorageCmd, StorageOp, StorageResp}; -pub use host::{ - aici_stop, arg_bytes, arg_string, get_config, host_trie, self_seq_id, tokenize, tokenize_bytes, - StorageCmd, StorageOp, StorageResp, VariableStorage, WasmTokenizerEnv, -}; +impl From for InitPromptResult { + fn from(value: InitPromptArg) -> Self { + InitPromptResult { + prompt: value.prompt, + } -#[cfg(not(target_arch = "wasm32"))] -pub use host::{set_host, HostInterface}; + } +} -#[derive(Serialize, Deserialize, Debug)] -pub struct InitPromptArg { - pub prompt: Vec, +impl InitPromptResult { + pub fn from_arg(arg: InitPromptArg) -> Self { + arg.into() + } } -#[derive(Serialize, Deserialize, Debug)] -pub struct InitPromptResult { - pub prompt: Vec, +impl From for Vocabulary { + fn from(value: toktrie::SimpleVob) -> Self { + let size = value.len() as u64; + Vocabulary { + data: value.into(), + size, + } + } } -impl InitPromptResult { - pub fn from_arg(arg: InitPromptArg) -> Self { - InitPromptResult { prompt: arg.prompt } +impl From for Splice { + fn from(value: toktrie::Splice) -> Self { + Splice { + backtrack: value.backtrack, + ff_tokens: value.ff_tokens, + when_sampled: value.when_sampled, + } } } -#[repr(transparent)] -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub struct SeqId(pub u32); - -#[derive(Serialize, Deserialize, Debug)] -pub struct MidProcessArg { - /// Sampling result for the previous iteration. - /// For simple sampled token 't', backtrack==0 and tokens==[t]. - /// For first request, backtrack==0 and tokens==[] (prompt is passed separately, before). - /// Can be more complex when splices are used. - pub backtrack: u32, - pub tokens: Vec, - /// The token that was sampled, before splicing, if any. - pub sampled: Option, - /// - pub fork_group: Vec, +impl From> for Branch { + fn from(value: toktrie::Branch) -> Self { + Branch { + sample_mask: value.sample_mask.map(|x| x.into()), + splices: value.splices.into_iter().map(|x| x.into()).collect(), + temperature: value.temperature, + } + } } impl MidProcessArg { pub fn has_eos(&self) -> bool { - let eos = host::eos_token(); + let eos = tokenizer::eos_token(); self.tokens.iter().any(|t| *t == eos) } @@ -79,42 +95,36 @@ impl MidProcessArg { } } -pub use toktrie::{Branch, Splice}; - -#[derive(Debug)] -pub struct MidProcessResult { - /// Fork the request into multiple branches. - /// Typically, exactly one branch is returned. - /// If multiple branches are returned, they are executed in parallel. - /// If no branches are returned, the request is terminated. - pub branches: Vec>, -} - impl MidProcessResult { - pub fn from_branch(branch: Branch) -> Self { + pub fn from_branch(branch: toktrie::Branch) -> Self { if branch.is_stop() { Self::stop() } else { MidProcessResult { - branches: vec![branch], + branches: vec![branch.into()], } } } + pub fn from_branches(branches: Vec>) -> Self { + MidProcessResult { + branches: branches.into_iter().map(|x| x.into()).collect(), + } + } pub fn stop() -> Self { MidProcessResult { branches: vec![] } } - pub fn sample(set: SimpleVob) -> Self { + pub fn sample(set: toktrie::SimpleVob) -> Self { Self::sample_with_temp(set, None) } - pub fn sample_with_temp(set: SimpleVob, temperature: Option) -> Self { - Self::from_branch(Branch::sample(set, temperature)) + pub fn sample_with_temp(set: toktrie::SimpleVob, temperature: Option) -> Self { + Self::from_branch(toktrie::Branch::sample(set, temperature)) } pub fn splice(backtrack: u32, ff_tokens: Vec) -> Self { - Self::from_branch(Branch::splice(backtrack, ff_tokens)) + Self::from_branch(toktrie::Branch::splice(backtrack, ff_tokens)) } pub fn noop() -> Self { @@ -126,113 +136,39 @@ impl MidProcessResult { } } -#[derive(Serialize, Deserialize)] -pub struct ProcessResultOffset { - /// Branches use byte offsets into the bias tensor. - pub branches: Vec>, -} - pub trait AiciCtrl { - /// Called with the initial prompt. ~1000ms time limit. - /// By default ignore prompt. fn init_prompt(&mut self, arg: InitPromptArg) -> InitPromptResult { InitPromptResult::from_arg(arg) } - - /// This is the main entry point for the module. ~20ms time limit. fn mid_process(&mut self, arg: MidProcessArg) -> MidProcessResult; - - // Internals - fn aici_init_prompt(&mut self) { - let arg: InitPromptArg = serde_json::from_slice(&host::process_arg_bytes()).unwrap(); - let res = self.init_prompt(arg); - let res_bytes = serde_json::to_vec(&res).unwrap(); - host::return_process_result(&res_bytes); - } - - fn aici_mid_process(&mut self) { - let arg: MidProcessArg = serde_json::from_slice(&host::process_arg_bytes()) - .expect("aici_mid_process: failed to deserialize MidProcessArg"); - let res = self.mid_process(arg); - let mut used_logits = false; - let res = ProcessResultOffset { - branches: res - .branches - .into_iter() - .map(|b| { - b.map_mask(|vob| { - if used_logits { - panic!("aici_mid_process: multiple branches with sampling not yet supported"); - } - used_logits = true; - host::return_logit_bias(&vob) as usize - }) - }) - .collect(), - }; - let res_bytes = serde_json::to_vec(&res).expect("aici_mid_process: failed to serialize"); - host::return_process_result(&res_bytes); - } } -/// Expose method as extern "C", usage: -/// expose!(Foo::set_count(n: i32) -> i32); -/// Generates "C" function: -/// set_count(Foo *, i32) -> i32 -#[macro_export] -macro_rules! expose { - ($struct_name:ident :: $method_name:ident ( $($arg:ident : $typ:ty),* ) -> $ret:ty) => { - #[no_mangle] - pub extern "C" fn $method_name(self_: *mut $struct_name, $($arg : $typ),*) -> $ret { - unsafe { - (&mut *self_).$method_name($($arg),*) - } - } - }; - ($struct_name:ident :: $field:ident :: $method_name:ident ( $($arg:ident : $typ:ty),* ) -> $ret:ty) => { - #[no_mangle] - pub extern "C" fn $method_name(self_: *mut $struct_name, $($arg : $typ),*) -> $ret { - unsafe { - (&mut *self_).$field.$method_name($($arg),*) - } - } - }; +pub trait Program: AiciCtrl { + fn new(_: String) -> Self; } -#[macro_export] -macro_rules! aici_expose_all { - ($struct_name:ident, $new:expr) => { - $crate::expose!($struct_name::aici_mid_process() -> ()); - $crate::expose!($struct_name::aici_init_prompt() -> ()); - - #[no_mangle] - pub extern "C" fn aici_create() -> *mut $struct_name { - let b = Box::new($new); - Box::into_raw(b) - } +pub struct ExportedProgram { + mutable_controller: Arc>, +} - #[no_mangle] - pub extern "C" fn aici_panic() { - panic!("aici_panic()") +impl ExportedProgram { + pub fn new(controller: C) -> Self { + ExportedProgram { + mutable_controller: Arc::new(Mutex::new(controller)), } } } -#[macro_export] -macro_rules! include_bytes_aligned { - ($align_ty:ty, $path:literal) => {{ - #[repr(C)] // guarantee 'bytes' comes after '_align' - pub struct AlignedAs { - pub _align: [Align; 0], - pub bytes: Bytes, - } +impl GuestRunner for ExportedProgram { + fn new(arg: String) -> Self { + ExportedProgram::new(C::new(arg)) + } - // this assignment is made possible by CoerceUnsized - static ALIGNED: &AlignedAs<$align_ty, [u8]> = &AlignedAs { - _align: [], - bytes: *include_bytes!($path), - }; + fn init_prompt(&self, arg: InitPromptArg) -> InitPromptResult { + self.mutable_controller.lock().unwrap().init_prompt(arg) + } - &ALIGNED.bytes - }}; + fn mid_process(&self, arg: MidProcessArg) -> MidProcessResult { + self.mutable_controller.lock().unwrap().mid_process(arg) + } } diff --git a/controllers/aici_abi/src/recognizer.rs b/controllers/aici_abi/src/recognizer.rs new file mode 100644 index 00000000..cf2fda40 --- /dev/null +++ b/controllers/aici_abi/src/recognizer.rs @@ -0,0 +1,143 @@ +use std::fmt::Debug; + +use toktrie::{Recognizer, TokTrie}; + +use crate::{ + tokenizer, AiciCtrl, MidProcessArg, MidProcessResult, PostProcessArg, PostProcessResult, SampleWithBias +}; + +pub struct AiciRecognizer { + pub trie: TokTrie, + pub rec: R, +} + +impl AiciRecognizer { + pub fn from_recognizer(rec: R) -> Self { + AiciRecognizer { + trie: TokTrie::from_bytes(&tokenizer::token_trie_bytes()), + rec, + } + } +} + +impl AiciCtrl for AiciRecognizer { + fn mid_process(&mut self, _arg: MidProcessArg) -> MidProcessResult { + let mut set = self.trie.alloc_token_set(); + self.trie.compute_bias(&mut self.rec, &mut set); + MidProcessResult::SampleWithBias(SampleWithBias { + allowed_tokens: set, + }) + } + + fn post_process(&mut self, arg: PostProcessArg) -> PostProcessResult { + self.trie.append_tokens(&mut self.rec, &arg.tokens); + PostProcessResult::from_arg(&arg) + } +} + +pub trait FunctionalRecognizer { + /// Initial state + fn initial(&self) -> S; + /// Extend the recognizer with given byte. + fn append(&self, state: S, byte: u8) -> S; + /// Check if given byte is allowed in given state. + fn byte_allowed(&self, state: S, byte: u8) -> bool; + /// Check if given special token is allowed in given state. + fn special_allowed(&self, state: S, tok: SpecialToken) -> bool; +} + +#[derive(Clone)] +pub struct StackRecognizer> { + rec: R, + stack: Vec, + stack_ptr: usize, +} + +impl> StackRecognizer { + pub fn from(rec: R) -> Self { + let stack = vec![rec.initial(); 130]; + StackRecognizer { + rec, + stack, + stack_ptr: 0, + } + } + + pub fn reset(&mut self) { + self.stack_ptr = 0; + self.stack[0] = self.rec.initial(); + } +} + +impl> Debug for StackRecognizer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("StackRecognizer") + .field("top", &self.stack[self.stack_ptr]) + .finish() + } +} + +impl> Recognizer for StackRecognizer { + #[inline(always)] + fn push_byte(&mut self, byte: u8) { + let state = self.stack[self.stack_ptr]; + let state = self.rec.append(state, byte); + self.stack_ptr += 1; + self.stack[self.stack_ptr] = state; + } + + #[inline(always)] + fn pop_bytes(&mut self, num: usize) { + self.stack_ptr -= num; + } + + #[inline(always)] + fn byte_allowed(&mut self, byte: u8) -> bool { + self.rec.byte_allowed(self.stack[self.stack_ptr], byte) + } + + fn trie_finished(&mut self) { + // println!("{:?}", &self.stack[0..=self.stack_ptr]); + assert!(self.stack_ptr == 0); + } + + fn collapse(&mut self) { + self.stack[0] = self.stack[self.stack_ptr]; + self.stack_ptr = 0; + } + + fn special_allowed(&mut self, tok: SpecialToken) -> bool { + self.rec.special_allowed(self.stack[self.stack_ptr], tok) + } + + #[inline(always)] + fn try_push_byte(&mut self, byte: u8) -> bool { + if self.rec.byte_allowed(self.stack[self.stack_ptr], byte) { + self.push_byte(byte); + true + } else { + false + } + } +} + +#[derive(Clone)] +pub struct AnythingGoes {} + +impl FunctionalRecognizer<()> for AnythingGoes { + fn initial(&self) -> () { + () + } + + fn append(&self, state: (), _byte: u8) -> () { + state + } + + fn byte_allowed(&self, _state: (), _byte: u8) -> bool { + true + } + + fn special_allowed(&self, _state: (), _tok: SpecialToken) -> bool { + true + } +} diff --git a/controllers/aici_abi/src/substring.rs b/controllers/aici_abi/src/substring.rs index b8be55d5..10b10650 100644 --- a/controllers/aici_abi/src/substring.rs +++ b/controllers/aici_abi/src/substring.rs @@ -1,5 +1,4 @@ use std::fmt::Display; - use crate::{ bytes::limit_bytes, recognizer::{FunctionalRecognizer, StackRecognizer}, diff --git a/controllers/aici_native/src/variables.rs b/controllers/aici_native/src/variables.rs index 4f0dc07b..c1a3bc03 100644 --- a/controllers/aici_native/src/variables.rs +++ b/controllers/aici_native/src/variables.rs @@ -9,7 +9,7 @@ pub struct Variables { impl Variables { pub fn process_cmd(&mut self, cmd: StorageCmd) -> StorageResp { match cmd { - StorageCmd::ReadVar { name } => match self.variables.get(&name).map(|x| x.clone()) { + StorageCmd::ReadVar { name } => match self.variables.get(&name).cloned() { None => StorageResp::VariableMissing {}, Some((version, value)) => StorageResp::ReadVar { value, version }, }, @@ -19,7 +19,7 @@ impl Variables { when_version_is, op, } => { - let curr = self.variables.get(&name).map(|x| x.clone()); + let curr = self.variables.get(&name).cloned(); match curr { Some((prev_version, prev_val)) => match when_version_is { Some(v) if v != prev_version => StorageResp::ReadVar { @@ -53,4 +53,3 @@ impl Variables { } } } - diff --git a/controllers/aici_wasm_guest/Cargo.toml b/controllers/aici_wasm_guest/Cargo.toml new file mode 100644 index 00000000..eb2c7ae2 --- /dev/null +++ b/controllers/aici_wasm_guest/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "aici_wasm_guest" +version = "0.1.0" +edition = "2021" + +[dependencies] +wit-bindgen = "0.30.0" +serde = { version = "1.0.192", features = ["derive"] } diff --git a/controllers/aici_wasm_guest/src/lib.rs b/controllers/aici_wasm_guest/src/lib.rs new file mode 100644 index 00000000..401cacb7 --- /dev/null +++ b/controllers/aici_wasm_guest/src/lib.rs @@ -0,0 +1,8 @@ +wit_bindgen::generate!({ + world: "aici", + path: "../../wit", + additional_derives: [serde::Serialize, serde::Deserialize], + pub_export_macro: true, +}); + +pub use self::{aici::abi::*, exports::aici::abi::*}; diff --git a/controllers/aici_wasm_host/Cargo.toml b/controllers/aici_wasm_host/Cargo.toml new file mode 100644 index 00000000..2805e8ab --- /dev/null +++ b/controllers/aici_wasm_host/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "aici_wasm_host" +version = "0.1.0" +edition = "2021" + +[dependencies] +wasmtime = { version = "24.0.0", default-features = false, features = ["component-model"] } +serde = { version = "1.0.192", features = ["derive"] } +toktrie = { path = "../toktrie/core" } diff --git a/controllers/aici_wasm_host/src/lib.rs b/controllers/aici_wasm_host/src/lib.rs new file mode 100644 index 00000000..6b3b3a14 --- /dev/null +++ b/controllers/aici_wasm_host/src/lib.rs @@ -0,0 +1,46 @@ +use wasmtime::component::bindgen; + +bindgen!({ + world: "aici", + path: "../../wit", + additional_derives: [ + serde::Deserialize, + serde::Serialize, + ], + trappable_imports: true, // host implementations return wasmtime::Result +}); + +impl Branch { + pub fn map_mask(&self, f: F) -> toktrie::Branch + where + F: FnOnce(&Vocabulary) -> T, + { + toktrie::Branch { + sample_mask: self.sample_mask.as_ref().map(f), + temperature: self.temperature, + splices: self + .splices + .iter() + .map(|s| toktrie::Splice { + backtrack: s.backtrack, + when_sampled: s.when_sampled.clone(), + ff_tokens: s.ff_tokens.clone(), + }) + .collect(), + } + } + + pub fn has_backtrack(&self) -> bool { + let max_bt = if self.sample_mask.is_none() { 0 } else { 1 }; + self.splices.iter().any(|s| s.backtrack > max_bt) + } + + pub fn has_ff_tokens(&self) -> bool { + self.splices.len() > 0 + } +} + +pub use self::{ + aici::abi::{runtime::SeqId, tokenizer::TokenId}, + exports::aici::abi::controller::*, +}; diff --git a/controllers/declctrl/.cargo/config.toml b/controllers/declctrl/.cargo/config.toml index e0b0d22a..774e91b1 100644 --- a/controllers/declctrl/.cargo/config.toml +++ b/controllers/declctrl/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasi" +target = "wasm32-wasip2" [profile.dev] strip = "debuginfo" diff --git a/controllers/declctrl/Cargo.toml b/controllers/declctrl/Cargo.toml index 31077fd3..25dddb99 100644 --- a/controllers/declctrl/Cargo.toml +++ b/controllers/declctrl/Cargo.toml @@ -10,6 +10,5 @@ serde = { version = "1.0.192", features = ["derive"] } serde_json = "1.0.108" anyhow = "1.0.75" -[[bin]] -name = "aici_declctrl" -path = "src/declctrl.rs" +[lib] +crate-type = ["cdylib"] diff --git a/controllers/declctrl/src/declctrl.rs b/controllers/declctrl/src/lib.rs similarity index 95% rename from controllers/declctrl/src/declctrl.rs rename to controllers/declctrl/src/lib.rs index d3e11e47..06fc6582 100644 --- a/controllers/declctrl/src/declctrl.rs +++ b/controllers/declctrl/src/lib.rs @@ -10,7 +10,7 @@ */ use aici_abi::{ - aici_expose_all, bytes::limit_str, cfg::CfgParser, host_trie, rx::{RecRx, RxStackRecognizer}, SimpleVob, tokenize_bytes, toktrie::{Recognizer, SpecialToken, TokTrie}, AiciCtrl, Branch, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult, TokenId, VariableStorage + bytes::limit_str, cfg::CfgParser, export, rx::{RecRx, RxStackRecognizer}, tokenizer, toktrie::{Branch, Recognizer, SpecialToken, TokTrie}, ExportedProgram, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult, SimpleVob, Splice, TokenId }; use core::panic; use serde::{Deserialize, Serialize}; @@ -409,7 +409,6 @@ struct TokenInfo { struct RunnerCtx { trie: TokTrie, - vars: VariableStorage, tokens: Vec, bytes: Vec, } @@ -427,7 +426,7 @@ impl RunnerCtx { fn do_expand(&self, expr: &Expr, curr_ctx: Option<&StepState>) -> Vec { match expr { Expr::String { str } => str.as_bytes().to_vec(), - Expr::Var { var } => match self.vars.get(&var.0) { + Expr::Var { var } => match aici_abi::runtime_storage::get(&var.0) { Some(r) => r, None => Vec::new(), }, @@ -738,7 +737,6 @@ impl StepState { self.check_eos(false) } - #[allow(dead_code)] fn attention_mask(&self, ctx: &RunnerCtx) -> Vec { if self.mask_tags.len() == 0 { vec![] @@ -798,7 +796,10 @@ impl StepState { .iter() .filter_map(|e| { if e.starts_with(pref) { - Some(tokenize_bytes(&e[pref.len()..])) + Some({ + let s: &[u8] = &e[pref.len()..]; + tokenizer::tokenize_bytes(s) + }) } else { None } @@ -856,7 +857,7 @@ impl StepState { Stmt::Set { var, expr } => { let val = runner.expand_with_curr(&expr, self); println!(" set {:?} := {:?}", var, String::from_utf8_lossy(&val)); - runner.vars.set(&var.0, val); + aici_abi::runtime_storage::set(&var.0, &val); } } } @@ -873,7 +874,7 @@ impl StepState { }; let tokens = options .iter() - .map(|v| tokenize_bytes(v)) + .map(|v| tokenizer::tokenize_bytes(v)) .collect::>(); self.specific = StepSpecific::Options { tokens } } @@ -926,10 +927,9 @@ impl Runner { Self { ctx: RunnerCtx { - trie: host_trie(), + trie: TokTrie::from_bytes(&tokenizer::token_trie_bytes()), tokens: Vec::new(), bytes: Vec::new(), - vars: VariableStorage::new(), }, state_idx: 0, prev_state_idx: 0, @@ -1122,7 +1122,10 @@ impl Runner { fn maybe_wait(&mut self) -> bool { if let StepSpecific::Wait { vars } = &self.curr_state().specific { - if vars.iter().any(|name| self.ctx.vars.get(&name.0).is_none()) { + if vars + .iter() + .any(|name| aici_abi::runtime_storage::get(&name.0).is_none()) + { println!("wait {vars:?} suspend"); true } else { @@ -1143,7 +1146,7 @@ impl Runner { } } -impl AiciCtrl for Runner { +impl aici_abi::AiciCtrl for Runner { fn init_prompt(&mut self, arg: InitPromptArg) -> InitPromptResult { println!("prompt: {:?}", arg.prompt); for t in &arg.prompt { @@ -1226,7 +1229,7 @@ impl AiciCtrl for Runner { let st = self.states.remove(self.state_idx); if let StepSpecific::Fork { mut branches } = st.specific { assert!(arg.fork_group.len() == branches.len()); - let my_id = aici_abi::self_seq_id(); + let my_id = aici_abi::runtime::sequence_id(); let idx = arg.fork_group.iter().position(|id| *id == my_id).unwrap(); let branch = branches.remove(idx); self.states.splice(self.state_idx..self.state_idx, branch); @@ -1239,7 +1242,7 @@ impl AiciCtrl for Runner { if let StepSpecific::Fork { branches } = &self.curr_state().specific { assert!(branches.len() > 1); return MidProcessResult { - branches: branches.iter().map(|_| Branch::noop()).collect(), + branches: branches.iter().map(|_| Branch::noop().into()).collect(), }; } @@ -1252,38 +1255,36 @@ impl AiciCtrl for Runner { } } -fn main() { - aici_abi::cfg::cfg_test().unwrap(); - // let _run = sample_prog(); -} - -fn runner_from_env() -> Runner { - let a = aici_abi::arg_bytes(); - match serde_json::from_slice(&a) { - Ok(p) => Runner::new(p), - Err(e) => { - let mut col = e.column().saturating_sub(1); - let mut line = e.line().saturating_sub(1); - for off in 0..a.len() { - if line == 0 { - col -= 1; - if col == 0 { - println!( - "at: {:?} {:?}", - String::from_utf8_lossy(&a[off.saturating_sub(30)..off]), - String::from_utf8_lossy(&a[off..std::cmp::min(a.len(), off + 30)]), - ); - break; +impl aici_abi::Program for Runner { + fn new(arg: String) -> Self { + match serde_json::from_str(&arg) { + Ok(p) => Runner::new(p), + Err(e) => { + let mut col = e.column().saturating_sub(1); + let mut line = e.line().saturating_sub(1); + for off in 0..arg.len() { + if line == 0 { + col -= 1; + if col == 0 { + let prefix = &arg[off.saturating_sub(30)..off]; + let suffix = &arg[off..std::cmp::min(arg.len(), off + 30)]; + println!("at: {:?} {:?}", prefix, suffix,); + break; + } + } + if arg.as_bytes()[off] == b'\n' { + line -= 1; } } - if a[off] == b'\n' { - line -= 1; - } + println!("JSON AST parsing error: {:?}", e); + panic!() } - println!("JSON AST parsing error: {:?}", e); - panic!() } } } -aici_expose_all!(Runner, runner_from_env()); +impl aici_abi::Guest for Runner { + type Runner = ExportedProgram; +} + +export!(Runner); diff --git a/controllers/declctrl/wasm.sh b/controllers/declctrl/wasm.sh index b6fa14db..5d7321d0 100755 --- a/controllers/declctrl/wasm.sh +++ b/controllers/declctrl/wasm.sh @@ -4,7 +4,7 @@ set -x set -e cargo build --release BIN=$(cd ../target; pwd) -cp $BIN/wasm32-wasi/release/aici_declctrl.wasm $BIN/opt.wasm +cp $BIN/wasm32-wasip2/release/aici_declctrl.wasm $BIN/opt.wasm ls -l $BIN/opt.wasm if [ "X$1" = "Xbuild" ] ; then exit diff --git a/controllers/guidance_ctrl/src/earley_bench.rs b/controllers/guidance_ctrl/src/earley_bench.rs new file mode 100644 index 00000000..21a64804 --- /dev/null +++ b/controllers/guidance_ctrl/src/earley_bench.rs @@ -0,0 +1,11 @@ +fn main() { + #[cfg(not(target_arch = "wasm32"))] + bench(); +} + +#[cfg(not(target_arch = "wasm32"))] +fn bench() { + use aici_abi::toktree::TokTrie; + use aici_guidance_ctrl::earley::bench::earley_test; + earley_test(TokTrie::from_bytes(&tokenizer::token_trie_bytes())); +} diff --git a/controllers/jsctrl/.cargo/config.toml b/controllers/jsctrl/.cargo/config.toml index e0b0d22a..774e91b1 100644 --- a/controllers/jsctrl/.cargo/config.toml +++ b/controllers/jsctrl/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasi" +target = "wasm32-wasip2" [profile.dev] strip = "debuginfo" diff --git a/controllers/jsctrl/Cargo.toml b/controllers/jsctrl/Cargo.toml index 115ed916..b1252279 100644 --- a/controllers/jsctrl/Cargo.toml +++ b/controllers/jsctrl/Cargo.toml @@ -12,9 +12,8 @@ anyhow = "1.0.75" lazy_static = "1.4.0" rquickjs = { git = "https://github.com/DelSkayn/rquickjs", rev = "343b21b742d3bb052710dc53144b79dc61bb592d", features = ["array-buffer", "macro"] } -[[bin]] -name = "aici_jsctrl" -path = "src/jsctrl.rs" +[lib] +crate-type = ["cdylib"] [build-dependencies] glob = "0.3.1" diff --git a/controllers/jsctrl/src/jsctrl.rs b/controllers/jsctrl/src/lib.rs similarity index 88% rename from controllers/jsctrl/src/jsctrl.rs rename to controllers/jsctrl/src/lib.rs index 63dea08d..6a017e0a 100644 --- a/controllers/jsctrl/src/jsctrl.rs +++ b/controllers/jsctrl/src/lib.rs @@ -1,21 +1,19 @@ -use std::sync::Mutex; - use aici_abi::{ - aici_stop, host_trie, + aici_stop, export, recognizer::{AnythingGoes, StackRecognizer}, - SimpleVob, + tokenizer, toktrie::{Recognizer, SpecialToken, TokTrie}, - AiciCtrl, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult, TokenId, - VariableStorage, + AiciCtrl, ExportedProgram, Guest, InitPromptArg, InitPromptResult, MidProcessArg, + MidProcessResult, Program, SeqId, SimpleVob, Splice, TokenId, }; use rquickjs::{ class::Trace, function::IntoArgs, ArrayBuffer, Context, Ctx, FromJs, Function, IntoAtom, IntoJs, Module, Object, Result, Runtime, TypedArray, Value, }; +use std::sync::Mutex; struct ModuleState { trie: TokTrie, - vars: VariableStorage, mid_process_result: Option, } @@ -23,8 +21,7 @@ unsafe impl Send for ModuleState {} lazy_static::lazy_static! { static ref GLOBAL_STATE: Mutex = Mutex::new(ModuleState { - trie: host_trie(), - vars: VariableStorage::new(), + trie: TokTrie::from_bytes(&tokenizer::token_trie_bytes()), mid_process_result: None, }); } @@ -79,19 +76,7 @@ impl<'js> CtxExt<'js> for Ctx<'js> { fn error_to_string(&self, e: rquickjs::Error) -> String { match e { rquickjs::Error::Exception => self.error_value_to_string(self.catch()), - _ => { - // let stack = match self.eval("new Error().stack") { - // Ok(v) => v, - // Err(e) => { - // format!("Error getting stack: {e}") - // } - // }; - // let exn = rquickjs::Exception::from_message(self.clone(), &format!("{e}")).unwrap(); - // let _ = exn.throw(); - // self.error_to_string(rquickjs::Error::Exception) - // format!("{e}\n{}", exn.stack().unwrap_or("No stack".to_string())) - format!("{e}") - } + _ => format!("{e}"), } } @@ -252,20 +237,21 @@ mod aici_mod { pub use super::{Constraint, TokenSet}; use super::GLOBAL_STATE; + use aici_abi::{ - aici_stop, cfg::CfgParser, get_config, rx::RecRx, substring::SubStrMatcher, - toktrie::SpecialToken, Branch, MidProcessResult, Splice, TokenId, + aici_stop, cfg::CfgParser, runtime, rx::RecRx, substring::SubStrMatcher, tokenizer, + toktrie::SpecialToken, Branch, MidProcessResult, SeqId, Splice, TokenId, }; use rquickjs::{Ctx, Exception, Object, Result, Value}; #[rquickjs::function] - pub fn selfSeqId() -> u32 { - aici_abi::self_seq_id().0 + pub fn selfSeqId() -> SeqId { + runtime::sequence_id() } #[rquickjs::function] pub fn tokenize(text: Buffer) -> Vec { - aici_abi::tokenize_bytes(&text.0) + tokenizer::tokenize_bytes(&text.0) } #[rquickjs::function] @@ -290,37 +276,23 @@ mod aici_mod { trie.token_dbg(token) } - #[rquickjs::function] - pub fn tokensRepr(tokens: Vec) -> String { - let trie = &mut GLOBAL_STATE.lock().unwrap().trie; - trie.tokens_dbg(&tokens) - } - #[rquickjs::function] pub fn getVar(name: String) -> Option { let name = name.as_str(); - let v = GLOBAL_STATE.lock().unwrap().vars.get(name); + let v = aici_abi::runtime_storage::get(name); v.map(Buffer) } #[rquickjs::function] pub fn setVar(name: String, value: Buffer) { let name = name.as_str(); - let vars = &GLOBAL_STATE.lock().unwrap().vars; - vars.set(name, value.0); + aici_abi::runtime_storage::set(name, &value.0); } #[rquickjs::function] pub fn appendVar(name: String, value: Buffer) { let name = name.as_str(); - let vars = &GLOBAL_STATE.lock().unwrap().vars; - vars.append(name, value.0); - } - - #[rquickjs::function] - pub fn getConfig(name: String) -> i32 { - let name = name.as_str(); - get_config(name) + aici_abi::runtime_storage::append(name, &value.0); } #[rquickjs::function] @@ -333,7 +305,7 @@ mod aici_mod { let sample_mask: Option = b.get2("sampleMask"); let splices: Vec = b.get2("splices"); Branch { - sample_mask: sample_mask.map(|ts| ts.inner), + sample_mask: sample_mask.map(|ts| ts.inner.into()), temperature: None, splices: splices .into_iter() @@ -438,8 +410,6 @@ mod aici_mod { } } -fn main() {} - trait PyConstraint { fn eos_allowed(&mut self) -> bool; fn eos_forced(&mut self) -> bool; @@ -483,9 +453,7 @@ fn _print(msg: String) { } impl Runner { - pub fn new(arg: Vec) -> Self { - let source = String::from_utf8(arg).unwrap(); - + pub fn new(source: String) -> Self { let rt = Runtime::new().unwrap(); let s = Self { context: Context::full(&rt).unwrap(), @@ -556,7 +524,7 @@ impl AiciCtrl for Runner { fn mid_process(&mut self, arg: MidProcessArg) -> MidProcessResult { self.with_cb("mid_process", |ctx| { let cb: Function = ctx.eval2("globalThis._aici_cb.mid_process"); - let fg: Vec = arg.fork_group.iter().map(|v| v.0.clone()).collect(); + let fg: Vec = arg.fork_group.iter().map(|v| *v as u32).collect(); let _: Value = cb.call2((arg.backtrack, &arg.tokens, &fg)); () }); @@ -569,8 +537,14 @@ impl AiciCtrl for Runner { } } -fn runner_from_env() -> Runner { - Runner::new(aici_abi::arg_bytes()) +impl Program for Runner { + fn new(arg: String) -> Self { + Runner::new(arg) + } +} + +impl Guest for Runner { + type Runner = ExportedProgram; } -aici_abi::aici_expose_all!(Runner, runner_from_env()); +export!(Runner); diff --git a/controllers/llguidance_ctrl/.cargo/config.toml b/controllers/llguidance_ctrl/.cargo/config.toml index e0b0d22a..774e91b1 100644 --- a/controllers/llguidance_ctrl/.cargo/config.toml +++ b/controllers/llguidance_ctrl/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasi" +target = "wasm32-wasip2" [profile.dev] strip = "debuginfo" diff --git a/controllers/pyctrl/.cargo/config.toml b/controllers/pyctrl/.cargo/config.toml index e0b0d22a..774e91b1 100644 --- a/controllers/pyctrl/.cargo/config.toml +++ b/controllers/pyctrl/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasi" +target = "wasm32-wasip2" [profile.dev] strip = "debuginfo" diff --git a/controllers/pyctrl/Cargo.toml b/controllers/pyctrl/Cargo.toml index c7bca933..5788cae3 100644 --- a/controllers/pyctrl/Cargo.toml +++ b/controllers/pyctrl/Cargo.toml @@ -15,9 +15,8 @@ num-traits = "0.2.17" crossbeam-utils = "0.8.16" once_cell = "1.18.0" -[[bin]] -name = "aici_pyctrl" -path = "src/pyctrl.rs" +[lib] +crate-type = ["cdylib"] [build-dependencies] glob = "0.3.1" diff --git a/controllers/pyctrl/src/pyctrl.rs b/controllers/pyctrl/src/lib.rs similarity index 91% rename from controllers/pyctrl/src/pyctrl.rs rename to controllers/pyctrl/src/lib.rs index 7da07019..c99e0ac8 100644 --- a/controllers/pyctrl/src/pyctrl.rs +++ b/controllers/pyctrl/src/lib.rs @@ -1,8 +1,8 @@ use aici_abi::{ - aici_stop, host_trie, + aici_stop, export, tokenizer, toktrie::{Recognizer, SpecialToken, TokTrie}, - AiciCtrl, Branch, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult, SimpleVob, - Splice, TokenId, VariableStorage, + AiciCtrl, Branch, ExportedProgram, Guest, InitPromptArg, InitPromptResult, MidProcessArg, + MidProcessResult, Program, SimpleVob, Splice, TokenId, }; use anyhow::Result; use lazy_static::lazy_static; @@ -20,7 +20,6 @@ use std::{ struct ModuleState { cb_obj: Option, trie: TokTrie, - vars: VariableStorage, } unsafe impl Send for ModuleState {} @@ -28,8 +27,7 @@ unsafe impl Send for ModuleState {} lazy_static! { static ref GLOBAL_STATE: Mutex = Mutex::new(ModuleState { cb_obj: None, - trie: host_trie(), - vars: VariableStorage::new(), + trie: TokTrie::from_bytes(&tokenizer::token_trie_bytes()), // tokens: vec![], // bytes: vec![], }); @@ -50,8 +48,10 @@ mod _aici { cfg::CfgParser, dlex::{self, DynamicLexerRec}, recognizer::{AnythingGoes, StackRecognizer}, + runtime, rx::RecRx, substring::SubStrMatcher, + tokenizer, toktrie::SpecialToken, SimpleVob, TokenId, }; @@ -77,8 +77,8 @@ mod _aici { } #[pyfunction] - fn self_seq_id() -> u32 { - aici_abi::self_seq_id().0 + fn self_seq_id() -> runtime::SeqId { + runtime::sequence_id() } #[pyfunction] @@ -88,13 +88,13 @@ mod _aici { #[pyfunction] fn tokenize(text: ArgStrOrBytesLike, vm: &VirtualMachine) -> PyResult { - let tokens = aici_abi::tokenize_bytes(&text.borrow_bytes()); + let tokens = tokenizer::tokenize_bytes(&text.borrow_bytes()); Ok(vm.new_int_list(&tokens).into()) } #[pyfunction] fn detokenize(tokens: PyObjectRef, vm: &VirtualMachine) -> Vec { - let tokens = vm.to_u32_list(tokens); + let tokens = vm.to_list(tokens, |v| vm.to_i32(v) as u32); let trie = &mut GLOBAL_STATE.lock().unwrap().trie; let bytes = tokens .iter() @@ -103,13 +103,6 @@ mod _aici { bytes } - #[pyfunction] - fn tokens_repr(tokens: PyObjectRef, vm: &VirtualMachine) -> String { - let tokens = vm.to_u32_list(tokens); - let trie = &mut GLOBAL_STATE.lock().unwrap().trie; - trie.tokens_dbg(&tokens) - } - #[pyfunction] fn token_repr(token: u32) -> String { let trie = &mut GLOBAL_STATE.lock().unwrap().trie; @@ -119,22 +112,20 @@ mod _aici { #[pyfunction] fn get_var(name: PyStrRef, _vm: &VirtualMachine) -> Option> { let name = name.as_str(); - let v = GLOBAL_STATE.lock().unwrap().vars.get(name); + let v = aici_abi::runtime_storage::get(name); v } #[pyfunction] fn set_var(name: PyStrRef, value: ArgStrOrBytesLike, _vm: &VirtualMachine) { let name = name.as_str(); - let vars = &GLOBAL_STATE.lock().unwrap().vars; - vars.set(name, (&value.borrow_bytes()).to_vec()); + aici_abi::runtime_storage::set(name, &value.borrow_bytes()); } #[pyfunction] fn append_var(name: PyStrRef, value: ArgStrOrBytesLike, _vm: &VirtualMachine) { let name = name.as_str(); - let vars = &GLOBAL_STATE.lock().unwrap().vars; - vars.append(name, (&value.borrow_bytes()).to_vec()); + aici_abi::runtime_storage::append(name, &value.borrow_bytes()); } #[pyfunction] @@ -146,7 +137,7 @@ mod _aici { #[pyfunction] fn get_config(name: PyStrRef) -> PyResult { let name = name.as_str(); - let v = aici_abi::get_config(name); + let v = runtime::get_config(name); Ok(v) } @@ -249,7 +240,7 @@ mod _aici { #[pyfunction(name = "CfgConstraint")] fn cfg_constraint(cfg: PyStrRef, vm: &VirtualMachine) -> PyResult { match CfgParser::from_yacc(cfg.as_str()) { - Ok(cfg) => Ok(Constraint::new(cfg)), + Ok(cfg) => Ok(Constraint(Mutex::new(Box::new(cfg)))), Err(e) => Err(vm.new_runtime_error(format!("{}", e))), } } @@ -257,14 +248,14 @@ mod _aici { #[pyfunction(name = "SubStrConstraint")] fn substr_constraint(templ: PyStrRef, end_str: PyStrRef) -> PyResult { let rx = SubStrMatcher::new(templ.as_str(), end_str.as_str()).to_stack_recognizer(); - Ok(Constraint::new(rx)) + Ok(Constraint(Mutex::new(Box::new(rx)))) } impl Constructor for Constraint { type Args = FuncArgs; fn py_new(cls: PyTypeRef, _arg: Self::Args, vm: &VirtualMachine) -> PyResult { let anything = StackRecognizer::from(AnythingGoes {}); - Constraint::new(anything) + Constraint(Mutex::new(Box::new(anything))) .into_ref_with_type(vm, cls) .map(Into::into) } @@ -361,33 +352,19 @@ mod _aici { fn _main() -> Result<()> { let source = std::fs::read_to_string("samples/test.py").unwrap(); - let mut runner = Runner::new(source.as_bytes().to_vec()); + let mut runner = Runner::new(source); runner.init_prompt(InitPromptArg { prompt: vec![1] }); Ok(()) } -#[no_mangle] -pub extern "C" fn aici_main(p: *mut Runner) { - let runner = unsafe { &mut *p }; - let _ = runner; - // runner.init(InitPromptArg { - // prompt: vec![1, 2, 3], - // }); -} - -fn main() { - _main().unwrap(); -} - pub struct Runner { interpreter: rustpython_vm::Interpreter, } impl Runner { - pub fn new(arg: Vec) -> Self { - let source = String::from_utf8(arg).unwrap(); + pub fn new(source: String) -> Self { let interpreter = rustpython_vm::Interpreter::with_init(Default::default(), |vm| { vm.add_native_module( "pyaici.server_native".to_owned(), @@ -618,7 +595,7 @@ impl AiciCtrl for Runner { fn mid_process(&mut self, arg: MidProcessArg) -> MidProcessResult { let obj = get_cb_obj(); self.interpreter.enter(|vm| { - let fork_group = vm.new_int_list(&arg.fork_group.iter().map(|v| v.0.clone()).collect()); + let fork_group = vm.new_int_list(&arg.fork_group.iter().map(|v| *v as u64).collect()); let tokens = vm.new_int_list(&arg.tokens); let bt = vm.ctx.new_int(arg.backtrack as i32); let r = vm.catch_exn(vm.call_method( @@ -636,7 +613,7 @@ impl AiciCtrl for Runner { .payload_if_exact::<_aici::TokenSet>(vm) .expect("expecting TokenSet as sample_mask"); let bias = v.0.lock().unwrap(); - Some(bias.clone()) + Some(bias.clone().into()) }; let splices = vm.to_list(vm.attr(&b, "splices"), |s| { let backtrack = vm.u32_attr(&s, "backtrack"); @@ -661,8 +638,14 @@ impl AiciCtrl for Runner { } } -fn runner_from_env() -> Runner { - Runner::new(aici_abi::arg_bytes()) +impl Program for Runner { + fn new(arg: String) -> Self { + Runner::new(arg) + } +} + +impl Guest for Runner { + type Runner = ExportedProgram; } -aici_abi::aici_expose_all!(Runner, runner_from_env()); +export!(Runner); diff --git a/controllers/pyctrl/wasm.sh b/controllers/pyctrl/wasm.sh index 2e5ccc26..cb6dae73 100755 --- a/controllers/pyctrl/wasm.sh +++ b/controllers/pyctrl/wasm.sh @@ -4,7 +4,7 @@ set -x set -e cargo build --release BIN=$(cd ../target; pwd) -cp $BIN/wasm32-wasi/release/aici_pyctrl.wasm $BIN/opt.wasm +cp $BIN/wasm32-wasip2/release/aici_pyctrl.wasm $BIN/opt.wasm ls -l $BIN/opt.wasm if [ "X$1" = "Xbuild" ] ; then exit diff --git a/controllers/uppercase/.cargo/config.toml b/controllers/uppercase/.cargo/config.toml index e0b0d22a..774e91b1 100644 --- a/controllers/uppercase/.cargo/config.toml +++ b/controllers/uppercase/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasi" +target = "wasm32-wasip2" [profile.dev] strip = "debuginfo" diff --git a/controllers/uppercase/README.md b/controllers/uppercase/README.md index 349cbee4..6e15109b 100644 --- a/controllers/uppercase/README.md +++ b/controllers/uppercase/README.md @@ -15,7 +15,7 @@ will build aici_uppercase from /workspaces/aici/uppercase/Cargo.toml Compiling aici_abi v0.1.0 (/workspaces/aici/aici_abi) Compiling aici_uppercase v0.1.0 (/workspaces/aici/uppercase) Finished release [optimized + debuginfo] target(s) in 1.81s -built: /workspaces/aici/target/wasm32-wasi/release/aici_uppercase.wasm, 0.189 MiB +built: /workspaces/aici/target/wasm32-wasip2/release/aici_uppercase.wasm, 0.189 MiB upload module... 193kB -> 675kB id:a4000d9b [DONE] [Response] Here's a tweet: diff --git a/controllers/uppercase/src/main.rs b/controllers/uppercase/src/main.rs index d196f996..fa4999d5 100644 --- a/controllers/uppercase/src/main.rs +++ b/controllers/uppercase/src/main.rs @@ -1,9 +1,5 @@ use aici_abi::{ - host_trie, - recognizer::{FunctionalRecognizer, StackRecognizer}, - tokenize, - toktrie::{SpecialToken, TokTrie}, - AiciCtrl, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult, + export, recognizer::{FunctionalRecognizer, StackRecognizer}, tokenizer, toktrie::{SpecialToken, TokTrie}, AiciCtrl, ExportedProgram, Guest, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult }; // This constraints enforces an upper case letter every 4th byte @@ -36,10 +32,10 @@ pub struct Runner { recognizer: StackRecognizer, } -impl Runner { - pub fn new() -> Self { +impl aici_abi::Program for Runner { + fn new(prompt: String) -> Self { Runner { - toktrie: host_trie(), + toktrie: TokTrie::from_bytes(&tokenizer::token_trie_bytes()), tokens: Vec::new(), recognizer: StackRecognizer::from(QuadUpper {}), } @@ -51,7 +47,7 @@ impl AiciCtrl for Runner { if arg.prompt.len() <= 1 { // in case no prompt was provided, invent some InitPromptResult { - prompt: tokenize("Here's a tweet:\n"), + prompt: tokenizer::tokenize("Here's a tweet:\n"), } } else { InitPromptResult::from_arg(arg) @@ -82,4 +78,8 @@ fn main() { // test code here? } -aici_abi::aici_expose_all!(Runner, Runner::new()); +impl Guest for Runner { + type Runner = ExportedProgram; +} + +export!(Runner); diff --git a/controllers/yesno/.cargo/config.toml b/controllers/yesno/.cargo/config.toml new file mode 100644 index 00000000..774e91b1 --- /dev/null +++ b/controllers/yesno/.cargo/config.toml @@ -0,0 +1,8 @@ +[build] +target = "wasm32-wasip2" + +[profile.dev] +strip = "debuginfo" + +[profile.release] +strip = "debuginfo" diff --git a/controllers/yesno/Cargo.toml b/controllers/yesno/Cargo.toml new file mode 100644 index 00000000..3fdb4ba1 --- /dev/null +++ b/controllers/yesno/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "aici_yesno" +version = "0.1.0" +edition = "2021" + +[package.metadata.component] +package = "component:yesno" + +[package.metadata.component.dependencies] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +aici_abi = { path = "../aici_abi" } + +[lib] +crate-type = ["cdylib"] diff --git a/controllers/aici_abi/src/yesno.rs b/controllers/yesno/src/lib.rs similarity index 60% rename from controllers/aici_abi/src/yesno.rs rename to controllers/yesno/src/lib.rs index 78b574c3..9a4abc7e 100644 --- a/controllers/aici_abi/src/yesno.rs +++ b/controllers/yesno/src/lib.rs @@ -1,4 +1,7 @@ -use aici_abi::{host_trie, tokenize, toktrie::TokTrie, AiciCtrl, MidProcessArg, MidProcessResult, TokenId}; +use aici_abi::{ + export, tokenizer, toktrie::TokTrie, AiciCtrl, ExportedProgram, Guest, MidProcessArg, + MidProcessResult, TokenId, +}; pub struct Runner { toktrie: TokTrie, @@ -7,13 +10,13 @@ pub struct Runner { no: TokenId, } -impl Runner { - pub fn new() -> Self { - let yes = tokenize("Yes")[0]; - let no = tokenize("No")[0]; +impl aici_abi::Program for Runner { + fn new(_arg: String) -> Self { + let yes = tokenizer::tokenize("Yes")[0]; + let no = tokenizer::tokenize("No")[0]; // ignore user-passed arg Runner { - toktrie: host_trie(), + toktrie: TokTrie::from_bytes(&tokenizer::token_trie_bytes()), tokens: Vec::new(), yes, no, @@ -36,8 +39,8 @@ impl AiciCtrl for Runner { } } -fn main() { - // test code here? +impl Guest for Runner { + type Runner = ExportedProgram; } -aici_abi::aici_expose_all!(Runner, Runner::new()); +export!(Runner); diff --git a/py/pyaici/cli.py b/py/pyaici/cli.py index 7c78bcac..3510822e 100644 --- a/py/pyaici/cli.py +++ b/py/pyaici/cli.py @@ -55,7 +55,7 @@ def build_rust(folder: str, features: List[str] = []): bin_file = bins[0]["name"] print(f'will build {bin_file} from {pkg["manifest_path"]}') - triple = "wasm32-wasi" + triple = "wasm32-wasip2" trg_path = (info["target_directory"] + "/" + triple + "/release/" + bin_file + ".wasm") # remove file first, so we're sure it's rebuilt @@ -73,12 +73,27 @@ def build_rust(folder: str, features: List[str] = []): ] + (["--features", ",".join(features)] if features else []), cwd=folder, ) + if r.returncode != 0: + sys.exit(1) + r = subprocess.run( + [ + "wasm-tools", + "component", + "new", + trg_path, + "-o", + component_path, + "--adapt", + reactor_path, + ] + ) if r.returncode != 0: sys.exit(1) bb = open(trg_path, "rb").read() + M = 1024 * 1024 - print(f"built: {trg_path}, {len(bb)/M:.3} MiB") - return rest.upload_module(trg_path) + print(f"built: {component_path}, {len(bb)/M:.3} MiB") + return rest.upload_module(component_path) def run_ctrl( diff --git a/py/tests/conftest.py b/py/tests/conftest.py index a06e123f..d1f50a51 100644 --- a/py/tests/conftest.py +++ b/py/tests/conftest.py @@ -19,7 +19,7 @@ def upload_wasm(): ) if r.returncode != 0: sys.exit(1) - file_path = prj_dir + "/target/wasm32-wasi/release/aici_declctrl.wasm" + file_path = prj_dir + "/target/wasm32-wasip2/release/aici_declctrl.wasm" pyaici.rest.log_level = 0 ast_module = pyaici.rest.upload_module(file_path) diff --git a/rllm/llama-cpp-low/Cargo.toml b/rllm/llama-cpp-low/Cargo.toml index 399ae68a..0edfc102 100644 --- a/rllm/llama-cpp-low/Cargo.toml +++ b/rllm/llama-cpp-low/Cargo.toml @@ -4,14 +4,14 @@ version = "0.0.1" edition = "2021" [dependencies] -anyhow = "1.0.79" +anyhow = "1.0.86" link-cplusplus = "1.0.9" -log = "0.4.20" +log = "0.4.22" num_cpus = "1.16.0" [build-dependencies] -bindgen = "0.69.2" -cmake = "0.1.50" +bindgen = "0.70.1" +cmake = "0.1.51" [features] default = [] diff --git a/rllm/rllm-base/src/engine.rs b/rllm/rllm-base/src/engine.rs index c20f783f..1ec2c344 100644 --- a/rllm/rllm-base/src/engine.rs +++ b/rllm/rllm-base/src/engine.rs @@ -1,6 +1,6 @@ use crate::{ config::{ParallelConfig, RllmConfig, SamplingParams, SchedulerConfig}, - iface::AiciRtIface, + iface::aicirt::AiciRtIface, seq::{ FinishReason, RequestOutput, SchedulingPhase, SeqOutput, Sequence, SequenceGroup, Token, TokenUsage, @@ -11,8 +11,7 @@ use crate::{ }; use aici_abi::{toktrie::TokTrie, Splice}; use aicirt::{ - api::{AiciMidOp, AiciMidProcessReq, ModuleInstId, SequenceResult}, - with_timer, TimerRef, TimerSet, + api::{AiciMidOp, AiciMidProcessReq, ModuleInstId, SequenceResult}, bindings::SeqId, with_timer, TimerRef, TimerSet }; use anyhow::{bail, Error as E, Result}; use hf_hub::{ @@ -343,7 +342,7 @@ impl RllmEngine { fn aici_bias( &mut self, sched_out: &mut SchedulerOutputs, - ) -> Result<(ME::AiciBias, HashMap)> { + ) -> Result<(ME::AiciBias, HashMap)> { let mut seq_id_mapping = HashMap::default(); let vocab_size = self.tok_trie.vocab_size(); if self.aicirt.is_none() { @@ -377,11 +376,11 @@ impl RllmEngine { let mut copy = seq.fork_as(self.seq_mgr.deref(), new_id, sg.max_index + 1); log::debug!("forked: {:?} -> {:?}", seq.seq_id, copy.seq_id); - seq_id_mapping.insert(copy.seq_id.to_num(), seq.seq_id.to_num()); + seq_id_mapping.insert(copy.seq_id, seq.seq_id); sg.max_index += 1; copy.aici_sampling = Some(b.clone()); copy.mid_op = Some(AiciMidOp { - clone_id: Some(seq.seq_id.to_num()), + clone_id: Some(seq.seq_id), clone_idx: Some(idx), ..copy.defl_mid_op() }); @@ -495,7 +494,7 @@ impl RllmEngine { continue; } - let sidx = seq.seq_id.to_num(); + let sidx = seq.seq_id; let sidx = seq_id_mapping.get(&sidx).unwrap_or(&sidx); let mut logits = self.tmodel.get_logits(*sidx); @@ -663,7 +662,7 @@ impl RllmEngine { seq: &mut Sequence, seqs: &'a HashMap>, ) -> Option<&'a T> { - if let Some(r) = seqs.get(&seq.seq_id.to_num()) { + if let Some(r) = seqs.get(&seq.seq_id) { seq.aici_logs.push(r.clone_with(None)); if r.error.len() > 0 { self.scheduler.finish_seq(seq, FinishReason::Failed); diff --git a/rllm/rllm-base/src/exec.rs b/rllm/rllm-base/src/exec.rs index c2c5330f..74d374a6 100644 --- a/rllm/rllm-base/src/exec.rs +++ b/rllm/rllm-base/src/exec.rs @@ -1,6 +1,7 @@ use std::{fmt::Display, sync::Arc}; -use aicirt::TimerRef; +use aicirt::{TimerRef}; +pub use aicirt::bindings::SeqId; use anyhow::Result; use crate::{ @@ -20,21 +21,6 @@ pub trait AiciBias { fn apply(&self, logits: &mut T, seq_id: usize); } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct SeqId(pub usize); - -impl SeqId { - pub fn to_num(&self) -> usize { - self.0 - } -} - -impl Display for SeqId { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - pub trait SequenceManager { fn new_sequence(&self) -> SeqId; fn copy(&self, src: SeqId, dst: SeqId, length: usize); @@ -71,7 +57,7 @@ pub trait ModelExec: Sized { step_no: usize, sched_out: &mut SchedulerOutputs, ) -> Result<()>; - fn get_logits(&self, seq_id: usize) -> Self::Tensor; + fn get_logits(&self, seq_id: SeqId) -> Self::Tensor; fn finalize_run(&mut self) -> Result<()>; fn empty_bias(&self, vocab_size: usize) -> Self::AiciBias; diff --git a/rllm/rllm-base/src/iface/aici.rs b/rllm/rllm-base/src/iface/aici.rs new file mode 100644 index 00000000..e69de29b diff --git a/rllm/rllm-base/src/iface.rs b/rllm/rllm-base/src/iface/aicirt.rs similarity index 99% rename from rllm/rllm-base/src/iface.rs rename to rllm/rllm-base/src/iface/aicirt.rs index d53944a0..e38780f4 100644 --- a/rllm/rllm-base/src/iface.rs +++ b/rllm/rllm-base/src/iface/aicirt.rs @@ -1,4 +1,3 @@ -use crate::HashMap; use aici_abi::{ bytes::{limit_bytes, limit_str}, toktrie::TokTrie, @@ -12,7 +11,7 @@ use aicirt::{ futexshm::ClientChannel, msgchannel::MessageChannel, shm::{Shm, Unlink}, - user_error, + user_error, HashMap, }; use anyhow::Result; use futures::future::select_all; diff --git a/rllm/rllm-base/src/iface/mod.rs b/rllm/rllm-base/src/iface/mod.rs new file mode 100644 index 00000000..5e41a3d9 --- /dev/null +++ b/rllm/rllm-base/src/iface/mod.rs @@ -0,0 +1 @@ +pub mod aicirt; diff --git a/rllm/rllm-base/src/scheduler.rs b/rllm/rllm-base/src/scheduler.rs index c3338b86..ad04ca09 100644 --- a/rllm/rllm-base/src/scheduler.rs +++ b/rllm/rllm-base/src/scheduler.rs @@ -4,6 +4,7 @@ use crate::{ util::limit_str, HashMap, ModelExec, SequenceManager, TBlockSpaceManager, }; +use aici_abi::SeqId; use aicirt::api::SequenceResult; use std::{ cell::RefCell, @@ -97,7 +98,7 @@ pub struct Scheduler { pub(crate) config: Arc>, prompt_limit: usize, pub(crate) block_manager: ME::BlockSpaceManager, - freed_seq_ids: RefCell>, + freed_seq_ids: RefCell>, seq_mgr: Arc, queues: Mutex>>, @@ -168,7 +169,7 @@ impl Scheduler { } } - pub(crate) fn get_freed_seq_ids(&self) -> Vec { + pub(crate) fn get_freed_seq_ids(&self) -> Vec { self.freed_seq_ids.borrow_mut().drain(..).collect() } @@ -453,7 +454,7 @@ impl Scheduler { ))) } seq.sched_phase = SchedulingPhase::Finished(reason); - self.freed_seq_ids.borrow_mut().push(seq.seq_id.to_num()); + self.freed_seq_ids.borrow_mut().push(seq.seq_id); self.seq_mgr.delete(seq.seq_id); } diff --git a/rllm/rllm-base/src/seq.rs b/rllm/rllm-base/src/seq.rs index 96f9da61..0d79a05c 100644 --- a/rllm/rllm-base/src/seq.rs +++ b/rllm/rllm-base/src/seq.rs @@ -72,7 +72,7 @@ pub struct Sequence { impl Debug for Sequence { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Sequence") - .field("seq_id", &self.seq_id.to_num()) + .field("seq_id", &self.seq_id) .field("sched_phase", &self.sched_phase) .field("kv_computed", &self.num_kv_computed) .field("aici_sampling", &self.aici_sampling) @@ -233,7 +233,7 @@ impl Sequence { self.output_ptr = self.tokens.len(); let new_text = String::from_utf8_lossy(&buf).to_string(); SeqOutput { - seq_id: self.seq_id.to_num(), + seq_id: self.seq_id, index: self.index, new_output_tokens, new_text, @@ -330,7 +330,7 @@ impl SequenceGroup { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SeqOutput { - pub seq_id: usize, + pub seq_id: SeqId, pub index: usize, // within the sequence group pub new_output_tokens: Vec, pub new_text: String, diff --git a/rllm/rllm-base/src/server/mod.rs b/rllm/rllm-base/src/server/mod.rs index 7c207651..4b0e04a0 100644 --- a/rllm/rllm-base/src/server/mod.rs +++ b/rllm/rllm-base/src/server/mod.rs @@ -1,6 +1,6 @@ use crate::{ config::{ModelMeta, SamplingParams}, - iface::{kill_self, AiciRtIface, AsyncCmdChannel}, + iface::aicirt::{kill_self, AiciRtIface, AsyncCmdChannel}, seq::RequestOutput, util::apply_settings, AddRequest, HashMap, LoaderArgs, ModelExec, RllmEngine, @@ -642,7 +642,7 @@ pub async fn server_main( None => format!("/aici-{}-", args.port), }; - let rt_args = crate::iface::Args { + let rt_args = crate::iface::aicirt::Args { aicirt, tokenizer: loader_args.tokenizer.clone(), json_size: args.json_size, diff --git a/rllm/rllm-cuda/src/llm/paged/batch_info.rs b/rllm/rllm-cuda/src/llm/paged/batch_info.rs index 1bd5a700..ce9702ee 100644 --- a/rllm/rllm-cuda/src/llm/paged/batch_info.rs +++ b/rllm/rllm-cuda/src/llm/paged/batch_info.rs @@ -1,6 +1,7 @@ use super::super::{kernels::to_offsets, tmodel::TModel}; use super::cache_engine::CacheEngine; use super::BlockAllocator; +use rllm::SeqId; use rllm::{ config::RllmConfig, seq::SchedulingPhase, util::pad_to_multiple, HashMap, SchedulerOutputs, }; @@ -25,7 +26,7 @@ pub struct BatchInfo { pub logit_idxs: Tensor, // u32, [batch_size] pub max_seqlen_q: usize, pub max_seqlen_k: usize, - pub seq_id_to_idx: HashMap, // seq_id -> index into seqlens_* + pub seq_id_to_idx: HashMap, // seq_id -> index into seqlens_* pub infer_log: Mutex>, pub step_no: usize, @@ -99,7 +100,7 @@ pub struct BatchInfoBuilder { } struct BatchEntry { - seq_id: usize, + seq_id: SeqId, query_pos_token: Vec<(usize, Token)>, kv_slots: Vec, } @@ -137,7 +138,7 @@ impl BatchInfoBuilder { let off = k_len - q_len; self.entries.push(BatchEntry { - seq_id: seq.seq_id.to_num(), + seq_id: seq.seq_id, query_pos_token: (off..off + q_len) .map(|idx| (idx, seq.get_token(idx))) .collect(), @@ -201,7 +202,7 @@ impl BatchInfoBuilder { let mut seqlens_k: Vec = Vec::new(); let mut gather_mapping: Vec = Vec::new(); let mut slot_mapping: Vec = Vec::new(); - let mut seq_id_to_idx: HashMap = HashMap::default(); + let mut seq_id_to_idx: HashMap = HashMap::default(); let mut paged_block_tables: Vec> = Vec::new(); let mut paged_context_lens: Vec = Vec::new(); diff --git a/rllm/rllm-cuda/src/llm/paged/blocks.rs b/rllm/rllm-cuda/src/llm/paged/blocks.rs index ef84492a..294f3c75 100644 --- a/rllm/rllm-cuda/src/llm/paged/blocks.rs +++ b/rllm/rllm-cuda/src/llm/paged/blocks.rs @@ -421,7 +421,7 @@ impl TchSeqMgr { impl SequenceManager for TchSeqMgr { fn new_sequence(&self) -> SeqId { let mut l = self.next.lock().unwrap(); - let r = SeqId(*l); + let r = *l as SeqId; *l = *l + 1; r } diff --git a/rllm/rllm-cuda/src/llm/tmodel.rs b/rllm/rllm-cuda/src/llm/tmodel.rs index e8aba4b2..6e1d350e 100644 --- a/rllm/rllm-cuda/src/llm/tmodel.rs +++ b/rllm/rllm-cuda/src/llm/tmodel.rs @@ -8,7 +8,7 @@ use super::{ use aicirt::{with_timer, TimerRef}; use anyhow::Result; use rand::distributions::Distribution as _; -use rllm::{config::RllmConfig, AiciBias, LogitsProcessor, ModelExec, SchedulerOutputs}; +use rllm::{config::RllmConfig, AiciBias, LogitsProcessor, ModelExec, SchedulerOutputs, SeqId}; use std::{sync::Arc, time::Instant}; use tch::{Device, IndexOp, Tensor}; @@ -114,7 +114,7 @@ impl ModelExec for TModel { Ok(()) } - fn get_logits(&self, seq_id: usize) -> Tensor { + fn get_logits(&self, seq_id: SeqId) -> Tensor { let _no_grad = tch::no_grad_guard(); let idx = self.batch_info.as_ref().unwrap().seq_id_to_idx[&seq_id]; self.logits.as_ref().unwrap().i((idx as i64, ..)) diff --git a/rllm/rllm-llamacpp/src/llamacpp/seqid.rs b/rllm/rllm-llamacpp/src/llamacpp/seqid.rs index 6fd23984..90ed97a9 100644 --- a/rllm/rllm-llamacpp/src/llamacpp/seqid.rs +++ b/rllm/rllm-llamacpp/src/llamacpp/seqid.rs @@ -26,7 +26,7 @@ impl CppSequenceManager { impl SequenceManager for CppSequenceManager { fn new_sequence(&self) -> SeqId { let r = self.model.new_sequence(); - let id = SeqId(r.id() as usize); + let id = r.id() as SeqId; self.seqs.lock().unwrap().insert(id, r); id } diff --git a/rllm/rllm-llamacpp/src/llamacpp/tmodel.rs b/rllm/rllm-llamacpp/src/llamacpp/tmodel.rs index 89472173..6f361dc3 100644 --- a/rllm/rllm-llamacpp/src/llamacpp/tmodel.rs +++ b/rllm/rllm-llamacpp/src/llamacpp/tmodel.rs @@ -5,7 +5,7 @@ use rand::distributions::Distribution as _; use rllm::{ config::{ModelMeta, RllmConfig}, seq::SchedulingPhase, - AiciBias, HashMap, LoaderArgs, LogitsProcessor, ModelExec, SchedulerOutputs, + AiciBias, HashMap, LoaderArgs, LogitsProcessor, ModelExec, SchedulerOutputs, SeqId, }; use std::{sync::Arc, time::Instant}; @@ -20,7 +20,7 @@ pub struct TModel { pub(super) model: cpp::Model, seq_mgr: Arc, batch: cpp::Batch, - seq_id_to_idx: HashMap, + seq_id_to_idx: HashMap, t0: Instant, step_no: usize, } @@ -80,7 +80,7 @@ impl ModelExec for TModel { let logits = idx + 1 == off + q_len; if logits { self.seq_id_to_idx - .insert(seq.seq_id.to_num(), self.batch.len()); + .insert(seq.seq_id, self.batch.len()); } self.seq_mgr.with_cpp(seq.seq_id, |cpp| { cpp.assert_model(&self.model); @@ -101,7 +101,7 @@ impl ModelExec for TModel { Ok(()) } - fn get_logits(&self, seq_id: usize) -> Tensor { + fn get_logits(&self, seq_id: SeqId) -> Tensor { let l = self.model.get_logits(self.seq_id_to_idx[&seq_id]); Tensor::from_slice(l) } diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..ef33a7d3 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2024-08-26" diff --git a/scripts/release.sh b/scripts/release.sh index 73164a43..1140ddc3 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -67,7 +67,7 @@ for f in "$@" ; do BN="$BN $(basename $f)" done -if [ "$SUFF" = "wasm32-wasi" ] ; then +if [ "$SUFF" = "wasm32-wasip2" ] ; then WASM= for B in $BN ; do case $B in @@ -132,7 +132,7 @@ echo >> $T/README.md echo '```' >> $T/README.md echo >> $T/README.md -if [ "$SUFF" = "wasm32-wasi" ] ; then +if [ "$SUFF" = "wasm32-wasip2" ] ; then cat >> $T/README.md <<'EOF' ## Tagging @@ -169,7 +169,7 @@ rm -rf target/dist mkdir -p target/dist echo -n > target/dist/README.md -release aici-controllers "AICI Controllers" "wasm32-wasi" target/wasm32-wasi/release/*.wasm +release aici-controllers "AICI Controllers" "wasm32-wasip2" target/wasm32-wasip2/release/*.wasm release aicirt "AICI Runtime" "$NATIVE" target/release/aicirt if test -z "$SKIP_LLAMA_CPP" ; then diff --git a/scripts/sample-yesno.sh b/scripts/sample-yesno.sh index 5ddc5dea..c7a5d8cf 100755 --- a/scripts/sample-yesno.sh +++ b/scripts/sample-yesno.sh @@ -4,4 +4,4 @@ if [ -z "$PROMPT" ]; then PROMPT="Is coffee any good?" fi set -x -echo "$PROMPT" | ./aici.sh run --build controllers/aici_abi::yesno - +echo "$PROMPT" | ./aici.sh run --build controllers/yesno - diff --git a/scripts/upload-all.sh b/scripts/upload-all.sh index 32b694fb..ed35babb 100755 --- a/scripts/upload-all.sh +++ b/scripts/upload-all.sh @@ -3,7 +3,7 @@ export AICI="$(cd `dirname $0`; pwd)/aici.sh --all-prefixes" case "$1" in - *aici-controllers-wasm32-wasi-*.tar.?z) + *aici-controllers-wasm32-wasip2-*.tar.?z) mkdir -p tmp/aici-controllers tar --strip-components=1 -xf "$1" -C tmp/aici-controllers if test -f tmp/aici-controllers/tag.sh ; then @@ -16,7 +16,7 @@ case "$1" in fi ;; *) - echo "Usage: $0 aici-controllers-wasm32-wasi-....tar.[xz|gz]" + echo "Usage: $0 aici-controllers-wasm32-wasip2-....tar.[xz|gz]" exit 1 ;; esac diff --git a/wit/controller.wit b/wit/controller.wit new file mode 100644 index 00000000..e203a2dc --- /dev/null +++ b/wit/controller.wit @@ -0,0 +1,53 @@ + +interface controller { + use tokenizer.{token-id}; + use runtime.{seq-id}; + + // A bitmap of allowable token IDs. + record vocabulary { + data: list, + size: u64, + } + + record init-prompt-arg { + prompt: list, + } + + record init-prompt-result { + prompt: list, + } + + record mid-process-arg { + backtrack: u32, + tokens: list, + sampled: option, + fork-group: list, + } + + record sample-with-bias { + allowed-tokens: vocabulary, + } + + record splice { + when-sampled: list, + backtrack: u32, + ff-tokens: list, + } + + // Branch + record branch { + sample-mask: option, // option + temperature: option, + splices: list, + } + + record mid-process-result { + branches: list, + } + + resource runner { + constructor(args: string); + init-prompt: func(arg: init-prompt-arg) -> init-prompt-result; + mid-process: func(arg: mid-process-arg) -> mid-process-result; + } +} diff --git a/wit/package.wit b/wit/package.wit new file mode 100644 index 00000000..5683e435 --- /dev/null +++ b/wit/package.wit @@ -0,0 +1,10 @@ +package aici:abi; + +world aici { + import tokenizer; + + import runtime; + import runtime-storage; + + export controller; +} diff --git a/wit/runtime-storage.wit b/wit/runtime-storage.wit new file mode 100644 index 00000000..9a6d7541 --- /dev/null +++ b/wit/runtime-storage.wit @@ -0,0 +1,5 @@ +interface runtime-storage { + get: func(name: string) -> option>; + set: func(name: string, value: list); + append: func(name: string, value: list); +} diff --git a/wit/runtime.wit b/wit/runtime.wit new file mode 100644 index 00000000..0008fc88 --- /dev/null +++ b/wit/runtime.wit @@ -0,0 +1,9 @@ +interface runtime { + type seq-id = u64; + + sequence-id: func() -> seq-id; + + get-config: func(key: string) -> s32; + + stop: func(); +} diff --git a/wit/tokenizer.wit b/wit/tokenizer.wit new file mode 100644 index 00000000..8d09d91d --- /dev/null +++ b/wit/tokenizer.wit @@ -0,0 +1,11 @@ +interface tokenizer { + type token-id = u32; + + eos-token: func() -> token-id; + + tokenize: func(text: string) -> list; + + tokenize-bytes: func(text: list) -> list; + + token-trie-bytes: func() -> list; +} From 2563d93fde9277a6f8714f9fc5669ccc9c10112d Mon Sep 17 00:00:00 2001 From: Aaron Friel Date: Sat, 7 Sep 2024 14:14:21 -0700 Subject: [PATCH 2/8] Revert to wasip1 while wasip2 requires nightly --- .devcontainer/Dockerfile-prod-vllm | 2 +- .devcontainer/common.dockerfile | 2 +- .github/workflows/aicirt-release.yml | 2 +- .github/workflows/aicirt.yml | 2 +- README.md | 4 ++-- controllers/aici_abi/.cargo/config.toml | 2 +- controllers/declctrl/.cargo/config.toml | 2 +- controllers/declctrl/wasm.sh | 2 +- controllers/jsctrl/.cargo/config.toml | 2 +- controllers/llguidance_ctrl/.cargo/config.toml | 2 +- controllers/pyctrl/.cargo/config.toml | 2 +- controllers/pyctrl/wasm.sh | 2 +- controllers/uppercase/.cargo/config.toml | 2 +- controllers/uppercase/README.md | 2 +- controllers/yesno/.cargo/config.toml | 2 +- py/pyaici/cli.py | 2 +- py/tests/conftest.py | 2 +- rust-toolchain.toml | 2 -- scripts/release.sh | 6 +++--- scripts/upload-all.sh | 4 ++-- 20 files changed, 23 insertions(+), 25 deletions(-) delete mode 100644 rust-toolchain.toml diff --git a/.devcontainer/Dockerfile-prod-vllm b/.devcontainer/Dockerfile-prod-vllm index a2977f26..e1c648f4 100644 --- a/.devcontainer/Dockerfile-prod-vllm +++ b/.devcontainer/Dockerfile-prod-vllm @@ -2,7 +2,7 @@ FROM rust:1.75.0-bookworm AS aicirt WORKDIR /workspace -RUN rustup target add wasm32-wasip2 +RUN rustup target add wasm32-wasip1 RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - RUN apt-get install -y nodejs diff --git a/.devcontainer/common.dockerfile b/.devcontainer/common.dockerfile index d9269b8e..64f48575 100644 --- a/.devcontainer/common.dockerfile +++ b/.devcontainer/common.dockerfile @@ -31,7 +31,7 @@ ENV RUSTUP_HOME=/usr/local/rustup \ RUN curl https://sh.rustup.rs -sSf | sh -s -- \ -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION -RUN rustup target add wasm32-wasip2 +RUN rustup target add wasm32-wasip1 RUN rustup component add rustfmt # run as root please; note that settings in devcontainer.json are also needed... diff --git a/.github/workflows/aicirt-release.yml b/.github/workflows/aicirt-release.yml index a67fe694..f679d704 100644 --- a/.github/workflows/aicirt-release.yml +++ b/.github/workflows/aicirt-release.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - run: rustup target add wasm32-wasip2 + - run: rustup target add wasm32-wasip1 - uses: hendrikmuhs/ccache-action@v1.2 - uses: Swatinem/rust-cache@v2 with: diff --git a/.github/workflows/aicirt.yml b/.github/workflows/aicirt.yml index f9c44080..242ebbe7 100644 --- a/.github/workflows/aicirt.yml +++ b/.github/workflows/aicirt.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - run: rustup target add wasm32-wasip2 + - run: rustup target add wasm32-wasip1 - uses: hendrikmuhs/ccache-action@v1.2 - uses: Swatinem/rust-cache@v2 with: diff --git a/README.md b/README.md index 3b6625db..94b3b9bb 100644 --- a/README.md +++ b/README.md @@ -80,9 +80,9 @@ Then install **Rust, Rustup and Cargo**, following the instructions provided [he After installation, verify that the `rustup --version` command is accessible by running it from the terminal. If the command isn't recognized, try opening a new terminal session. -Next install wasm32-wasip2 Rust component: +Next install wasm32-wasip1 Rust component: - rustup target add wasm32-wasip2 + rustup target add wasm32-wasip1 If you already had Rust installed, or are getting complaints from Cargo about outdated versions, run: diff --git a/controllers/aici_abi/.cargo/config.toml b/controllers/aici_abi/.cargo/config.toml index 774e91b1..c3fd0010 100644 --- a/controllers/aici_abi/.cargo/config.toml +++ b/controllers/aici_abi/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasip2" +target = "wasm32-wasip1" [profile.dev] strip = "debuginfo" diff --git a/controllers/declctrl/.cargo/config.toml b/controllers/declctrl/.cargo/config.toml index 774e91b1..c3fd0010 100644 --- a/controllers/declctrl/.cargo/config.toml +++ b/controllers/declctrl/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasip2" +target = "wasm32-wasip1" [profile.dev] strip = "debuginfo" diff --git a/controllers/declctrl/wasm.sh b/controllers/declctrl/wasm.sh index 5d7321d0..93352a0a 100755 --- a/controllers/declctrl/wasm.sh +++ b/controllers/declctrl/wasm.sh @@ -4,7 +4,7 @@ set -x set -e cargo build --release BIN=$(cd ../target; pwd) -cp $BIN/wasm32-wasip2/release/aici_declctrl.wasm $BIN/opt.wasm +cp $BIN/wasm32-wasip1/release/aici_declctrl.wasm $BIN/opt.wasm ls -l $BIN/opt.wasm if [ "X$1" = "Xbuild" ] ; then exit diff --git a/controllers/jsctrl/.cargo/config.toml b/controllers/jsctrl/.cargo/config.toml index 774e91b1..c3fd0010 100644 --- a/controllers/jsctrl/.cargo/config.toml +++ b/controllers/jsctrl/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasip2" +target = "wasm32-wasip1" [profile.dev] strip = "debuginfo" diff --git a/controllers/llguidance_ctrl/.cargo/config.toml b/controllers/llguidance_ctrl/.cargo/config.toml index 774e91b1..c3fd0010 100644 --- a/controllers/llguidance_ctrl/.cargo/config.toml +++ b/controllers/llguidance_ctrl/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasip2" +target = "wasm32-wasip1" [profile.dev] strip = "debuginfo" diff --git a/controllers/pyctrl/.cargo/config.toml b/controllers/pyctrl/.cargo/config.toml index 774e91b1..c3fd0010 100644 --- a/controllers/pyctrl/.cargo/config.toml +++ b/controllers/pyctrl/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasip2" +target = "wasm32-wasip1" [profile.dev] strip = "debuginfo" diff --git a/controllers/pyctrl/wasm.sh b/controllers/pyctrl/wasm.sh index cb6dae73..b5a5f26e 100755 --- a/controllers/pyctrl/wasm.sh +++ b/controllers/pyctrl/wasm.sh @@ -4,7 +4,7 @@ set -x set -e cargo build --release BIN=$(cd ../target; pwd) -cp $BIN/wasm32-wasip2/release/aici_pyctrl.wasm $BIN/opt.wasm +cp $BIN/wasm32-wasip1/release/aici_pyctrl.wasm $BIN/opt.wasm ls -l $BIN/opt.wasm if [ "X$1" = "Xbuild" ] ; then exit diff --git a/controllers/uppercase/.cargo/config.toml b/controllers/uppercase/.cargo/config.toml index 774e91b1..c3fd0010 100644 --- a/controllers/uppercase/.cargo/config.toml +++ b/controllers/uppercase/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasip2" +target = "wasm32-wasip1" [profile.dev] strip = "debuginfo" diff --git a/controllers/uppercase/README.md b/controllers/uppercase/README.md index 6e15109b..a9379d07 100644 --- a/controllers/uppercase/README.md +++ b/controllers/uppercase/README.md @@ -15,7 +15,7 @@ will build aici_uppercase from /workspaces/aici/uppercase/Cargo.toml Compiling aici_abi v0.1.0 (/workspaces/aici/aici_abi) Compiling aici_uppercase v0.1.0 (/workspaces/aici/uppercase) Finished release [optimized + debuginfo] target(s) in 1.81s -built: /workspaces/aici/target/wasm32-wasip2/release/aici_uppercase.wasm, 0.189 MiB +built: /workspaces/aici/target/wasm32-wasip1/release/aici_uppercase.wasm, 0.189 MiB upload module... 193kB -> 675kB id:a4000d9b [DONE] [Response] Here's a tweet: diff --git a/controllers/yesno/.cargo/config.toml b/controllers/yesno/.cargo/config.toml index 774e91b1..c3fd0010 100644 --- a/controllers/yesno/.cargo/config.toml +++ b/controllers/yesno/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -target = "wasm32-wasip2" +target = "wasm32-wasip1" [profile.dev] strip = "debuginfo" diff --git a/py/pyaici/cli.py b/py/pyaici/cli.py index 3510822e..27d0f389 100644 --- a/py/pyaici/cli.py +++ b/py/pyaici/cli.py @@ -55,7 +55,7 @@ def build_rust(folder: str, features: List[str] = []): bin_file = bins[0]["name"] print(f'will build {bin_file} from {pkg["manifest_path"]}') - triple = "wasm32-wasip2" + triple = "wasm32-wasip1" trg_path = (info["target_directory"] + "/" + triple + "/release/" + bin_file + ".wasm") # remove file first, so we're sure it's rebuilt diff --git a/py/tests/conftest.py b/py/tests/conftest.py index d1f50a51..37c8be67 100644 --- a/py/tests/conftest.py +++ b/py/tests/conftest.py @@ -19,7 +19,7 @@ def upload_wasm(): ) if r.returncode != 0: sys.exit(1) - file_path = prj_dir + "/target/wasm32-wasip2/release/aici_declctrl.wasm" + file_path = prj_dir + "/target/wasm32-wasip1/release/aici_declctrl.wasm" pyaici.rest.log_level = 0 ast_module = pyaici.rest.upload_module(file_path) diff --git a/rust-toolchain.toml b/rust-toolchain.toml deleted file mode 100644 index ef33a7d3..00000000 --- a/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "nightly-2024-08-26" diff --git a/scripts/release.sh b/scripts/release.sh index 1140ddc3..6eee8d99 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -67,7 +67,7 @@ for f in "$@" ; do BN="$BN $(basename $f)" done -if [ "$SUFF" = "wasm32-wasip2" ] ; then +if [ "$SUFF" = "wasm32-wasip1" ] ; then WASM= for B in $BN ; do case $B in @@ -132,7 +132,7 @@ echo >> $T/README.md echo '```' >> $T/README.md echo >> $T/README.md -if [ "$SUFF" = "wasm32-wasip2" ] ; then +if [ "$SUFF" = "wasm32-wasip1" ] ; then cat >> $T/README.md <<'EOF' ## Tagging @@ -169,7 +169,7 @@ rm -rf target/dist mkdir -p target/dist echo -n > target/dist/README.md -release aici-controllers "AICI Controllers" "wasm32-wasip2" target/wasm32-wasip2/release/*.wasm +release aici-controllers "AICI Controllers" "wasm32-wasip1" target/wasm32-wasip1/release/*.wasm release aicirt "AICI Runtime" "$NATIVE" target/release/aicirt if test -z "$SKIP_LLAMA_CPP" ; then diff --git a/scripts/upload-all.sh b/scripts/upload-all.sh index ed35babb..6f53172d 100755 --- a/scripts/upload-all.sh +++ b/scripts/upload-all.sh @@ -3,7 +3,7 @@ export AICI="$(cd `dirname $0`; pwd)/aici.sh --all-prefixes" case "$1" in - *aici-controllers-wasm32-wasip2-*.tar.?z) + *aici-controllers-wasm32-wasip1-*.tar.?z) mkdir -p tmp/aici-controllers tar --strip-components=1 -xf "$1" -C tmp/aici-controllers if test -f tmp/aici-controllers/tag.sh ; then @@ -16,7 +16,7 @@ case "$1" in fi ;; *) - echo "Usage: $0 aici-controllers-wasm32-wasip2-....tar.[xz|gz]" + echo "Usage: $0 aici-controllers-wasm32-wasip1-....tar.[xz|gz]" exit 1 ;; esac From 770cdcd197bc126dde7431758f01e9f2ba8b44c8 Mon Sep 17 00:00:00 2001 From: Aaron Friel Date: Mon, 9 Sep 2024 03:15:50 +0000 Subject: [PATCH 3/8] complete migration to components --- .devcontainer/Dockerfile-cuda | 3 +- .devcontainer/Dockerfile-prod-vllm | 2 +- .devcontainer/Dockerfile-vllm | 5 +- .devcontainer/common.dockerfile | 2 +- .devcontainer/install-perf.sh | 10 ++ Cargo.lock | 2 + aicirt/src/hostimpl.rs | 128 +++++------------- aicirt/src/lib.rs | 1 + aicirt/src/main.rs | 15 +- aicirt/src/moduleinstance.rs | 18 +-- aicirt/src/wasi/clock.rs | 49 +++++++ aicirt/src/wasi/mod.rs | 1 + aicirt/src/worker.rs | 17 +-- controllers/aici_abi/Cargo.toml | 2 +- controllers/aici_abi/src/cfg.rs | 5 +- controllers/aici_abi/src/lib.rs | 105 +------------- controllers/aici_wasm_guest/Cargo.toml | 1 + controllers/aici_wasm_guest/src/lib.rs | 105 ++++++++++++++ controllers/declctrl/src/lib.rs | 9 +- controllers/guidance_ctrl/src/earley_bench.rs | 4 +- controllers/jsctrl/src/lib.rs | 2 +- controllers/llguidance_ctrl/src/gctrl.rs | 65 +++++++-- controllers/uppercase/src/main.rs | 2 +- rllm/rllm-base/Cargo.toml | 1 + rllm/rllm-base/src/engine.rs | 2 +- rllm/rllm-base/src/exec.rs | 4 +- rllm/rllm-base/src/seq.rs | 6 +- rllm/rllm-llamacpp/Cargo.toml | 2 +- 28 files changed, 305 insertions(+), 263 deletions(-) create mode 100755 .devcontainer/install-perf.sh create mode 100644 aicirt/src/wasi/clock.rs create mode 100644 aicirt/src/wasi/mod.rs diff --git a/.devcontainer/Dockerfile-cuda b/.devcontainer/Dockerfile-cuda index 39813e4f..3c4ed119 100644 --- a/.devcontainer/Dockerfile-cuda +++ b/.devcontainer/Dockerfile-cuda @@ -11,7 +11,8 @@ RUN pip install torch==2.1.0 nvidia-cuda-runtime RUN ln -s /usr/local/lib/python3.10/dist-packages/nvidia/cuda_runtime/lib/libcudart.so{.12,} # perf tool -RUN apt-get install -y linux-tools-`uname -r` +COPY install-perf.sh /tmp/install-perf.sh +RUN apt-get update && /tmp/install-perf.sh RUN source /usr/local/nvm/nvm.sh && npm install -g yarn diff --git a/.devcontainer/Dockerfile-prod-vllm b/.devcontainer/Dockerfile-prod-vllm index e1c648f4..cfe92838 100644 --- a/.devcontainer/Dockerfile-prod-vllm +++ b/.devcontainer/Dockerfile-prod-vllm @@ -1,4 +1,4 @@ -FROM rust:1.75.0-bookworm AS aicirt +FROM rust:1.81.0-bookworm AS aicirt WORKDIR /workspace diff --git a/.devcontainer/Dockerfile-vllm b/.devcontainer/Dockerfile-vllm index 49c9389f..81432548 100644 --- a/.devcontainer/Dockerfile-vllm +++ b/.devcontainer/Dockerfile-vllm @@ -13,7 +13,7 @@ RUN pip install -r /tmp/requirements.txt # Uninstall the transformer engine that comes with the base image. # Otherwise it will cause error when importing vLLM (LLAVA models). -RUN pip uninstall -y transformer_engine +RUN pip uninstall -y transformer_engine # crashes docker? # RUN pip install -v -U git+https://github.com/facebookresearch/xformers.git@main#egg=xformers @@ -28,6 +28,7 @@ RUN pip uninstall -y transformer_engine RUN ln -s /usr/local/lib/python3.10/dist-packages/nvidia/cuda_runtime/lib/libcudart.so{.12,} # perf tool -RUN apt-get install -y linux-tools-`uname -r` +COPY install-perf.sh /tmp/install-perf.sh +RUN apt-get update && /tmp/install-perf.sh RUN source /usr/local/nvm/nvm.sh && npm install -g yarn diff --git a/.devcontainer/common.dockerfile b/.devcontainer/common.dockerfile index 64f48575..8fc1046f 100644 --- a/.devcontainer/common.dockerfile +++ b/.devcontainer/common.dockerfile @@ -27,7 +27,7 @@ RUN cd /tmp && \ ENV RUSTUP_HOME=/usr/local/rustup \ CARGO_HOME=/usr/local/cargo \ PATH=/usr/local/cargo/bin:$PATH \ - RUST_VERSION=1.75.0 + RUST_VERSION=1.81.0 RUN curl https://sh.rustup.rs -sSf | sh -s -- \ -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION diff --git a/.devcontainer/install-perf.sh b/.devcontainer/install-perf.sh new file mode 100755 index 00000000..288cc294 --- /dev/null +++ b/.devcontainer/install-perf.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -euo pipefail + +UNAME_R=$(uname -r) +if [[ $UNAME_R == *"-microsoft-standard-WSL2" ]]; then + apt-get install -y linux-tools-generic +else + apt-get install -y "linux-tools-$(uname -r)" +fi diff --git a/Cargo.lock b/Cargo.lock index 2e345bca..d7da0cca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,6 +343,7 @@ name = "aici_wasm_guest" version = "0.1.0" dependencies = [ "serde", + "toktrie", "wit-bindgen", ] @@ -3298,6 +3299,7 @@ dependencies = [ "serde_json", "tokenizers", "tokio", + "toktrie", "uuid", ] diff --git a/aicirt/src/hostimpl.rs b/aicirt/src/hostimpl.rs index 4e6a6497..773bf60b 100644 --- a/aicirt/src/hostimpl.rs +++ b/aicirt/src/hostimpl.rs @@ -3,17 +3,13 @@ use crate::{ worker::{GroupCmd, GroupHandle, GroupResp}, }; use aici_abi::{ - bytes::limit_str, toktrie::{TokRxInfo, TokTrie}, StorageCmd, }; +use aicirt::wasi::clock::BoundedResolutionClock; use aicirt::{api::InferenceCapabilities, bindings::SeqId, user_error}; use anyhow::{anyhow, Result}; -use std::{ - ops::Deref, - sync::Arc, - time::{Duration, Instant}, -}; +use std::{ops::Deref, sync::Arc, time::Duration}; use tokenizers::Tokenizer; #[derive(Clone)] @@ -39,19 +35,17 @@ type ModuleInstId = crate::api::ModuleInstId; // this is available to functions called from wasm pub struct ModuleData { pub id: ModuleInstId, - log: Vec, + log: wasmtime_wasi::pipe::MemoryOutputPipe, printed_log: usize, pub globals: GlobalInfo, pub group_channel: GroupHandle, pub store_limits: wasmtime::StoreLimits, - pub had_error: bool, pub storage_log: Vec, - pub start_time: Instant, pub wasi_ctx: wasmtime_wasi::WasiCtx, pub resource_table: wasmtime_wasi::ResourceTable, } -const MAXLOG: usize = 64 * 1024; +const MAX_LOG: usize = 64 * 1024; impl ModuleData { pub fn new( @@ -68,82 +62,37 @@ impl ModuleData { .instances(100) .trap_on_grow_failure(true) .build(); + + let wall_clock = + BoundedResolutionClock::new(Duration::from_nanos(limits.timer_resolution_ns)); + let monotonic_clock = wall_clock.clone(); + + let log = wasmtime_wasi::pipe::MemoryOutputPipe::new(MAX_LOG); + let stdout = log.clone(); + let stderr = log.clone(); ModuleData { id, - log: Vec::new(), + log: log, printed_log: 0, globals, group_channel, store_limits, - had_error: false, storage_log: Vec::new(), - start_time: Instant::now(), - wasi_ctx: wasmtime_wasi::WasiCtxBuilder::new().build(), + wasi_ctx: wasmtime_wasi::WasiCtxBuilder::new() + .wall_clock(wall_clock) + .monotonic_clock(monotonic_clock) + .stdout(stdout) + .stderr(stderr) + .build(), resource_table: wasmtime_wasi::ResourceTable::new(), } } - pub fn tokenize(&mut self, s: &str) -> Result> { - let tokens = self.globals.hf_tokenizer.encode(s, false); - match tokens { - Err(e) => Err(anyhow!(e)), - Ok(tokens) => Ok(Vec::from(tokens.get_ids())), - } - } - - pub fn fatal(&mut self, msg: &str) { - log::warn!("{}: fatal error {}", self.id, msg); - let msg = format!("FATAL ERROR: {}\n", msg); - self.write_log(msg.as_bytes()); - self.had_error = true; - // ideally, this should call into the module and cause panic - } - - // pub fn warn(&mut self, msg: &str) { - // log::warn!("{}: {}", self.id, msg); - // let msg = format!("warning: {}\n", msg); - // self.write_log(msg.as_bytes()); - // } - - pub fn write_log(&mut self, bytes: &[u8]) { - self.log.extend_from_slice(bytes); - if self.log.len() > MAXLOG { - let drop = MAXLOG / 4; - if self.had_error { - // normally, we drop prefix, but if "had_error" is set - // we drop the suffix instead to avoid flushing out "FATAL ERROR" message - self.log.truncate(self.log.len() - drop); - } else { - self.printed_log = self.printed_log.saturating_sub(drop); - self.log.drain(0..drop); - } - } - } - pub fn string_log(&mut self) -> String { self.printed_log = 0; - let logs = String::from_utf8_lossy(&self.log).to_string(); - self.log.clear(); + let logs = String::from_utf8_lossy(&self.log.contents()).to_string(); logs } - - pub fn flush_logs(&mut self, name: &str) { - if !log::log_enabled!(log::Level::Debug) { - return; - } - - let data = &self.log[self.printed_log..]; - if data.len() == 0 { - return; - } - - let logs = String::from_utf8_lossy(data).to_string(); - self.printed_log = self.log.len(); - - for line in logs.lines() { - log::debug!("{}:{}> {}", self.id, name, limit_str(line, 512)); - } - } } impl wasmtime_wasi::WasiView for ModuleData { @@ -165,23 +114,6 @@ pub struct GlobalInfo { pub hf_tokenizer: Arc, } -fn check_fatal(caller: &mut wasmtime::Caller<'_, ModuleData>) { - if caller.data().had_error { - fatal_error(caller, "see above") - } -} - -fn fatal_error(caller: &mut wasmtime::Caller<'_, ModuleData>, msg: &str) { - caller.data_mut().fatal(msg); - match caller.get_export("aici_panic") { - Some(wasmtime::Extern::Func(f)) => { - let mut res = Vec::new(); - let _ = f.call(caller, &[], &mut res); - } - _ => {} - } -} - impl abi::runtime::Host for ModuleData { fn sequence_id(&mut self) -> wasmtime::Result { Ok(self.id as SeqId) @@ -258,12 +190,15 @@ impl abi::runtime_storage::Host for ModuleData { } impl ModuleData { - pub fn tokenize_str(&mut self, s: &str) -> Result> { - let tokens = self.globals.hf_tokenizer.encode(s, false); - match tokens { - Err(e) => Err(anyhow!(e)), - Ok(tokens) => Ok(Vec::from(tokens.get_ids())), - } + pub fn tokenize_bytes_greedy(&mut self, s: impl AsRef<[u8]>) -> Result> { + Ok(self.globals.tok_trie.tokenize_with_greedy_fallback(s.as_ref(), |s| { + self.globals + .hf_tokenizer + .encode(s, false) + .expect("tokenizer error") + .get_ids() + .to_vec() + })) } } @@ -273,12 +208,11 @@ impl abi::tokenizer::Host for ModuleData { } fn tokenize(&mut self, s: String) -> wasmtime::Result> { - self.tokenize_str(&s) + self.tokenize_bytes_greedy(s.as_bytes()) } fn tokenize_bytes(&mut self, bytes: Vec) -> wasmtime::Result> { - let s = String::from_utf8_lossy(&bytes); - self.tokenize(&s) + self.tokenize_bytes_greedy(&bytes) } fn token_trie_bytes(&mut self) -> wasmtime::Result> { diff --git a/aicirt/src/lib.rs b/aicirt/src/lib.rs index b1164dbc..6d73ada6 100644 --- a/aicirt/src/lib.rs +++ b/aicirt/src/lib.rs @@ -5,6 +5,7 @@ pub mod futexshm; pub mod msgchannel; pub mod semaphore; pub mod shm; +pub mod wasi; pub use aici_native::*; diff --git a/aicirt/src/main.rs b/aicirt/src/main.rs index db77f29d..91edffae 100644 --- a/aicirt/src/main.rs +++ b/aicirt/src/main.rs @@ -9,7 +9,6 @@ use crate::{ msgchannel::MessageChannel, shm::Shm, worker::{RtMidProcessArg, WorkerForker}, - TimerSet, }; use aici_abi::{ bytes::limit_str, @@ -142,7 +141,7 @@ struct Cli { #[arg(long, default_value = "25")] wasm_max_step_time: u64, - /// How many steps have to timeout before the sequenace is terminated + /// How many steps have to timeout before the sequence is terminated #[arg(long, default_value = "10")] wasm_max_timeout_steps: usize, @@ -210,8 +209,8 @@ fn write_json(filename: &PathBuf, json: &T) -> Result<()> { } impl ModuleRegistry { - pub fn new(wasm_ctx: WasmContext, shm: Rc) -> Result { - let forker = WorkerForker::new(wasm_ctx.clone(), shm); + pub fn new(wasm_ctx: WasmContext) -> Result { + let forker = WorkerForker::new(wasm_ctx.clone()); Ok(Self { forker: Arc::new(Mutex::new(forker)), @@ -1225,9 +1224,9 @@ fn save_tokenizer(cli: &Cli) { } } -fn install_from_cmdline(cli: &Cli, wasm_ctx: WasmContext, shm: Rc) { +fn install_from_cmdline(cli: &Cli, wasm_ctx: WasmContext) { let name = cli.module.as_deref().unwrap(); - let mut reg = ModuleRegistry::new(wasm_ctx, shm).unwrap(); + let mut reg = ModuleRegistry::new(wasm_ctx).unwrap(); let module_id = if name.ends_with(".wasm") { let wasm_bytes = fs::read(name).unwrap(); if let Some(gh) = &cli.gh_module { @@ -1349,7 +1348,7 @@ fn main() -> () { )); if cli.module.is_some() { - install_from_cmdline(&cli, wasm_ctx, shm_alloc.clone()); + install_from_cmdline(&cli, wasm_ctx); return (); } @@ -1362,7 +1361,7 @@ fn main() -> () { set_max_priority(); - let reg = ModuleRegistry::new(wasm_ctx, shm_alloc.clone()).unwrap(); + let reg = ModuleRegistry::new(wasm_ctx).unwrap(); // needs to be done after WorkerForker is spawned setup_bg_worker_pool(); diff --git a/aicirt/src/moduleinstance.rs b/aicirt/src/moduleinstance.rs index 53cd45e9..5515a588 100644 --- a/aicirt/src/moduleinstance.rs +++ b/aicirt/src/moduleinstance.rs @@ -2,20 +2,17 @@ use crate::{ api::ModuleInstId, hostimpl::{AiciLimits, GlobalInfo, ModuleData}, setup_component_linker, - shm::Shm, worker::{GroupHandle, RtMidProcessArg}, TimerSet, UserError, }; use aici_abi::toktrie::TokTrie; use aicirt::{ api::{InferenceCapabilities, SequenceResult}, - bindings::{self, aici::abi::tokenizer::Host, exports::aici::abi::controller::*, InitPromptResult}, + bindings::{self, exports::aici::abi::controller::*, InitPromptResult}, bintokens::ByteTokenizer, - shm::ShmAllocator, - user_error, }; -use anyhow::{bail, ensure, Result}; -use std::{path::PathBuf, rc::Rc, sync::Arc, time::Instant}; +use anyhow::Result; +use std::{path::PathBuf, sync::Arc, time::Instant}; use wasmtime; #[derive(Clone)] @@ -28,10 +25,7 @@ pub struct WasmContext { } impl WasmContext { - pub fn deserialize_component( - &self, - path: PathBuf, - ) -> Result { + pub fn deserialize_component(&self, path: PathBuf) -> Result { // TODO: Use type safety to ensure that the input is derived from `Component::serialize` or // `Engine::precompile_component`. unsafe { wasmtime::component::Component::deserialize_file(&self.engine, path) } @@ -149,7 +143,6 @@ impl ModuleInstance { &self.store.data().group_channel } - fn do_mid_process(&mut self, arg: RtMidProcessArg) -> Result { self.aici.aici_abi_controller().runner().call_mid_process( &mut self.store, @@ -158,7 +151,6 @@ impl ModuleInstance { ) } - fn seq_result(&mut self, lbl: &str, t0: Instant, res: Result) -> SequenceResult { // 10us accuracy for Spectre mitigation let micros = (t0.elapsed().as_micros() as u64 / 10) * 10; @@ -196,7 +188,7 @@ impl ModuleInstance { } pub fn tokenize(&mut self, s: &str) -> Result> { - self.store.data_mut().tokenize_str(s) + self.store.data_mut().tokenize_bytes_greedy(s) } fn setup_inner(&mut self, prompt: Vec) -> Result { diff --git a/aicirt/src/wasi/clock.rs b/aicirt/src/wasi/clock.rs new file mode 100644 index 00000000..6bfd20dc --- /dev/null +++ b/aicirt/src/wasi/clock.rs @@ -0,0 +1,49 @@ +use std::time::{Duration, Instant}; + +use wasmtime_wasi::{HostMonotonicClock, HostWallClock}; + +#[derive(Debug, Clone)] +pub struct BoundedResolutionClock { + resolution: Duration, + initial: Instant, +} + +impl BoundedResolutionClock { + pub fn new(resolution: Duration) -> Self { + BoundedResolutionClock { + resolution, + initial: Instant::now(), + } + } +} + +impl HostMonotonicClock for BoundedResolutionClock { + fn resolution(&self) -> u64 { + self.resolution.as_nanos() as u64 + } + + fn now(&self) -> u64 { + let now = std::time::Instant::now(); + let nanos = now.duration_since(self.initial).as_nanos() as u64; + let res = self.resolution.as_nanos() as u64; + let nanos = if res > 0 { nanos / res * res } else { nanos }; + nanos as u64 + } +} + +impl HostWallClock for BoundedResolutionClock { + fn resolution(&self) -> Duration { + self.resolution + } + + fn now(&self) -> Duration { + let now = std::time::SystemTime::now(); + let nanos = now + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos() as u64; + let res = self.resolution.as_nanos() as u64; + let nanos = if res > 0 { nanos / res * res } else { nanos }; + Duration::from_nanos(nanos) + } +} diff --git a/aicirt/src/wasi/mod.rs b/aicirt/src/wasi/mod.rs new file mode 100644 index 00000000..159730d2 --- /dev/null +++ b/aicirt/src/wasi/mod.rs @@ -0,0 +1 @@ +pub mod clock; diff --git a/aicirt/src/worker.rs b/aicirt/src/worker.rs index 7efb9297..77c54859 100644 --- a/aicirt/src/worker.rs +++ b/aicirt/src/worker.rs @@ -7,13 +7,13 @@ use crate::{ shm::Shm, InstantiateReq, UserError, }; -use aici_abi::{toktrie, StorageCmd, StorageOp, StorageResp}; +use aici_abi::{StorageCmd, StorageResp}; use aicirt::{ api::SequenceResult, bindings::*, futexshm::{TypedClient, TypedClientHandle, TypedServer}, set_max_priority, - shm::{ShmAllocator, Unlink}, + shm::Unlink, user_error, variables::Variables, }; @@ -23,7 +23,6 @@ use serde::{Deserialize, Serialize}; use std::{ fmt::Debug, path::PathBuf, - rc::Rc, sync::{Arc, Mutex}, time::{Duration, Instant}, }; @@ -458,7 +457,6 @@ struct SeqCtx { query: Option, inst_id: ModuleInstId, modinst: Option, - shm: Rc, } struct CommsPid { @@ -558,11 +556,7 @@ pub struct WorkerForker { fork_worker: ForkerHandle, } -fn forker_dispatcher( - mut server: TypedServer, - wasm_ctx: WasmContext, - shm: Rc, -) -> ! { +fn forker_dispatcher(mut server: TypedServer, wasm_ctx: WasmContext) -> ! { set_process_name("aicirt-forker"); loop { // wait for any children that might have exited to prevent zombies @@ -597,7 +591,6 @@ fn forker_dispatcher( id: cmd_id, server, wasm_ctx, - shm, query: None, inst_id: 424242, modinst: None, @@ -669,7 +662,7 @@ pub fn stop_process() -> ! { // } impl WorkerForker { - pub fn new(wasm_ctx: WasmContext, shm: Rc) -> Self { + pub fn new(wasm_ctx: WasmContext) -> Self { // create a new process group let pid = unsafe { libc::getpid() }; unsafe { @@ -687,7 +680,7 @@ impl WorkerForker { limits, } } - ForkResult::Child { server } => forker_dispatcher(server, wasm_ctx, shm), + ForkResult::Child { server } => forker_dispatcher(server, wasm_ctx), } } diff --git a/controllers/aici_abi/Cargo.toml b/controllers/aici_abi/Cargo.toml index 190067b8..f3703b40 100644 --- a/controllers/aici_abi/Cargo.toml +++ b/controllers/aici_abi/Cargo.toml @@ -2,7 +2,7 @@ name = "aici_abi" version = "0.1.0" edition = "2021" -rust-version = "1.75.0" +rust-version = "1.81.0" [lib] name = "aici_abi" diff --git a/controllers/aici_abi/src/cfg.rs b/controllers/aici_abi/src/cfg.rs index 74137b81..8dbcc317 100644 --- a/controllers/aici_abi/src/cfg.rs +++ b/controllers/aici_abi/src/cfg.rs @@ -4,6 +4,7 @@ use crate::{ toktrie::{Recognizer, SpecialToken}, SimpleVob, }; +use std::str; use anyhow::Result; use cfgrammar::{ yacc::{YaccGrammar, YaccKind}, @@ -511,7 +512,7 @@ pub fn cfg_test() -> Result<()> { let trie = TokTrie::from_bytes(&tokenizer::token_trie_bytes()); let toks = trie.greedy_tokenize(sample); - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(target_os = "wasi"))] let t0 = std::time::Instant::now(); let mut line = 1; @@ -542,7 +543,7 @@ pub fn cfg_test() -> Result<()> { trie.append_token(&mut cfg, tok).unwrap(); } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(target_os = "wasi"))] println!("time: {:?} ", t0.elapsed()); println!("stats: {}", cfg.get_stats()); diff --git a/controllers/aici_abi/src/lib.rs b/controllers/aici_abi/src/lib.rs index 4a218f3c..b23e883d 100644 --- a/controllers/aici_abi/src/lib.rs +++ b/controllers/aici_abi/src/lib.rs @@ -12,7 +12,7 @@ pub use bindings::{controller::*, runtime, runtime_storage, tokenizer}; macro_rules! export { ($ty:ident) => { #[doc(hidden)] - #[cfg(target_arch = "wasm32")] + #[cfg(target_os = "wasi")] $crate::bindings::export!($ty with_types_in $crate::bindings); }; } @@ -33,109 +33,6 @@ pub mod substring; pub use host::{aici_stop, StorageCmd, StorageOp, StorageResp}; -impl From for InitPromptResult { - fn from(value: InitPromptArg) -> Self { - InitPromptResult { - prompt: value.prompt, - } - - } -} - -impl InitPromptResult { - pub fn from_arg(arg: InitPromptArg) -> Self { - arg.into() - } -} - -impl From for Vocabulary { - fn from(value: toktrie::SimpleVob) -> Self { - let size = value.len() as u64; - Vocabulary { - data: value.into(), - size, - } - } -} - -impl From for Splice { - fn from(value: toktrie::Splice) -> Self { - Splice { - backtrack: value.backtrack, - ff_tokens: value.ff_tokens, - when_sampled: value.when_sampled, - } - } -} - -impl From> for Branch { - fn from(value: toktrie::Branch) -> Self { - Branch { - sample_mask: value.sample_mask.map(|x| x.into()), - splices: value.splices.into_iter().map(|x| x.into()).collect(), - temperature: value.temperature, - } - } -} - -impl MidProcessArg { - pub fn has_eos(&self) -> bool { - let eos = tokenizer::eos_token(); - self.tokens.iter().any(|t| *t == eos) - } - - pub fn save_tokens(&self, acc_tokens: &mut Vec) { - let bt = self.backtrack as usize; - assert!( - bt <= acc_tokens.len(), - "attempting to backtrack past beginning" - ); - acc_tokens.truncate(acc_tokens.len() - bt); - acc_tokens.extend_from_slice(&self.tokens); - } -} - -impl MidProcessResult { - pub fn from_branch(branch: toktrie::Branch) -> Self { - if branch.is_stop() { - Self::stop() - } else { - MidProcessResult { - branches: vec![branch.into()], - } - } - } - pub fn from_branches(branches: Vec>) -> Self { - MidProcessResult { - branches: branches.into_iter().map(|x| x.into()).collect(), - } - } - - pub fn stop() -> Self { - MidProcessResult { branches: vec![] } - } - - pub fn sample(set: toktrie::SimpleVob) -> Self { - Self::sample_with_temp(set, None) - } - - pub fn sample_with_temp(set: toktrie::SimpleVob, temperature: Option) -> Self { - Self::from_branch(toktrie::Branch::sample(set, temperature)) - } - - pub fn splice(backtrack: u32, ff_tokens: Vec) -> Self { - Self::from_branch(toktrie::Branch::splice(backtrack, ff_tokens)) - } - - pub fn noop() -> Self { - Self::splice(0, vec![]) - } - - pub fn is_stop(&self) -> bool { - self.branches.is_empty() - } -} - pub trait AiciCtrl { fn init_prompt(&mut self, arg: InitPromptArg) -> InitPromptResult { InitPromptResult::from_arg(arg) diff --git a/controllers/aici_wasm_guest/Cargo.toml b/controllers/aici_wasm_guest/Cargo.toml index eb2c7ae2..fde1d88c 100644 --- a/controllers/aici_wasm_guest/Cargo.toml +++ b/controllers/aici_wasm_guest/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] wit-bindgen = "0.30.0" serde = { version = "1.0.192", features = ["derive"] } +toktrie = { path = "../toktrie/core" } diff --git a/controllers/aici_wasm_guest/src/lib.rs b/controllers/aici_wasm_guest/src/lib.rs index 401cacb7..d7b5e396 100644 --- a/controllers/aici_wasm_guest/src/lib.rs +++ b/controllers/aici_wasm_guest/src/lib.rs @@ -6,3 +6,108 @@ wit_bindgen::generate!({ }); pub use self::{aici::abi::*, exports::aici::abi::*}; + +use controller::*; + +impl From for InitPromptResult { + fn from(value: InitPromptArg) -> Self { + InitPromptResult { + prompt: value.prompt, + } + + } +} + +impl InitPromptResult { + pub fn from_arg(arg: InitPromptArg) -> Self { + arg.into() + } +} + +impl From for Vocabulary { + fn from(value: toktrie::SimpleVob) -> Self { + let size = value.len() as u64; + Vocabulary { + data: value.into(), + size, + } + } +} + +impl From for Splice { + fn from(value: toktrie::Splice) -> Self { + Splice { + backtrack: value.backtrack, + ff_tokens: value.ff_tokens, + when_sampled: value.when_sampled, + } + } +} + +impl From> for Branch { + fn from(value: toktrie::Branch) -> Self { + Branch { + sample_mask: value.sample_mask.map(|x| x.into()), + splices: value.splices.into_iter().map(|x| x.into()).collect(), + temperature: value.temperature, + } + } +} + +impl MidProcessArg { + pub fn has_eos(&self) -> bool { + let eos = tokenizer::eos_token(); + self.tokens.iter().any(|t| *t == eos) + } + + pub fn save_tokens(&self, acc_tokens: &mut Vec) { + let bt = self.backtrack as usize; + assert!( + bt <= acc_tokens.len(), + "attempting to backtrack past beginning" + ); + acc_tokens.truncate(acc_tokens.len() - bt); + acc_tokens.extend_from_slice(&self.tokens); + } +} + +impl MidProcessResult { + pub fn from_branch(branch: toktrie::Branch) -> Self { + if branch.is_stop() { + Self::stop() + } else { + MidProcessResult { + branches: vec![branch.into()], + } + } + } + pub fn from_branches(branches: Vec>) -> Self { + MidProcessResult { + branches: branches.into_iter().map(|x| x.into()).collect(), + } + } + + pub fn stop() -> Self { + MidProcessResult { branches: vec![] } + } + + pub fn sample(set: toktrie::SimpleVob) -> Self { + Self::sample_with_temp(set, None) + } + + pub fn sample_with_temp(set: toktrie::SimpleVob, temperature: Option) -> Self { + Self::from_branch(toktrie::Branch::sample(set, temperature)) + } + + pub fn splice(backtrack: u32, ff_tokens: Vec) -> Self { + Self::from_branch(toktrie::Branch::splice(backtrack, ff_tokens)) + } + + pub fn noop() -> Self { + Self::splice(0, vec![]) + } + + pub fn is_stop(&self) -> bool { + self.branches.is_empty() + } +} diff --git a/controllers/declctrl/src/lib.rs b/controllers/declctrl/src/lib.rs index 06fc6582..3e3237da 100644 --- a/controllers/declctrl/src/lib.rs +++ b/controllers/declctrl/src/lib.rs @@ -10,7 +10,14 @@ */ use aici_abi::{ - bytes::limit_str, cfg::CfgParser, export, rx::{RecRx, RxStackRecognizer}, tokenizer, toktrie::{Branch, Recognizer, SpecialToken, TokTrie}, ExportedProgram, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult, SimpleVob, Splice, TokenId + bytes::limit_str, + cfg::CfgParser, + export, + rx::{RecRx, RxStackRecognizer}, + tokenizer, + toktrie::{Branch, Recognizer, SpecialToken, TokTrie}, + ExportedProgram, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult, SimpleVob, + TokenId, }; use core::panic; use serde::{Deserialize, Serialize}; diff --git a/controllers/guidance_ctrl/src/earley_bench.rs b/controllers/guidance_ctrl/src/earley_bench.rs index 21a64804..15635291 100644 --- a/controllers/guidance_ctrl/src/earley_bench.rs +++ b/controllers/guidance_ctrl/src/earley_bench.rs @@ -1,9 +1,9 @@ fn main() { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(target_os = "wasi"))] bench(); } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(target_os = "wasi"))] fn bench() { use aici_abi::toktree::TokTrie; use aici_guidance_ctrl::earley::bench::earley_test; diff --git a/controllers/jsctrl/src/lib.rs b/controllers/jsctrl/src/lib.rs index 6a017e0a..905e90e7 100644 --- a/controllers/jsctrl/src/lib.rs +++ b/controllers/jsctrl/src/lib.rs @@ -4,7 +4,7 @@ use aici_abi::{ tokenizer, toktrie::{Recognizer, SpecialToken, TokTrie}, AiciCtrl, ExportedProgram, Guest, InitPromptArg, InitPromptResult, MidProcessArg, - MidProcessResult, Program, SeqId, SimpleVob, Splice, TokenId, + MidProcessResult, Program, SimpleVob, TokenId, }; use rquickjs::{ class::Trace, function::IntoArgs, ArrayBuffer, Context, Ctx, FromJs, Function, IntoAtom, diff --git a/controllers/llguidance_ctrl/src/gctrl.rs b/controllers/llguidance_ctrl/src/gctrl.rs index f68da01d..08dcb2c9 100644 --- a/controllers/llguidance_ctrl/src/gctrl.rs +++ b/controllers/llguidance_ctrl/src/gctrl.rs @@ -1,9 +1,10 @@ use std::sync::Arc; use aici_abi::{ - arg_bytes, get_config, + export, tokenizer, toktrie::{InferenceCapabilities, StepArg}, - AiciCtrl, InitPromptArg, InitPromptResult, MidProcessArg, MidProcessResult, + AiciCtrl, ExportedProgram, Guest, InitPromptArg, InitPromptResult, MidProcessArg, + MidProcessResult, Program, TokenizerEnv, }; use serde::{Deserialize, Serialize}; @@ -29,19 +30,55 @@ struct RunnerArg { grammar: TopLevelGrammar, } +struct AmbientTokenEnv { + toktrie: aici_abi::toktrie::TokTrie, +} + +impl AmbientTokenEnv { + fn new() -> Self { + AmbientTokenEnv { + toktrie: aici_abi::toktrie::TokTrie::from_bytes( + &aici_abi::tokenizer::token_trie_bytes(), + ), + } + } +} + +impl TokenizerEnv for AmbientTokenEnv { + fn stop(&self) -> ! { + aici_abi::aici_stop() + } + + fn tok_trie(&self) -> &aici_abi::toktrie::TokTrie { + &self.toktrie + } + + fn tokenize_bytes(&self, s: &[u8]) -> Vec { + tokenizer::tokenize_bytes(s) + } + + fn tokenize(&self, s: &str) -> Vec { + tokenizer::tokenize(s) + } + + fn eos_token(&self) -> aici_abi::toktrie::TokenId { + tokenizer::eos_token() + } +} + impl Runner { - pub fn new() -> Self { + pub fn new(arg: String) -> Self { infoln!("building runner..."); - let arg: RunnerArg = serde_json::from_slice(&arg_bytes()).expect("invalid JSON arg"); + let arg: RunnerArg = serde_json::from_str(&arg).expect("invalid JSON arg"); let log_level = 2; let inf = InferenceCapabilities { - backtrack: get_config("backtrack") != 0, - ff_tokens: get_config("ff_tokens") != 0, - conditional_ff_tokens: get_config("ff_tokens") != 0, + backtrack: aici_abi::runtime::get_config("backtrack") != 0, + ff_tokens: aici_abi::runtime::get_config("ff_tokens") != 0, + conditional_ff_tokens: aici_abi::runtime::get_config("ff_tokens") != 0, fork: false, }; let tok_parser = TokenParser::from_llguidance_json( - Arc::new(aici_abi::WasmTokenizerEnv::default()), + Arc::new(AmbientTokenEnv::new()), arg.grammar, Logger::new(0, log_level), inf, @@ -81,4 +118,14 @@ impl AiciCtrl for Runner { fn main() {} -aici_abi::aici_expose_all!(Runner, Runner::new()); +impl Program for Runner { + fn new(arg: String) -> Self { + Runner::new(arg) + } +} + +impl Guest for Runner { + type Runner = ExportedProgram; +} + +export!(Runner); diff --git a/controllers/uppercase/src/main.rs b/controllers/uppercase/src/main.rs index fa4999d5..4cd94fd9 100644 --- a/controllers/uppercase/src/main.rs +++ b/controllers/uppercase/src/main.rs @@ -33,7 +33,7 @@ pub struct Runner { } impl aici_abi::Program for Runner { - fn new(prompt: String) -> Self { + fn new(_: String) -> Self { Runner { toktrie: TokTrie::from_bytes(&tokenizer::token_trie_bytes()), tokens: Vec::new(), diff --git a/rllm/rllm-base/Cargo.toml b/rllm/rllm-base/Cargo.toml index f73bab3c..928af95e 100644 --- a/rllm/rllm-base/Cargo.toml +++ b/rllm/rllm-base/Cargo.toml @@ -17,6 +17,7 @@ actix-web = "4.4.0" tokio = { version = "1.34.0", features = ["sync"] } futures = "0.3.29" uuid = { version = "1.6.1", features = ["v4"] } +toktrie = { path = "../../controllers/toktrie/core" } aicirt = { path = "../../aicirt" } aici_abi = { path = "../../controllers/aici_abi" } diff --git a/rllm/rllm-base/src/engine.rs b/rllm/rllm-base/src/engine.rs index 1ec2c344..9cd9ab01 100644 --- a/rllm/rllm-base/src/engine.rs +++ b/rllm/rllm-base/src/engine.rs @@ -9,7 +9,7 @@ use crate::{ AiciBias as _, HashMap, LoaderArgs, LogitsProcessor, ModelExec, Scheduler, SchedulerOutputs, SequenceManager, TBlockSpaceManager as _, }; -use aici_abi::{toktrie::TokTrie, Splice}; +use aici_abi::toktrie::{TokTrie, Splice}; use aicirt::{ api::{AiciMidOp, AiciMidProcessReq, ModuleInstId, SequenceResult}, bindings::SeqId, with_timer, TimerRef, TimerSet }; diff --git a/rllm/rllm-base/src/exec.rs b/rllm/rllm-base/src/exec.rs index 74d374a6..468dd367 100644 --- a/rllm/rllm-base/src/exec.rs +++ b/rllm/rllm-base/src/exec.rs @@ -1,7 +1,7 @@ -use std::{fmt::Display, sync::Arc}; +use std::sync::Arc; -use aicirt::{TimerRef}; pub use aicirt::bindings::SeqId; +use aicirt::TimerRef; use anyhow::Result; use crate::{ diff --git a/rllm/rllm-base/src/seq.rs b/rllm/rllm-base/src/seq.rs index 0d79a05c..6f88d7b7 100644 --- a/rllm/rllm-base/src/seq.rs +++ b/rllm/rllm-base/src/seq.rs @@ -1,7 +1,7 @@ use crate::{ config::SamplingParams, engine::ExpectedGeneration, LogitsProcessor, SeqId, SequenceManager, }; -use aici_abi::{toktrie::TokTrie, Branch, TokenId}; +use aici_abi::{toktrie::TokTrie, TokenId}; use aicirt::api::{AiciMidOp, SequenceResult}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; @@ -59,7 +59,7 @@ pub struct Sequence { pub(crate) output_pending: Vec, pub num_kv_computed: usize, pub(crate) has_aici: bool, - pub(crate) aici_sampling: Option>, + pub(crate) aici_sampling: Option>, pub aici_logs: Vec, pub(crate) expected: Option, @@ -130,7 +130,7 @@ impl Sequence { pub(crate) fn defl_mid_op(&self) -> AiciMidOp { AiciMidOp { - id: self.seq_id.to_num(), + id: self.seq_id, clone_id: None, clone_idx: None, req_id: None, diff --git a/rllm/rllm-llamacpp/Cargo.toml b/rllm/rllm-llamacpp/Cargo.toml index 3f9cee4d..fff092ca 100644 --- a/rllm/rllm-llamacpp/Cargo.toml +++ b/rllm/rllm-llamacpp/Cargo.toml @@ -2,7 +2,7 @@ name = "rllm-llamacpp" version = "0.1.0" edition = "2021" -rust-version = "1.75.0" +rust-version = "1.81.0" [dependencies] actix-web = "4.4.0" From fe67ea7311ab365753ba43c54b8228d62bafa95d Mon Sep 17 00:00:00 2001 From: Aaron Friel Date: Mon, 9 Sep 2024 05:32:50 +0000 Subject: [PATCH 4/8] Fix up wasm build, add wasm-tools to devcontainers --- .devcontainer/common.dockerfile | 1 + py/pyaici/cli.py | 38 +++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/.devcontainer/common.dockerfile b/.devcontainer/common.dockerfile index 8fc1046f..23c68a47 100644 --- a/.devcontainer/common.dockerfile +++ b/.devcontainer/common.dockerfile @@ -33,6 +33,7 @@ RUN curl https://sh.rustup.rs -sSf | sh -s -- \ -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION RUN rustup target add wasm32-wasip1 RUN rustup component add rustfmt +RUN cargo install wasm-tools@1.216.0 # run as root please; note that settings in devcontainer.json are also needed... USER root diff --git a/py/pyaici/cli.py b/py/pyaici/cli.py index 27d0f389..bb9d38fd 100644 --- a/py/pyaici/cli.py +++ b/py/pyaici/cli.py @@ -41,23 +41,33 @@ def build_rust(folder: str, features: List[str] = []): pkg_id = info["workspace_default_members"][0] pkg = [pkg for pkg in info["packages"] if pkg["id"] == pkg_id][0] - bins = [trg for trg in pkg["targets"] if trg["kind"] == ["bin"]] - if len(bins) == 0: - cli_error("no bin targets found") - bins_str = ", ".join([folder + "::" + trg["name"] for trg in bins]) - if bin_file: - if len([trg for trg in bins if trg["name"] == bin_file]) == 0: - cli_error(f"{bin_file} not found; try one of {bins_str}") - else: - if len(bins) > 1: - cli_error("more than one bin target found; use one of: " + - bins_str) - bin_file = bins[0]["name"] + libs = [trg for trg in pkg["targets"] if trg["kind"] == ["cdylib"]] + + if len(libs) == 0: + cli_error("no cdylib targets found") + + bins_str = ", ".join([folder + "::" + trg["name"] for trg in libs]) + if len(libs) > 1: + cli_error("more than one bin target found; use one of: " + bins_str) + bin_file = libs[0]["name"] print(f'will build {bin_file} from {pkg["manifest_path"]}') triple = "wasm32-wasip1" - trg_path = (info["target_directory"] + "/" + triple + "/release/" + - bin_file + ".wasm") + trg_path = ( + info["target_directory"] + "/" + triple + "/release/" + bin_file + ".wasm" + ) + + component_path = ( + info["target_directory"] + + "/" + + triple + + "/release/" + + bin_file + + ".component.wasm" + ) + + reactor_path = "controllers/wasi_snapshot_preview1.reactor.wasm" + # remove file first, so we're sure it's rebuilt try: os.unlink(trg_path) From acbf6db10a026e3906537ce843210d6a266ef914 Mon Sep 17 00:00:00 2001 From: Aaron Friel Date: Mon, 9 Sep 2024 05:35:21 +0000 Subject: [PATCH 5/8] Fix build and increase compile time --- aicirt/src/main.rs | 2 +- controllers/aici_abi/src/lib.rs | 2 +- controllers/pyctrl/src/lib.rs | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/aicirt/src/main.rs b/aicirt/src/main.rs index 91edffae..b5316788 100644 --- a/aicirt/src/main.rs +++ b/aicirt/src/main.rs @@ -1296,7 +1296,7 @@ fn main() -> () { max_init_ms: cli.wasm_max_init_time, max_step_ms: cli.wasm_max_step_time, max_timeout_steps: cli.wasm_max_timeout_steps, - max_compile_ms: 10_000, + max_compile_ms: 30_000, logit_memory_bytes: cli.bin_size * MEGABYTE, busy_wait_duration: Duration::from_millis(cli.busy_wait_time), max_forks: cli.wasm_max_forks, diff --git a/controllers/aici_abi/src/lib.rs b/controllers/aici_abi/src/lib.rs index b23e883d..f9c75b4a 100644 --- a/controllers/aici_abi/src/lib.rs +++ b/controllers/aici_abi/src/lib.rs @@ -4,7 +4,7 @@ pub use toktrie::{SimpleVob, TokenizerEnv}; use std::sync::{Arc, Mutex}; -mod bindings; +pub mod bindings; pub use bindings::{controller::*, runtime, runtime_storage, tokenizer}; diff --git a/controllers/pyctrl/src/lib.rs b/controllers/pyctrl/src/lib.rs index c99e0ac8..a8f9f3ac 100644 --- a/controllers/pyctrl/src/lib.rs +++ b/controllers/pyctrl/src/lib.rs @@ -103,6 +103,13 @@ mod _aici { bytes } + #[pyfunction] + fn tokens_repr(tokens: PyObjectRef, vm: &VirtualMachine) -> String { + let tokens = vm.to_u32_list(tokens); + let trie = &mut GLOBAL_STATE.lock().unwrap().trie; + trie.tokens_dbg(&tokens) + } + #[pyfunction] fn token_repr(token: u32) -> String { let trie = &mut GLOBAL_STATE.lock().unwrap().trie; From d4633d99476cc94600c8039146c15c0c7d2ea889 Mon Sep 17 00:00:00 2001 From: Aaron Friel Date: Mon, 9 Sep 2024 05:39:32 +0000 Subject: [PATCH 6/8] download reactor on demand --- controllers/.gitignore | 1 + py/pyaici/cli.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 controllers/.gitignore diff --git a/controllers/.gitignore b/controllers/.gitignore new file mode 100644 index 00000000..7df99e66 --- /dev/null +++ b/controllers/.gitignore @@ -0,0 +1 @@ +wasi_snapshot_preview1.reactor.wasm diff --git a/py/pyaici/cli.py b/py/pyaici/cli.py index bb9d38fd..03748b0d 100644 --- a/py/pyaici/cli.py +++ b/py/pyaici/cli.py @@ -3,6 +3,7 @@ import sys import os import argparse +import requests from . import rest, jssrc from . import add_cli_args, runner_from_cli @@ -15,6 +16,20 @@ def cli_error(msg: str): sys.exit(1) +def acquire_reactor_adaptor(): + REACTOR_PATH = "controllers/wasi_snapshot_preview1.reactor.wasm" + + if os.path.exists(REACTOR_PATH): + return os.path.abspath(REACTOR_PATH) + + print("Downloading reactor adaptor...") + url = "https://github.com/bytecodealliance/wasmtime/releases/download/dev/wasi_snapshot_preview1.reactor.wasm" + response = requests.get(url) + with open(REACTOR_PATH, "wb") as f: + f.write(response.content) + + return os.path.abspath(REACTOR_PATH) + def build_rust(folder: str, features: List[str] = []): bin_file = "" spl = folder.split("::") @@ -66,7 +81,7 @@ def build_rust(folder: str, features: List[str] = []): + ".component.wasm" ) - reactor_path = "controllers/wasi_snapshot_preview1.reactor.wasm" + reactor_path = acquire_reactor_adaptor() # remove file first, so we're sure it's rebuilt try: From ad72b372af170d3f76487857e2a5e241725b8036 Mon Sep 17 00:00:00 2001 From: Aaron Friel Date: Mon, 9 Sep 2024 05:45:02 +0000 Subject: [PATCH 7/8] Add example list-of-five script --- scripts/list-of-five.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 scripts/list-of-five.py diff --git a/scripts/list-of-five.py b/scripts/list-of-five.py new file mode 100644 index 00000000..e94bb2fb --- /dev/null +++ b/scripts/list-of-five.py @@ -0,0 +1,33 @@ +import pyaici.server as aici + +# Force the model to generate a well formatted list of 5 items, e.g. +# 1. name 1 +# 2. name 2 +# 3. name 3 +# 4. name 4 +# 5. name 5 +async def main(): + + # This is the prompt we want to run. + # Note how the prompt doesn't mention a number of vehicles or how to format the result. + prompt = "What are the most popular types of vehicles?\n" + + # Tell the model to generate the prompt string, ie. let's start with the prompt "to complete" + await aici.FixedTokens(prompt) + + # Store the current position in the token generation process + marker = aici.Label() + + for i in range(1,6): + # Tell the model to generate the list number + await aici.FixedTokens(f"{i}.") + + # Wait for the model to generate a vehicle name and end with a new line + await aici.gen_text(stop_at = "\n") + + await aici.FixedTokens("\n") + + # Store the tokens generated in a result variable + aici.set_var("result", marker.text_since()) + +aici.start(main()) From 94eb745b588d85c5487c8ca17ec0c1d23c417aae Mon Sep 17 00:00:00 2001 From: Aaron Friel Date: Mon, 9 Sep 2024 07:56:33 +0000 Subject: [PATCH 8/8] restore logging behavior --- Cargo.lock | 1 + aicirt/Cargo.toml | 1 + aicirt/src/hostimpl.rs | 32 ++++++++++++---- aicirt/src/main.rs | 50 ++++++++++-------------- aicirt/src/moduleinstance.rs | 10 +++-- aicirt/src/wasi/logs.rs | 74 ++++++++++++++++++++++++++++++++++++ aicirt/src/wasi/mod.rs | 1 + 7 files changed, 130 insertions(+), 39 deletions(-) create mode 100644 aicirt/src/wasi/logs.rs diff --git a/Cargo.lock b/Cargo.lock index d7da0cca..ea87fd93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -374,6 +374,7 @@ dependencies = [ "base64 0.21.7", "bincode", "bytemuck", + "bytes", "cap", "clap", "hex", diff --git a/aicirt/Cargo.toml b/aicirt/Cargo.toml index a59eceee..11e07914 100644 --- a/aicirt/Cargo.toml +++ b/aicirt/Cargo.toml @@ -29,6 +29,7 @@ ureq = "2.9.5" wasmtime-wasi = "24.0.0" bytemuck = "1.16.0" aici_wasm_host = { version = "0.1.0", path = "../controllers/aici_wasm_host" } +bytes = "1.7.1" [target.'cfg(target_os = "linux")'.dependencies] linux-futex = "0.2.0" diff --git a/aicirt/src/hostimpl.rs b/aicirt/src/hostimpl.rs index 773bf60b..ffc842a5 100644 --- a/aicirt/src/hostimpl.rs +++ b/aicirt/src/hostimpl.rs @@ -3,10 +3,9 @@ use crate::{ worker::{GroupCmd, GroupHandle, GroupResp}, }; use aici_abi::{ - toktrie::{TokRxInfo, TokTrie}, - StorageCmd, + bytes::limit_str, toktrie::{TokRxInfo, TokTrie}, StorageCmd }; -use aicirt::wasi::clock::BoundedResolutionClock; +use aicirt::wasi::{clock::BoundedResolutionClock, logs::BoundedLogPipe}; use aicirt::{api::InferenceCapabilities, bindings::SeqId, user_error}; use anyhow::{anyhow, Result}; use std::{ops::Deref, sync::Arc, time::Duration}; @@ -35,7 +34,7 @@ type ModuleInstId = crate::api::ModuleInstId; // this is available to functions called from wasm pub struct ModuleData { pub id: ModuleInstId, - log: wasmtime_wasi::pipe::MemoryOutputPipe, + log: BoundedLogPipe, printed_log: usize, pub globals: GlobalInfo, pub group_channel: GroupHandle, @@ -67,12 +66,12 @@ impl ModuleData { BoundedResolutionClock::new(Duration::from_nanos(limits.timer_resolution_ns)); let monotonic_clock = wall_clock.clone(); - let log = wasmtime_wasi::pipe::MemoryOutputPipe::new(MAX_LOG); + let log = BoundedLogPipe::new(MAX_LOG); let stdout = log.clone(); let stderr = log.clone(); ModuleData { id, - log: log, + log, printed_log: 0, globals, group_channel, @@ -90,9 +89,28 @@ impl ModuleData { pub fn string_log(&mut self) -> String { self.printed_log = 0; - let logs = String::from_utf8_lossy(&self.log.contents()).to_string(); + let logs = String::from_utf8_lossy(&self.log.drain_contents()).to_string(); logs } + + pub fn flush_logs(&mut self, name: &str) { + if !log::log_enabled!(log::Level::Debug) { + return; + } + + let contents = self.log.contents(); + let data = &contents[self.printed_log..]; + if data.len() == 0 { + return; + } + + let logs = String::from_utf8_lossy(data).to_string(); + self.printed_log = contents.len(); + + for line in logs.lines() { + log::debug!("{}:{}> {}", self.id, name, limit_str(line, 512)); + } + } } impl wasmtime_wasi::WasiView for ModuleData { diff --git a/aicirt/src/main.rs b/aicirt/src/main.rs index b5316788..fb0617b4 100644 --- a/aicirt/src/main.rs +++ b/aicirt/src/main.rs @@ -856,9 +856,8 @@ impl Stepper { } } - if let Some(r) = &mut data.result { - let branches = r - .branches + let result: Vec> = if let Some(r) = &mut data.result { + r.branches .iter() .map(|b| { b.map_mask(|vob| { @@ -867,7 +866,11 @@ impl Stepper { let bias_type = BiasType::from_u32(shm.elt_type() & 0xf).unwrap(); - bias_type.apply_to_shm_allocator(bytemuck::cast_slice(&vob.data), &shm, off); + bias_type.apply_to_shm_allocator( + bytemuck::cast_slice(&vob.data), + &shm, + off, + ); let idx = (off - first_mask_byte_offset) / mask_num_bytes; assert!(idx * mask_num_bytes + first_mask_byte_offset == off); @@ -876,32 +879,21 @@ impl Stepper { idx }) }) - .collect(); - - outputs.insert( - id, - SequenceResult { - result: Some(RtMidProcessResult { branches }), - error: String::new(), - storage: vec![], - logs: String::new(), - micros: start_time.elapsed().as_micros() as u64, - }, - ); + .collect() } else { - outputs.insert( - id, - SequenceResult { - result: Some(RtMidProcessResult { - branches: vec![toktrie::Branch::noop()], - }), - error: String::new(), - storage: vec![], - logs: String::new(), - micros: start_time.elapsed().as_micros() as u64, - }, - ); - } + vec![toktrie::Branch::noop()] + }; + + outputs.insert( + id, + SequenceResult { + result: Some(RtMidProcessResult { branches: result }), + error: data.error, + storage: data.storage, + logs: data.logs, + micros: data.micros, + }, + ); } Err(e) => { if e.to_string() == "timeout" && prev_timeout < self.limits.max_timeout_steps { diff --git a/aicirt/src/moduleinstance.rs b/aicirt/src/moduleinstance.rs index 5515a588..99184d6e 100644 --- a/aicirt/src/moduleinstance.rs +++ b/aicirt/src/moduleinstance.rs @@ -125,7 +125,9 @@ impl ModuleInstance { let runner = aici .aici_abi_controller() .runner() - .call_constructor(&mut store, &module_arg)?; + .call_constructor(&mut store, &module_arg); + store.data_mut().flush_logs("constructor"); + let runner = runner?; Ok(ModuleInstance { store, @@ -184,6 +186,7 @@ impl ModuleInstance { let t0 = Instant::now(); let res = self.do_mid_process(op); // log::info!("mid_process: {:?}", t0.elapsed()); + self.store.data_mut().flush_logs("mid_process"); self.seq_result("mid", t0, res) } @@ -196,8 +199,9 @@ impl ModuleInstance { &mut self.store, self.runner, &InitPromptArg { prompt }, - )?; - Ok(res.into()) + ); + self.store.data_mut().flush_logs("init_prompt"); + Ok(res?.into()) } pub fn setup(&mut self, prompt: Vec) -> SequenceResult { diff --git a/aicirt/src/wasi/logs.rs b/aicirt/src/wasi/logs.rs new file mode 100644 index 00000000..e536fa47 --- /dev/null +++ b/aicirt/src/wasi/logs.rs @@ -0,0 +1,74 @@ +use std::sync::{Arc, Mutex}; + +use anyhow::{anyhow, Result}; +use wasmtime_wasi::{async_trait, HostOutputStream, StdoutStream, StreamError, Subscribe}; + +#[derive(Debug, Clone)] +pub struct BoundedLogPipe { + pub capacity: usize, + pub buffer: Arc>, +} + +impl BoundedLogPipe { + pub fn new(capacity: usize) -> Self { + BoundedLogPipe { + capacity, + buffer: std::sync::Arc::new(std::sync::Mutex::new(bytes::BytesMut::new())), + } + } + + pub fn contents(&self) -> bytes::Bytes { + self.buffer.lock().unwrap().clone().freeze() + } + + /// Drain the contents of the buffer, emptying it and returning the former contents. + pub fn drain_contents(&self) -> bytes::Bytes { + let mut buf = self.buffer.lock().unwrap(); + std::mem::replace(&mut *buf, bytes::BytesMut::new()).freeze() + } +} + +impl HostOutputStream for BoundedLogPipe { + fn write(&mut self, bytes: bytes::Bytes) -> Result<(), StreamError> { + let mut buf = self.buffer.lock().unwrap(); + if bytes.len() > self.capacity - buf.len() { + return Err(StreamError::Trap(anyhow!( + "write beyond capacity of BoundedLogPipe" + ))); + } + buf.extend_from_slice(bytes.as_ref()); + // Always ready for writing + Ok(()) + } + + fn flush(&mut self) -> Result<(), StreamError> { + // This stream is always flushed + Ok(()) + } + + fn check_write(&mut self) -> Result { + let consumed = self.buffer.lock().unwrap().len(); + if consumed < self.capacity { + Ok(self.capacity - consumed) + } else { + // Since the buffer is full, no more bytes will ever be written + Err(StreamError::Closed) + } + } +} + +#[async_trait] +impl Subscribe for BoundedLogPipe { + async fn ready(&mut self) {} +} + + +impl StdoutStream for BoundedLogPipe { + fn stream(&self) -> Box { + Box::new(self.clone()) + } + + fn isatty(&self) -> bool { + true // Otherwise terminal_stdout + } +} diff --git a/aicirt/src/wasi/mod.rs b/aicirt/src/wasi/mod.rs index 159730d2..22d46098 100644 --- a/aicirt/src/wasi/mod.rs +++ b/aicirt/src/wasi/mod.rs @@ -1 +1,2 @@ pub mod clock; +pub mod logs;