diff --git a/.cargo/audit.toml b/.cargo/audit.toml index fd61035..8468d24 100644 --- a/.cargo/audit.toml +++ b/.cargo/audit.toml @@ -8,4 +8,12 @@ ignore = [ # rsa 0.9.10 Marvin Attack (timing sidechannel). No fix available. Transitive # dependency via sqlx-mysql — Hadrian doesn't use RSA keys for MySQL auth. "RUSTSEC-2023-0071", + # hickory-proto 0.25.2 NSEC3 unbounded loop and O(n²) name-compression DoS. + # Pulled in only by microsandbox-network (the `runtime-microsandbox` feature, + # off in every default profile) for in-microVM DNS resolution behind the + # sandbox egress allowlist. microsandbox 0.4.5 pins the hickory 0.25.x line + # (see the dependency comment in Cargo.toml); a fixed 0.26.x requires a + # microsandbox bump. Hadrian's own resolver uses hickory-resolver 0.26.1. + "RUSTSEC-2026-0118", + "RUSTSEC-2026-0119", ] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c61009c..d789090 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: run: rustup install nightly && rustup component add rustfmt --toolchain nightly - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev tesseract-ocr tesseract-ocr-eng + run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev libcap-ng-dev tesseract-ocr tesseract-ocr-eng - name: Cache cargo uses: Swatinem/rust-cache@v2 @@ -85,7 +85,7 @@ jobs: uses: dtolnay/rust-toolchain@stable - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev tesseract-ocr tesseract-ocr-eng + run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev libcap-ng-dev tesseract-ocr tesseract-ocr-eng - name: Cache cargo uses: Swatinem/rust-cache@v2 @@ -202,7 +202,7 @@ jobs: - name: Install dependencies (Linux full) if: matrix.features == 'full' && runner.os == 'Linux' - run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev + run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev libcap-ng-dev - name: Install dependencies (macOS) if: runner.os == 'macOS' @@ -436,7 +436,7 @@ jobs: - name: Install build deps for samael run: | sudo apt-get update - sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev pkg-config libssl-dev + sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libcap-ng-dev pkg-config libssl-dev - name: Regenerate Hadrian OpenAPI spec run: cargo run --release -- openapi --output openapi/hadrian.openapi.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b8eff20..db0395c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -166,7 +166,7 @@ jobs: - name: Install dependencies (Linux full/standard) if: runner.os == 'Linux' && (contains(matrix.features, 'full') || contains(matrix.features, 'standard')) - run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev libssl-dev pkg-config + run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev libcap-ng-dev libssl-dev pkg-config - name: Install dependencies (macOS) if: runner.os == 'macOS' @@ -301,7 +301,7 @@ jobs: shared-key: publish - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev tesseract-ocr tesseract-ocr-eng + run: sudo apt-get update && sudo apt-get install -y libxml2-dev libxslt1-dev libxmlsec1-dev libclang-dev libcap-ng-dev tesseract-ocr tesseract-ocr-eng - name: Publish to crates.io run: cargo publish --no-default-features --features headless --allow-dirty diff --git a/CLAUDE.md b/CLAUDE.md index 08abf38..0661045 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,15 +19,18 @@ Read files in `agent_instructions/` for detailed guidance on specific tasks: - `adding_admin_endpoint.md` — Admin endpoints and pagination patterns - `adding_frontend_tool.md` — Frontend tools -- `adding_provider.md` — LLM providers -- `architecture.md` — Multi-tenancy, auth, RBAC, SSO, request flow, RAG, chat modes, caching +- `adding_provider.md` — LLM providers (and how server-side tools rewrite) +- `adding_runtime.md` — Shell-tool runtime backends (passthrough, microsandbox, opensandbox, …) +- `architecture.md` — Multi-tenancy, auth, RBAC, SSO, request flow, RAG, chat modes, caching, server-side tools - `ci_cd.md` — CI, release, and deploy pipelines - `configuration.md` — Config sections, feature flags, provider options +- `containers.md` — Responses-API containers, shell tool, lifecycle, file staging - `database_changes.md` — Database migrations and schema changes - `documentation.md` — Documentation site, writing guidelines, Storybook embeds - `frontend_conventions.md` — Frontend conventions, accessibility (WCAG 2.1 AA) - `key_files.md` — Comprehensive file listing by subsystem - `modifying_chat_ui.md` — Chat UI performance (stores, selectors, memoization) +- `responses_pipeline.md` — Foreground/background streaming pipeline, server-tool loop - `testing.md` — Provider e2e tests (wiremock), university E2E tests - `wasm.md` — WASM build architecture and frontend development @@ -47,6 +50,7 @@ cargo clippy # Lint cargo +nightly fmt # Format (requires nightly) cargo run # Run with default config (hadrian.toml) cargo run -- --config path.toml # Run with custom config +docker build -t hadrian:local . # Build gateway image first (compose files use hadrian:local) cd deploy/tests && pnpm test # E2E tests with testcontainers ``` @@ -61,6 +65,17 @@ Hierarchical profiles (default: `full`): - **`headless`** — full without embedded assets - **`wasm`** — Browser-only build (see `agent_instructions/wasm.md`) +Shell-tool runtime backends are gated by their own feature flags (off by default in every +profile so the heavy SDKs are opt-in): + +- **`runtime-microsandbox`** — pulls in the microsandbox SDK + microVM dependencies for the + in-process `microsandbox` runtime. +- **`runtime-opensandbox`** — pulls in the HTTP client glue for the Alibaba OpenSandbox + Lifecycle API. No new system dependencies. + +`passthrough_openai` and `client_passthrough` runtimes are always available; they require no +extra cargo features. See `agent_instructions/containers.md`. + ```bash cargo build --no-default-features --features tiny # Smallest binary cargo build --no-default-features --features minimal # Fast compile @@ -128,7 +143,7 @@ See `agent_instructions/architecture.md` for details on RBAC, SSO, RAG, chat mod ## Testing - Unit tests: same file as code (`#[cfg(test)]`) -- E2E tests: `cd deploy/tests && pnpm test` +- E2E tests: `docker build -t hadrian:local .` (first), then `cd deploy/tests && pnpm test` - Test both SQLite and PostgreSQL paths - See `agent_instructions/testing.md` for provider and university E2E tests diff --git a/Cargo.lock b/Cargo.lock index 605e0c8..fc896d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,6 +54,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + [[package]] name = "aligned" version = "0.4.3" @@ -244,6 +250,45 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "asn1-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure 0.13.2", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "assert-json-diff" version = "2.0.2" @@ -265,9 +310,9 @@ dependencies = [ [[package]] name = "astral-tokio-tar" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce73b17c62717c4b6a9af10b43e87c578b0cac27e00666d48304d3b7d2c0693" +checksum = "cb50a7aae84a03bf55b067832bc376f4961b790c97e64d3eacee97d389b90277" dependencies = [ "filetime", "futures-core", @@ -595,7 +640,7 @@ dependencies = [ "lru", "percent-encoding", "regex-lite", - "sha2", + "sha2 0.10.9", "tracing", "url", ] @@ -718,7 +763,7 @@ dependencies = [ "p256", "percent-encoding", "ring", - "sha2", + "sha2 0.10.9", "subtle", "time", "tracing", @@ -753,7 +798,7 @@ dependencies = [ "md-5", "pin-project-lite", "sha1", - "sha2", + "sha2 0.10.9", "tracing", ] @@ -1015,7 +1060,7 @@ dependencies = [ "rustc_version", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "tokio", "tracing", "typespec", @@ -1116,7 +1161,7 @@ checksum = "53d0c374feba1b9a59042a7c1cf00ce7c34b977b9134fe7c42b08e5183729f66" dependencies = [ "paste", "roman-numerals-rs", - "strum", + "strum 0.27.2", "unicode-normalization", "unscanny", ] @@ -1136,13 +1181,32 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + [[package]] name = "bindgen" version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags", + "bitflags 2.11.1", "cexpr", "clang-sys", "itertools 0.13.0", @@ -1192,6 +1256,12 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.11.1" @@ -1245,6 +1315,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -1262,7 +1341,7 @@ checksum = "ee04c4c84f1f811b017f2fbb7dd8815c976e7ca98593de9c1e2afad0f636bff4" dependencies = [ "async-stream", "base64 0.22.1", - "bitflags", + "bitflags 2.11.1", "bollard-buildkit-proto", "bollard-stubs", "bytes", @@ -1452,6 +1531,25 @@ dependencies = [ "either", ] +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "calamine" version = "0.34.0" @@ -1470,6 +1568,25 @@ dependencies = [ "zip 7.2.0", ] +[[package]] +name = "capng" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a26766f93f07f7e8b8309ed2824fa2a68f5d12d219de855e24688e9fbe89e85" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "caps" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd1ddba47aba30b6a889298ad0109c3b8dcb0e8fc993b459daa7067d46f865e0" +dependencies = [ + "libc", +] + [[package]] name = "caseless" version = "0.2.2" @@ -1609,13 +1726,40 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "inout", ] @@ -1667,7 +1811,7 @@ version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.117", @@ -1746,6 +1890,8 @@ dependencies = [ "compression-core", "flate2", "memchr", + "zstd", + "zstd-safe", ] [[package]] @@ -1818,6 +1964,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-random" version = "0.1.18" @@ -1838,12 +1990,42 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "constant_time_eq" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "cookie" version = "0.18.1" @@ -1921,7 +2103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" dependencies = [ "crc", - "digest", + "digest 0.10.7", "rustversion", "spin 0.10.0", ] @@ -1990,6 +2172,33 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crossterm" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +dependencies = [ + "bitflags 2.11.1", + "crossterm_winapi", + "derive_more", + "document-features", + "mio", + "parking_lot", + "rustix", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.4" @@ -2028,6 +2237,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + [[package]] name = "csv" version = "1.4.0" @@ -2208,13 +2426,54 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7eed2c4702fa172d1ce21078faa7c5203e69f5394d48cc436d25928394a867a2" +[[package]] +name = "defmt" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "defmt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.18", +] + [[package]] name = "der" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid", + "const-oid 0.9.6", "zeroize", ] @@ -2224,11 +2483,25 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", + "const-oid 0.9.6", "pem-rfc7468", "zeroize", ] +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits", + "rusticata-macros", +] + [[package]] name = "deranged" version = "0.5.8" @@ -2301,6 +2574,29 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.117", + "unicode-xid", +] + [[package]] name = "dialoguer" version = "0.12.0" @@ -2320,12 +2616,23 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", + "block-buffer 0.10.4", + "const-oid 0.9.6", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "const-oid 0.10.2", + "crypto-common 0.2.1", +] + [[package]] name = "dirs" version = "6.0.0" @@ -2441,7 +2748,7 @@ dependencies = [ "base16ct", "crypto-bigint 0.4.9", "der 0.6.1", - "digest", + "digest 0.10.7", "ff", "generic-array", "group", @@ -2476,12 +2783,30 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + [[package]] name = "entities" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "equator" version = "0.4.2" @@ -2515,7 +2840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2973,6 +3298,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getset" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "gif" version = "0.14.2" @@ -3121,7 +3458,7 @@ dependencies = [ "google-cloud-metadata", "google-cloud-token", "home", - "jsonwebtoken", + "jsonwebtoken 9.3.1", "reqwest 0.12.28", "serde", "serde_json", @@ -3394,10 +3731,11 @@ dependencies = [ "ipnet", "js-sys", "jsonschema", - "jsonwebtoken", + "jsonwebtoken 9.3.1", "kreuzberg", "metrics", "metrics-exporter-prometheus", + "microsandbox", "once_cell", "open", "openssl", @@ -3410,6 +3748,8 @@ dependencies = [ "redis", "regex", "reqwest 0.12.28", + "reqwest 0.13.2", + "rmcp", "rstest", "rust-embed", "rust_decimal", @@ -3419,7 +3759,7 @@ dependencies = [ "serde-wasm-bindgen", "serde_json", "serial_test", - "sha2", + "sha2 0.10.9", "sqlx", "subtle", "temp-env", @@ -3449,7 +3789,7 @@ dependencies = [ "vaultrs", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", + "wasm-streams 0.4.2", "web-sys", "wiremock", ] @@ -3465,6 +3805,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -3541,11 +3890,27 @@ dependencies = [ "fearless_simd", ] +[[package]] +name = "heapless" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" +dependencies = [ + "hash32", + "stable_deref_trait", +] + [[package]] name = "heck" -version = "0.5.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +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" @@ -3559,6 +3924,25 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hickory-client" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c466cd63a4217d5b2b8e32f23f58312741ce96e3c84bf7438677d2baff0fc555" +dependencies = [ + "cfg-if", + "data-encoding", + "futures-channel", + "futures-util", + "hickory-proto 0.25.2", + "once_cell", + "radix_trie", + "rand 0.9.4", + "thiserror 2.0.18", + "tokio", + "tracing", +] + [[package]] name = "hickory-net" version = "0.26.1" @@ -3571,7 +3955,7 @@ dependencies = [ "futures-channel", "futures-io", "futures-util", - "hickory-proto", + "hickory-proto 0.26.1", "idna", "ipnet", "jni 0.22.4", @@ -3583,6 +3967,34 @@ dependencies = [ "url", ] +[[package]] +name = "hickory-proto" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" +dependencies = [ + "async-trait", + "bytes", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand 0.9.4", + "ring", + "rustls", + "thiserror 2.0.18", + "tinyvec", + "tokio", + "tokio-rustls", + "tracing", + "url", +] + [[package]] name = "hickory-proto" version = "0.26.1" @@ -3612,7 +4024,7 @@ dependencies = [ "cfg-if", "futures-util", "hickory-net", - "hickory-proto", + "hickory-proto 0.26.1", "ipconfig", "ipnet", "jni 0.22.4", @@ -3644,7 +4056,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -3728,6 +4140,15 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-auth" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "150fa4a9462ef926824cf4519c84ed652ca8f4fbae34cb8af045b5cbcaf98822" +dependencies = [ + "memchr", +] + [[package]] name = "http-body" version = "0.4.6" @@ -3780,6 +4201,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "1.9.0" @@ -3831,7 +4261,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 1.0.6", ] [[package]] @@ -4074,6 +4504,26 @@ dependencies = [ "quick-error", ] +[[package]] +name = "imago" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae7cfee876c698a1a2ed9c705ab18f21acbed82110f19b51cc458de73426fe2c" +dependencies = [ + "async-trait", + "bincode", + "cfg-if", + "libc", + "miniz_oxide", + "nix", + "page_size", + "rustc_version", + "tokio", + "tracing", + "vm-memory 0.18.0", + "windows-sys 0.61.2", +] + [[package]] name = "imgref" version = "1.12.0" @@ -4112,6 +4562,17 @@ dependencies = [ "cfb 0.7.3", ] +[[package]] +name = "inherent" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c727f80bfa4a6c6e2508d2f05b6f4bfce242030bd88ed15ae5331c5b5d30fba7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "inout" version = "0.1.4" @@ -4164,6 +4625,15 @@ dependencies = [ "serde", ] +[[package]] +name = "ipnetwork" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf370abdafd54d13e54a620e8c3e1145f28e46cc9d704bc6d94414559df41763" +dependencies = [ + "serde", +] + [[package]] name = "iri-string" version = "0.7.12" @@ -4241,7 +4711,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -4412,6 +4882,21 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "jsonwebtoken" +version = "10.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" +dependencies = [ + "base64 0.22.1", + "getrandom 0.2.17", + "js-sys", + "serde", + "serde_json", + "signature 2.2.0", + "zeroize", +] + [[package]] name = "kamadak-exif" version = "0.6.1" @@ -4421,6 +4906,21 @@ dependencies = [ "mutate_once", ] +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "kreuzberg" version = "4.7.4" @@ -4493,7 +4993,7 @@ version = "4.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b3bd3fcf58d80f760e3abcafe4da1c0e2c9b61998eec6f8694baae436a30ca5" dependencies = [ - "bitflags", + "bitflags 2.11.1", "bytemuck", "chrono", "console_error_panic_hook", @@ -4525,6 +5025,27 @@ dependencies = [ "zip 8.5.1", ] +[[package]] +name = "kvm-bindings" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b3c06ff73c7ce03e780887ec2389d62d2a2a9ddf471ab05c2ff69207cd3f3b4" +dependencies = [ + "vmm-sys-util", +] + +[[package]] +name = "kvm-ioctls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "333f77a20344a448f3f70664918135fddeb804e938f28a99d685bd92926e0b19" +dependencies = [ + "bitflags 2.11.1", + "kvm-bindings", + "libc", + "vmm-sys-util", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -4594,7 +5115,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags", + "bitflags 2.11.1", "libc", "plain", "redox_syscall 0.7.4", @@ -4622,6 +5143,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-loader" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870c3814345f050991f99869417779f6062542bcf4ed81db7a1b926ad1306638" +dependencies = [ + "vm-memory 0.16.2", +] + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -4671,7 +5201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73fdcbab5b237a03984f83b1394dc534e0b1960675c7f3ec4d04dccc9032b56d" dependencies = [ "aes", - "bitflags", + "bitflags 2.11.1", "cbc", "chrono", "ecb", @@ -4688,7 +5218,7 @@ dependencies = [ "rand 0.10.1", "rangemap", "rayon", - "sha2", + "sha2 0.10.9", "stringprep", "thiserror 2.0.18", "time", @@ -4720,6 +5250,12 @@ dependencies = [ "nalgebra", ] +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + [[package]] name = "markup5ever" version = "0.39.0" @@ -4779,7 +5315,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", ] [[package]] @@ -4797,6 +5333,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "metrics" version = "0.24.3" @@ -4844,6 +5389,202 @@ dependencies = [ "sketches-ddsketch", ] +[[package]] +name = "microsandbox" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81251b9d0124a70d95e6f5f7211f4c45a71bc24d5d2f92c4aa016d464d06e0cf" +dependencies = [ + "astral-tokio-tar", + "async-compression", + "bytes", + "chrono", + "crossterm", + "dirs", + "docker_credential", + "flate2", + "futures", + "hex", + "libc", + "microsandbox-db", + "microsandbox-filesystem", + "microsandbox-image", + "microsandbox-migration", + "microsandbox-network", + "microsandbox-protocol", + "microsandbox-runtime", + "microsandbox-utils", + "nix", + "rand 0.10.1", + "reqwest 0.13.2", + "scopeguard", + "sea-orm", + "serde", + "serde_json", + "sha2 0.11.0", + "tar", + "tempfile", + "thiserror 2.0.18", + "tokio", + "tracing", + "typed-builder", + "ureq", + "which", +] + +[[package]] +name = "microsandbox-db" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e0cf4b1e42563a39975ec111d0c5ca3b2d2648dcc445a97be6cebc1c8155308" +dependencies = [ + "async-trait", + "sea-orm", + "sqlx", + "tokio", + "tracing", +] + +[[package]] +name = "microsandbox-filesystem" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efdf0dbee927e3e828860eddc6a3b234a8e793ccc23636ed9962c25b3955121e" +dependencies = [ + "libc", + "microsandbox-utils", + "msb_krun", + "scopeguard", + "tempfile", + "tracing", +] + +[[package]] +name = "microsandbox-image" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e99be592e0bf911930b31ae52864217c7d5d9b54e83cadd3b93d065ad23bed8d" +dependencies = [ + "astral-tokio-tar", + "async-compression", + "futures", + "hex", + "libc", + "microsandbox-utils", + "oci-client", + "oci-spec", + "rustls-pemfile", + "scopeguard", + "serde", + "serde_json", + "sha2 0.11.0", + "thiserror 2.0.18", + "tokio", + "tokio-util", + "tracing", + "xattr", +] + +[[package]] +name = "microsandbox-migration" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b72e5b5b2c5bdea11a4d50b540c69d20466b828311466713ed03b2e1720718a" +dependencies = [ + "sea-orm-migration", +] + +[[package]] +name = "microsandbox-network" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c09d853c6828f36c0e951dbf4190fc850fc5d4d976ebf5fcf26301d51d2c137" +dependencies = [ + "bytes", + "core-foundation 0.9.4", + "crossbeam-queue", + "dirs", + "futures", + "hickory-client", + "hickory-proto 0.25.2", + "ipnetwork", + "libc", + "lru", + "microsandbox-protocol", + "microsandbox-utils", + "msb_krun", + "parking_lot", + "pem", + "rcgen", + "resolv-conf", + "rustls", + "rustls-native-certs", + "rustls-pemfile", + "serde", + "smoltcp", + "system-configuration", + "thiserror 2.0.18", + "time", + "tokio", + "tokio-rustls", + "tracing", +] + +[[package]] +name = "microsandbox-protocol" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d655a839bc767cadbd769a15f35b3cedd23aac8c67a53ba36188822e6af193d4" +dependencies = [ + "chrono", + "ciborium", + "serde", + "serde_bytes", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "microsandbox-runtime" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9eb5b8015349c86daf7346d6bfb7199b809109831e5d6d5ef9f5729c627fe1" +dependencies = [ + "bytes", + "chrono", + "clap", + "crossbeam-queue", + "libc", + "microsandbox-db", + "microsandbox-filesystem", + "microsandbox-network", + "microsandbox-protocol", + "microsandbox-utils", + "msb_krun", + "nix", + "rustls", + "sea-orm", + "serde", + "serde_json", + "tempfile", + "thiserror 2.0.18", + "tokio", + "tracing", +] + +[[package]] +name = "microsandbox-utils" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d62293decc8415995915c95f45b5e2425316e518f3ff90a28c23beecf945108" +dependencies = [ + "dirs", + "libc", + "reflink-copy", + "scopeguard", + "ureq", +] + [[package]] name = "mime" version = "0.3.17" @@ -4883,6 +5624,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.61.2", ] @@ -4914,6 +5656,171 @@ dependencies = [ "pxfm", ] +[[package]] +name = "msb_krun" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c29ba9c9c8a38cd001c0c9af16bd3c75be328ab8c95a3aa933b125c1d93f41c" +dependencies = [ + "crossbeam-channel", + "kvm-bindings", + "kvm-ioctls", + "libc", + "libloading 0.8.9", + "log", + "msb_krun_devices", + "msb_krun_hvf", + "msb_krun_polly", + "msb_krun_utils", + "msb_krun_vmm", + "vm-memory 0.16.2", +] + +[[package]] +name = "msb_krun_arch" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb4327e3efe423f3bcdca0390589193834b9f73eb54bb13b90f48f1755b499e" +dependencies = [ + "kvm-bindings", + "kvm-ioctls", + "libc", + "msb_krun_arch_gen", + "msb_krun_smbios", + "msb_krun_utils", + "vm-memory 0.16.2", + "vmm-sys-util", +] + +[[package]] +name = "msb_krun_arch_gen" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bc7dbc08509138172ccd3b40df5c1501ad498ba12f2643eb013320205f9c987" + +[[package]] +name = "msb_krun_cpuid" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d88b81a52ae5b3fe1afb1692b0785a4fe946c77bbc9e43a030e84e90627819" +dependencies = [ + "kvm-bindings", + "kvm-ioctls", + "vmm-sys-util", +] + +[[package]] +name = "msb_krun_devices" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6d808b3c4d5a7c24fba02a64f2f704da973cf6820deedd2811c2ec795b9fc" +dependencies = [ + "bitflags 1.3.2", + "capng", + "caps", + "crossbeam-channel", + "imago", + "kvm-bindings", + "kvm-ioctls", + "libc", + "libloading 0.8.9", + "log", + "lru", + "msb_krun_arch", + "msb_krun_hvf", + "msb_krun_polly", + "msb_krun_utils", + "nix", + "rand 0.9.4", + "virtio-bindings", + "vm-fdt", + "vm-memory 0.16.2", +] + +[[package]] +name = "msb_krun_hvf" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bce2de785e2cceda28ce03f20a9eeb895ac947ab66b09db31077a070bd6dda86" +dependencies = [ + "crossbeam-channel", + "libloading 0.8.9", + "log", + "msb_krun_arch", +] + +[[package]] +name = "msb_krun_kernel" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047a3f886330138dd6a681ef96b0b2257b494f295535bdd641841068f5847bc" +dependencies = [ + "msb_krun_utils", + "vm-memory 0.16.2", +] + +[[package]] +name = "msb_krun_polly" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db57f147c6e1aca9a14d137ada76b6df78b538a0673d86b33652be78e9784499" +dependencies = [ + "libc", + "msb_krun_utils", +] + +[[package]] +name = "msb_krun_smbios" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c0c3a0923f194852028fd0e809a8d26c5465bc550f59c08b25bae5dd9885457" +dependencies = [ + "vm-memory 0.16.2", +] + +[[package]] +name = "msb_krun_utils" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbae5590c539ee8b9ed0e2d4c50c6ee5b546f03f9eb2408b885628514ddb9a6" +dependencies = [ + "bitflags 1.3.2", + "crossbeam-channel", + "kvm-bindings", + "libc", + "log", + "nix", + "vmm-sys-util", +] + +[[package]] +name = "msb_krun_vmm" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd62153e5ffe89a76b775c89b9c01b65d38c67a32ca8d516a910d4cb497d367" +dependencies = [ + "bzip2", + "crossbeam-channel", + "flate2", + "kvm-bindings", + "kvm-ioctls", + "libc", + "linux-loader", + "log", + "msb_krun_arch", + "msb_krun_arch_gen", + "msb_krun_cpuid", + "msb_krun_devices", + "msb_krun_hvf", + "msb_krun_kernel", + "msb_krun_polly", + "msb_krun_utils", + "nix", + "vm-memory 0.16.2", + "vmm-sys-util", + "zstd", +] + [[package]] name = "multer" version = "3.1.0" @@ -5020,6 +5927,28 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.11.1", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + [[package]] name = "no_std_io2" version = "0.9.3" @@ -5152,49 +6081,131 @@ version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "num-traits", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "oauth2" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" +dependencies = [ + "base64 0.22.1", + "chrono", + "getrandom 0.2.17", + "http 1.4.0", + "rand 0.8.5", + "serde", + "serde_json", + "serde_path_to_error", + "sha2 0.10.9", + "thiserror 1.0.69", + "url", ] [[package]] -name = "num-iter" -version = "0.1.45" +name = "oci-client" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "1b7f8deaffcd3b0e3baf93dddcab3d18b91d46dc37d38a8b170089b234de5bb3" dependencies = [ - "autocfg", - "num-integer", - "num-traits", + "bytes", + "chrono", + "futures-util", + "http 1.4.0", + "http-auth", + "jsonwebtoken 10.4.0", + "lazy_static", + "oci-spec", + "olpc-cjson", + "regex", + "reqwest 0.13.2", + "serde", + "serde_json", + "sha2 0.10.9", + "thiserror 2.0.18", + "tokio", + "tracing", + "unicase", ] [[package]] -name = "num-rational" -version = "0.4.2" +name = "oci-spec" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +checksum = "e8445a2631507cec628a15fdd6154b54a3ab3f20ed4fe9d73a3b8b7a4e1ba03a" dependencies = [ - "num-bigint", - "num-integer", - "num-traits", + "const_format", + "derive_builder 0.20.2", + "getset", + "regex", + "serde", + "serde_json", + "strum 0.27.2", + "strum_macros", + "thiserror 2.0.18", ] [[package]] -name = "num-traits" -version = "0.2.19" +name = "oid-registry" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" dependencies = [ - "autocfg", - "libm", + "asn1-rs", ] [[package]] -name = "num_cpus" -version = "1.17.0" +name = "olpc-cjson" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +checksum = "696183c9b5fe81a7715d074fd632e8bd46f4ccc0231a3ed7fc580a80de5f7083" dependencies = [ - "hermit-abi", - "libc", + "serde", + "serde_json", + "unicode-normalization", ] [[package]] @@ -5230,7 +6241,7 @@ version = "0.10.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfe4646e360ec77dff7dde40ed3d6c5fee52d156ef4a62f53973d38294dad87f" dependencies = [ - "bitflags", + "bitflags 2.11.1", "cfg-if", "foreign-types", "libc", @@ -5362,12 +6373,45 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + [[package]] name = "org" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfdf547b633735ad9d67353aba48b3e685ab5ffb3195aaa9a1b1d8613e11b98c" +[[package]] +name = "ouroboros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.117", +] + [[package]] name = "outref" version = "0.5.2" @@ -5382,7 +6426,17 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa", "elliptic-curve", - "sha2", + "sha2 0.10.9", +] + +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", ] [[package]] @@ -5614,7 +6668,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags", + "bitflags 2.11.1", "crc32fast", "fdeflate", "flate2", @@ -5727,6 +6781,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "version_check", + "yansi", +] + [[package]] name = "profiling" version = "1.0.17" @@ -5804,7 +6871,7 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" dependencies = [ - "bitflags", + "bitflags 2.11.1", "getopts", "memchr", "pulldown-cmark-escape", @@ -5948,6 +7015,16 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + [[package]] name = "rand" version = "0.8.5" @@ -6114,7 +7191,7 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags", + "bitflags 2.11.1", ] [[package]] @@ -6143,6 +7220,20 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rcgen" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "x509-parser", + "yasna", +] + [[package]] name = "redis" version = "0.32.7" @@ -6175,7 +7266,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.11.1", ] [[package]] @@ -6184,7 +7275,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ - "bitflags", + "bitflags 2.11.1", ] [[package]] @@ -6232,6 +7323,18 @@ dependencies = [ "serde_json", ] +[[package]] +name = "reflink-copy" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13362233b147e57674c37b802d216b7c5e3dcccbed8967c84f0d8d223868ae27" +dependencies = [ + "cfg-if", + "libc", + "rustix", + "windows", +] + [[package]] name = "regex" version = "1.12.3" @@ -6323,9 +7426,9 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", + "wasm-streams 0.4.2", "web-sys", - "webpki-roots", + "webpki-roots 1.0.6", ] [[package]] @@ -6336,9 +7439,11 @@ checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ "base64 0.22.1", "bytes", + "encoding_rs", "futures-channel", "futures-core", "futures-util", + "h2", "http 1.4.0", "http-body 1.0.1", "http-body-util", @@ -6348,6 +7453,7 @@ dependencies = [ "hyper-util", "js-sys", "log", + "mime", "native-tls", "percent-encoding", "pin-project-lite", @@ -6362,12 +7468,14 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls", + "tokio-util", "tower", "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams 0.5.0", "web-sys", ] @@ -6437,6 +7545,30 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rmcp" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0810a9f717d9828f475fe1f629f4c305c8464b7f496c3a854b58d29e65f4058e" +dependencies = [ + "async-trait", + "chrono", + "futures", + "http 1.4.0", + "oauth2", + "pin-project-lite", + "reqwest 0.13.2", + "serde", + "serde_json", + "sse-stream", + "thiserror 2.0.18", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", + "url", +] + [[package]] name = "rmp" version = "0.8.15" @@ -6483,8 +7615,8 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ - "const-oid", - "digest", + "const-oid 0.9.6", + "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", @@ -6559,7 +7691,7 @@ checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" dependencies = [ "globset", "mime_guess", - "sha2", + "sha2 0.10.9", "walkdir", ] @@ -6612,6 +7744,15 @@ dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + [[package]] name = "rustify" version = "0.6.1" @@ -6652,11 +7793,11 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6687,6 +7828,15 @@ dependencies = [ "security-framework", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" version = "1.14.0" @@ -6715,7 +7865,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6850,25 +8000,169 @@ dependencies = [ name = "schemars_derive" version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.117", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdd" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" + +[[package]] +name = "sea-bae" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f694a6ab48f14bc063cfadff30ab551d3c7e46d8f81836c51989d548f44a2a25" +dependencies = [ + "heck 0.4.1", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "sea-orm" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc312fedd460a47ea563911761d254a84e7b51d8cc73ec92c929e78f33fa957" +dependencies = [ + "async-stream", + "async-trait", + "chrono", + "derive_more", + "futures-util", + "log", + "ouroboros", + "sea-orm-macros", + "sea-query", + "sea-query-binder", + "serde", + "sqlx", + "strum 0.26.3", + "thiserror 2.0.18", + "tracing", + "url", +] + +[[package]] +name = "sea-orm-cli" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da80ebcdb44571e86f03a2bdcb5532136a87397f366f38bbce64673fc5e6a450" +dependencies = [ + "chrono", + "glob", + "regex", + "sea-schema", + "sqlx", + "tokio", + "tracing", + "tracing-subscriber", + "url", +] + +[[package]] +name = "sea-orm-macros" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b9a3f90e336ec74803e8eb98c61bc98754c1adfba3b4f84d946237b752b1c88" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "sea-bae", + "syn 2.0.117", + "unicode-ident", +] + +[[package]] +name = "sea-orm-migration" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c577f2959277e936c1d08109acd1e08fc36a95ef29ec028190ba82cad8f96e" +dependencies = [ + "async-trait", + "sea-orm", + "sea-orm-cli", + "sea-schema", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "sea-query" +version = "0.32.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a5d1c518eaf5eda38e5773f902b26ab6d5e9e9e2bb2349ca6c64cf96f80448c" +dependencies = [ + "chrono", + "inherent", + "ordered-float", + "sea-query-derive", +] + +[[package]] +name = "sea-query-binder" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0019f47430f7995af63deda77e238c17323359af241233ec768aba1faea7608" +dependencies = [ + "chrono", + "sea-query", + "sqlx", +] + +[[package]] +name = "sea-query-derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae0cbad6ab996955664982739354128c58d16e126114fe88c2a493642502aab" dependencies = [ + "darling 0.20.11", + "heck 0.4.1", "proc-macro2", "quote", - "serde_derive_internals", "syn 2.0.117", + "thiserror 2.0.18", ] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "sea-schema" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "2239ff574c04858ca77485f112afea1a15e53135d3097d0c86509cef1def1338" +dependencies = [ + "futures", + "sea-query", + "sea-query-binder", + "sea-schema-derive", + "sqlx", +] [[package]] -name = "sdd" -version = "3.0.10" +name = "sea-schema-derive" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" +checksum = "debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.117", +] [[package]] name = "seahash" @@ -6896,7 +8190,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", + "bitflags 2.11.1", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -6940,6 +8234,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -7122,7 +8426,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", ] [[package]] @@ -7139,7 +8443,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -7163,6 +8478,27 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.8" @@ -7179,7 +8515,7 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -7189,7 +8525,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -7286,6 +8622,20 @@ dependencies = [ "serde_core", ] +[[package]] +name = "smoltcp" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f73d40463bba65efc9adc6370b56df76d563cc46e2482bba58351b4afb7535e" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "cfg-if", + "defmt 0.3.100", + "heapless", + "managed", +] + [[package]] name = "socket2" version = "0.6.3" @@ -7369,9 +8719,10 @@ dependencies = [ "once_cell", "percent-encoding", "rust_decimal", + "rustls", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "thiserror 2.0.18", "tokio", @@ -7379,6 +8730,7 @@ dependencies = [ "tracing", "url", "uuid", + "webpki-roots 0.26.11", ] [[package]] @@ -7402,14 +8754,14 @@ checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", - "heck", + "heck 0.5.0", "hex", "once_cell", "proc-macro2", "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "sqlx-core", "sqlx-mysql", "sqlx-postgres", @@ -7427,12 +8779,12 @@ checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64 0.22.1", - "bitflags", + "bitflags 2.11.1", "byteorder", "bytes", "chrono", "crc", - "digest", + "digest 0.10.7", "dotenvy", "either", "futures-channel", @@ -7454,7 +8806,7 @@ dependencies = [ "rust_decimal", "serde", "sha1", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -7472,7 +8824,7 @@ checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64 0.22.1", - "bitflags", + "bitflags 2.11.1", "byteorder", "chrono", "crc", @@ -7494,7 +8846,7 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -7530,6 +8882,19 @@ dependencies = [ "uuid", ] +[[package]] +name = "sse-stream" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3962b63f038885f15bce2c6e02c0e7925c072f1ac86bb60fd44c5c6b762fb72" +dependencies = [ + "bytes", + "futures-util", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -7618,6 +8983,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + [[package]] name = "strum" version = "0.27.2" @@ -7633,7 +9004,7 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.117", @@ -7705,7 +9076,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags", + "bitflags 2.11.1", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -7732,6 +9103,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tar" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "temp-env" version = "0.3.6" @@ -7751,7 +9133,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -8193,7 +9575,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "async-compression", - "bitflags", + "bitflags 2.11.1", "bytes", "futures-core", "futures-util", @@ -8364,6 +9746,26 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" +[[package]] +name = "typed-builder" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31aa81521b70f94402501d848ccc0ecaa8f93c8eb6999eb9747e72287757ffda" +dependencies = [ + "typed-builder-macro", +] + +[[package]] +name = "typed-builder-macro" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "typed-path" version = "0.12.3" @@ -8372,9 +9774,9 @@ checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "typespec" @@ -8460,6 +9862,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" +[[package]] +name = "unicode-segmentation" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" + [[package]] name = "unicode-width" version = "0.2.2" @@ -8490,6 +9898,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "ureq" version = "3.3.0" @@ -8497,12 +9911,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ "base64 0.22.1", + "flate2", "log", "percent-encoding", "rustls", "rustls-pki-types", + "rustls-platform-verifier", "ureq-proto", "utf8-zero", + "webpki-roots 1.0.6", ] [[package]] @@ -8724,6 +10141,54 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "virtio-bindings" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "091f1f09cfbf2a78563b562e7a949465cce1aef63b6065645188d995162f8868" + +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + +[[package]] +name = "vm-fdt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e21282841a059bb62627ce8441c491f09603622cd5a21c43bfedc85a2952f23" + +[[package]] +name = "vm-memory" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd5e56d48353c5f54ef50bd158a0452fc82f5383da840f7b8efc31695dd3b9d" +dependencies = [ + "libc", + "thiserror 1.0.69", + "winapi", +] + +[[package]] +name = "vm-memory" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b55e753c7725603745cb32b2287ef7ef3da05c03c7702cda3fa8abe25ae0465" +dependencies = [ + "thiserror 2.0.18", +] + +[[package]] +name = "vmm-sys-util" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "506c62fdf617a5176827c2f9afbcf1be155b03a9b4bf9617a60dbc07e3a1642f" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + [[package]] name = "vsimd" version = "0.8.0" @@ -8870,13 +10335,26 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasm-streams" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wasmparser" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags", + "bitflags 2.11.1", "hashbrown 0.15.5", "indexmap 2.14.0", "semver", @@ -8923,6 +10401,15 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.6", +] + [[package]] name = "webpki-roots" version = "1.0.6" @@ -8938,6 +10425,15 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" +[[package]] +name = "which" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81995fafaaaf6ae47a7d0cc83c67caf92aeb7e5331650ae6ff856f7c0c60c459" +dependencies = [ + "libc", +] + [[package]] name = "whoami" version = "1.6.1" @@ -8986,7 +10482,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -8995,6 +10491,27 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -9008,6 +10525,17 @@ dependencies = [ "windows-strings", ] +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link 0.2.1", + "windows-threading", +] + [[package]] name = "windows-implement" version = "0.60.2" @@ -9042,6 +10570,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core", + "windows-link 0.2.1", +] + [[package]] name = "windows-registry" version = "0.6.1" @@ -9153,6 +10691,15 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -9339,7 +10886,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" dependencies = [ "anyhow", - "heck", + "heck 0.5.0", "wit-parser", ] @@ -9350,7 +10897,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", - "heck", + "heck 0.5.0", "indexmap 2.14.0", "prettyplease", "syn 2.0.117", @@ -9381,7 +10928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags", + "bitflags 2.11.1", "indexmap 2.14.0", "log", "serde", @@ -9426,6 +10973,24 @@ dependencies = [ "tap", ] +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom 7.1.3", + "oid-registry", + "ring", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + [[package]] name = "xattr" version = "1.6.1" @@ -9448,6 +11013,21 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + [[package]] name = "yoke" version = "0.8.2" @@ -9517,6 +11097,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] [[package]] name = "zerotrie" @@ -9602,6 +11196,34 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "zune-core" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index d5dfd97..3fe9c4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,6 +96,7 @@ standard = [ "embed-docs", "forecasting", "json-schema", + "mcp", "otlp", "prometheus", "redis", @@ -108,9 +109,16 @@ standard = [ "utoipa", "vault", ] +# `full` pulls in microsandbox (a KVM-based VMM SDK) and opensandbox. +# Microsandbox is Linux-only, brings ~135 transitive crates (KVM, +# sea-orm, oci-client, smoltcp, rcgen), and contains substantial +# unsafe. Keep it out of `standard` so the typical deployment profile +# stays small and macOS/Windows-portable. full = [ "standard", "document-extraction-full", + "runtime-microsandbox", + "runtime-opensandbox", "saml", "virus-scan", ] @@ -128,6 +136,7 @@ headless = [ "document-extraction-full", "forecasting", "json-schema", + "mcp", "otlp", "prometheus", "provider-anthropic", @@ -138,6 +147,8 @@ headless = [ "provider-vertex", "redis", "response-validation", + "runtime-microsandbox", + "runtime-opensandbox", "s3-storage", "saml", "secrets-aws", @@ -197,6 +208,20 @@ secrets-azure = ["azure-sdk", "dep:azure_security_keyvault_secrets"] secrets-gcp = ["gcp-sdk", "dep:google-cloud-secretmanager-v1"] vault = ["dep:vaultrs"] +# Shell-tool runtimes (server-executed `shell` tool backends) +# - microsandbox: local microVMs (github.com/superradcompany/microsandbox) +# - opensandbox: Alibaba's Sandbox Protocol over HTTP +runtime-microsandbox = ["dep:microsandbox"] +runtime-opensandbox = [] + +# MCP (Model Context Protocol) tool support — `{"type": "mcp", ...}` +# on `/v1/responses`. Pulls in the official `rmcp` crate for the +# client + Streamable HTTP transport when `hadrian_hosted` mode runs +# the loop. The `passthrough_openai` mode is pure forwarding and does +# not need this dep, so the feature gate keeps it out of `tiny` and +# `minimal` builds. +mcp = ["dep:rmcp", "dep:reqwest_mcp"] + # Auth sso = ["dep:hickory-resolver"] saml = ["sso", "dep:samael", "dep:openssl", "dep:flate2"] @@ -348,7 +373,7 @@ flate2 = { version = "1", optional = true } google-cloud-auth = { version = "0.17", default-features = false, features = ["rustls-tls"], optional = true } google-cloud-secretmanager-v1 = { version = "1.2", optional = true } google-cloud-token = { version = "0.1", optional = true } -hickory-resolver = { version = "0.26", features = ["tokio", "system-config"], optional = true } +hickory-resolver = { version = "0.26.1", features = ["tokio", "system-config"], optional = true } hostname = { version = "0.4.2", optional = true } jsonschema = { version = "0.29", optional = true } kreuzberg = { version = "~4.7", default-features = false, features = ["tokio-runtime", "bundled-pdfium", "office", "excel", "ocr"], optional = true } @@ -373,6 +398,44 @@ utoipa = { version = "5", features = ["chrono", "uuid", "axum_extras"], optional utoipa-scalar = { version = "0.3", features = ["axum"], optional = true } vaultrs = { version = "0.7.4", features = ["rustls"], optional = true } +# Shell-tool runtime: local microVM SDK. +# +# Pinned to 0.4.5: microsandbox 0.4.6 bumped `microsandbox-network` to +# `hickory-proto = 0.26.0-alpha.1` with the `tls-ring` feature, which +# was dropped in the 0.26 stable release — so 0.4.6 + Hadrian's +# `hickory-resolver = 0.26.1` won't resolve. 0.4.5 still depends on the +# 0.25.x line which carries `tls-ring`, letting Cargo pull two majors +# of hickory-proto side by side. +# +# We skip `keyring` (it pulls dbus) but keep `net` for container +# networking. +microsandbox = { version = "=0.4.5", default-features = false, features = ["net", "prebuilt"], optional = true } + +# Official Rust MCP SDK — client + Streamable HTTP transport + OAuth +# challenge detection. Used only when the `mcp` feature is enabled. +# Server-side features (transport-streamable-http-server, schemars, +# macros) are excluded to keep the runtime build lean; tests enable +# them via dev-dependencies when an in-process MCP server stub is +# needed. +rmcp = { version = "1.7", default-features = false, features = [ + "client", + "transport-streamable-http-client", + "transport-streamable-http-client-reqwest", + "client-side-sse", + "auth", + "reqwest", +], optional = true } + +# rmcp 1.7's `StreamableHttpClient` is implemented for reqwest 0.13's +# `Client`, while Hadrian's primary HTTP client is reqwest 0.12. To pin +# the MCP transport's DNS to validated IPs (SSRF / DNS-rebinding guard) +# we must hand rmcp a client of *its* reqwest version, so depend on 0.13 +# under an alias. Cargo unifies this with rmcp's transitive 0.13.x, so +# it's the same crate instance (and inherits rmcp's TLS features) — no +# duplicate compile. `default-features = false`: we only build a client +# with custom DNS resolution; TLS comes from rmcp's enabled features. +reqwest_mcp = { package = "reqwest", version = "0.13", default-features = false, optional = true } + # ───────────────────────────────────────────────────────────────────────────── # Target-specific: WASM needs JS-backed getrandom for uuid/rand # ───────────────────────────────────────────────────────────────────────────── diff --git a/Dockerfile b/Dockerfile index 971360e..d10bb60 100644 --- a/Dockerfile +++ b/Dockerfile @@ -61,6 +61,7 @@ RUN apt-get update && apt-get install -y \ libxslt1-dev \ libxmlsec1-dev \ libclang-dev \ + libcap-ng-dev \ && rm -rf /var/lib/apt/lists/* # Create app directory @@ -121,6 +122,7 @@ RUN apt-get update && apt-get install -y \ libxslt1.1 \ libxmlsec1 \ libxmlsec1-openssl \ + libcap-ng0 \ && rm -rf /var/lib/apt/lists/* # Create app user diff --git a/README.md b/README.md index 8d553e2..0d4b1a9 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ Supports OpenAI, Anthropic, AWS Bedrock, Google Vertex AI, Azure OpenAI, and any - **Cost tracking** -- Microcent precision, time-series forecasting, budget enforcement with atomic reservation. - **Observability** -- Prometheus metrics, OTLP tracing, structured logging, usage export. - **Web UI** -- Multi-model chat with 14 modes, web search, frontend tools (Python, JS, SQL, charts), MCP support, admin panel. +- **Agents** -- Server-side shell tool in persistent containers and server-side MCP, via the Responses API. - **Studio** -- Image generation, text-to-speech, transcription, and translation across providers. - **Secrets** -- External secrets managers (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, HashiCorp Vault) for credential storage. diff --git a/agent_instructions/adding_provider.md b/agent_instructions/adding_provider.md index a640c7a..c017874 100644 --- a/agent_instructions/adding_provider.md +++ b/agent_instructions/adding_provider.md @@ -662,6 +662,31 @@ ProviderTestSpec { | `list_models` | List available models | No | Yes (for health checks) | | `health_check` | Provider health | No | Has default impl | +## Server-side tools (`shell`, `file_search`, `web_search`) + +For `create_responses`, the execution layer rewrites server-side tools to function tools for +providers without a native equivalent — your provider doesn't need to know about `shell` or +`web_search` specifically. + +- **`shell`** — `routes/execution.rs` calls `preprocess_shell_tools` with a `ShellToolHint` + before invoking your provider. Anthropic / Bedrock / Vertex always get the rewrite (they + have no native shell tool); OpenAI / Azure keep the native spec when the runtime mode is + `passthrough_openai` or `client_passthrough`. If your provider has a native shell-like + primitive, extend `keeps_openai_native_shell()` in `config/runtimes.rs` and update the + per-provider branch in `ResponsesExecutor::execute`. +- **`file_search` / `web_search`** — same pattern; rewritten unconditionally for non-OpenAI + providers. The `ToolLoopRunner` (`services/server_tools/runner.rs`) intercepts the + resulting `function_call` items and executes them server-side. +- **Function-call shape compatibility** — your `convert.rs` needs to translate OpenAI-style + `function_call` / `function_call_output` items in `payload.input` to the provider's + tool-use format and back. The server-tool loop will not work otherwise. See + `providers/{anthropic,bedrock,vertex}/convert.rs` for working examples. +- **Container files** — when the server tool returns a `container_file_citation` annotation, + it shows up on a `response.content_part.done` event. You don't need to handle this in your + convert layer; the shell executor injects it on the way out via `transform_event`. + +For containers / shell architecture, see `containers.md` and `responses_pipeline.md`. + ## Checklist - [ ] Provider struct with `circuit_breaker` field diff --git a/agent_instructions/adding_runtime.md b/agent_instructions/adding_runtime.md new file mode 100644 index 0000000..9cde5fc --- /dev/null +++ b/agent_instructions/adding_runtime.md @@ -0,0 +1,73 @@ +# Adding a Shell Runtime Backend + +A "runtime" is the backend that executes the model's `shell` tool calls. Today: `passthrough_openai`, +`client_passthrough`, `microsandbox`, `opensandbox`. This doc walks through adding another +(e.g. E2B, Daytona, a local Docker exec, AgentCore Code Interpreter). + +Read `containers.md` first for the lifecycle and `responses_pipeline.md` for how runtimes plug +into the streaming pipeline. + +## The trait + +`src/runtimes/mod.rs` defines `ShellRuntime`: + +```rust +#[async_trait] +pub trait ShellRuntime: Send + Sync { + fn capabilities(&self) -> RuntimeCapabilities; + async fn start_session(&self, spec: SessionSpec) -> RuntimeResult; + async fn health_check(&self) -> RuntimeResult<()> { Ok(()) } +} +``` + +`SessionHandle` wraps a `Box` which exposes `exec`, `write_file`, +`read_file`, `terminate`. + +## Steps + +1. **Add a feature flag** in `Cargo.toml` (`runtime-`) — match the existing pattern of + gating the dep tree per backend so `tiny` / `minimal` profiles don't pull it in. +2. **Add config struct** in `src/config/runtimes.rs`: a `Config` with `serde(deny_unknown_fields)` + plus a new variant `ShellRuntimeConfig::(Config)`. Update `name()`, + `keeps_openai_native_shell()` (almost certainly returns `false` for a real sandbox), and + `ShellRuntimeConfig` doc examples. +3. **Add the runtime module** at `src/runtimes/.rs` behind `#[cfg(feature = "runtime-")]`. + Implement `ShellRuntime` + `ShellSession`. Honor `SessionSpec` (`mem_limit_bytes`, `cpu_limit`, + `egress_policy`, `mounted_skills`) — surface anything you can't honor as + `RuntimeCapabilities:: = false` so the orchestrator can fail-fast instead of silently + degrading. +4. **Re-export** in `src/runtimes/mod.rs` under matching `#[cfg]` and the module declaration. +5. **Construct in `src/app.rs`** alongside the other runtimes. Add an `info!` log line that + names the backend so operators see the choice on boot. +6. **Update `src/services/responses_pipeline.rs`** match (the one that resolves pricing / + label per runtime). It's behind a `passthrough_only` guard so the new arm should usually be + `(price_per_second, "")`. +7. **Pricing**: add a field on `[features.server_tools.pricing]` for the per-second microcents + rate so the usage tracker can attribute cost. See `microsandbox_microcents_per_second`. +8. **Tests** — at minimum: + - `capabilities()` returns the values you intend (test in the same file). + - A round-trip integration test if the backend has a stub mode; otherwise mark + `#[ignore]` and exercise from `deploy/tests` (see `testing.md`). + +## Capability checklist + +Each `RuntimeCapabilities` field controls a real behavior; lying breaks something: + +| Field | If false | +|-----------------------------|-------------------------------------------------------------------------------------------| +| `passthrough_only` | Orchestrator registers `ShellExecutor` and calls `start_session`. Pretty much always false. | +| `client_executes` | Only meaningful with `passthrough_only=true`. Drives whether OpenAI native `shell` is kept. | +| `secret_injection` | Requests with `domain_secrets` are rejected with a capability-mismatch error. | +| `egress_allowlist` | Requests with `network_policy.domains` are rejected. | +| `skill_mount` | `payload.skills` are silently dropped (warn-log only) for this runtime. | +| `file_io` | `input_file` staging into `/mnt/data` and file capture both fail open with a warning. | +| `network_isolation_modes` | Per-request `network_policy` modes outside this list are rejected. | +| `max_session_duration` | Sessions older than this are terminated by the reaper regardless of activity. | + +## Passthrough vs. hosted + +The trait was designed to model both. If your backend is really a passthrough (the call +happens elsewhere), implement it like `src/runtimes/passthrough.rs`: `start_session` returns +`Err(RuntimeError::Passthrough)`, capabilities advertise `passthrough_only: true`, and the +chat.rs preprocess decision is updated to keep the native `shell` spec for the right +upstream providers (currently OpenAI / Azure). diff --git a/agent_instructions/architecture.md b/agent_instructions/architecture.md index 0200bfe..5eb49f1 100644 --- a/agent_instructions/architecture.md +++ b/agent_instructions/architecture.md @@ -72,7 +72,9 @@ Each organization can configure its own identity provider (OIDC or SAML), replac ## Document Processing Flow (RAG) -1. **File Upload** (`POST /v1/files`) — Store raw file in database +1. **File Upload** (`POST /v1/files`) — Store raw file in database. The same Files API is also + the source for `input_file` parts on Responses requests (resolved into `/mnt/data` by + `services/input_file_staging.rs`). 2. **Add to Vector Store** (`POST /v1/vector_stores/{id}/files`) — Trigger processing - Note: 'Vector Stores' are called 'Knowledge Bases' in the UI. Do not refer to them as 'Vector Stores' there. 3. **Document Processor** (inline or queue mode): @@ -109,6 +111,34 @@ Client-side tool execution runs in the browser via WASM. When the LLM returns `t Tool results are sent back to the LLM to continue the conversation. Artifacts (charts, tables, images) are displayed inline in the chat. +## Server-side Tools & Agents + +The `/v1/responses` pipeline runs server-executed tools alongside the upstream provider's +stream. Today: `file_search`, `web_search`, `shell`. See `responses_pipeline.md` and +`containers.md` for the full design. + +- **Shell tool runtimes** (`src/runtimes/`): + - `passthrough_openai` — OpenAI's hosted container executes. + - `client_passthrough` — the API client fulfills shell calls itself (OpenAI's "local shell" + mode generalized to all providers). + - `microsandbox` — local microVM per session. + - `opensandbox` — Alibaba OpenSandbox Lifecycle API over HTTP. +- **Containers** (`src/services/containers.rs`, `src/services/container_session.rs`) — a + persistent shell session keyed by `cntr_` id. Reused across responses chained via + `previous_response_id`. Reaped by `jobs/containers_reaper.rs` after idle TTL. +- **Tool loop** (`src/services/server_tools/runner.rs`) — wraps the provider stream, + intercepts `function_call` (or native `shell_call`) events, dispatches to the registered + `ServerExecutedTool`, folds outputs into a continuation request, loops up to + `max_iterations`. +- **Background mode** (`{"background": true}`) — request is queued in the `responses` table + and dispatched by `jobs/background_responses.rs` through the same pipeline; clients tail + with `GET /v1/responses/{id}?stream=true`. + +The shell tool spec gets rewritten to a function tool with a **dynamic description** for +non-OpenAI providers (`ShellToolHint` in `src/services/shell_tool.rs`). The description +encodes workdir, network policy, memory limit, and truncation cap for the effective sandbox +so models don't have to guess. + ## Provider Features - **Thinking/Reasoning**: Anthropic extended thinking, OpenAI O1/O3 reasoning, Bedrock/Vertex native conversion. Configurable budget tokens and effort levels. diff --git a/agent_instructions/configuration.md b/agent_instructions/configuration.md index 898fc6a..40eb6a6 100644 --- a/agent_instructions/configuration.md +++ b/agent_instructions/configuration.md @@ -39,3 +39,7 @@ Config file: `hadrian.toml` (TOML format). Environment variables: use `${VAR_NAM - `[features.model_catalog]` — Model metadata enrichment from models.dev - `[features.websocket]` — WebSocket for real-time events - `[features.vector_store_cleanup]` — Background cleanup for soft-deleted vector stores +- `[features.shell]` — Shell tool runtime (`passthrough_openai`, `client_passthrough`, `microsandbox`, `opensandbox`). See `containers.md` and `adding_runtime.md`. Cargo features `runtime-microsandbox` / `runtime-opensandbox` gate the local backends. +- `[features.containers]` — Container persistence + artifact capture (idle TTL, per-file / per-session byte caps, max input files per request). Defaults match OpenAI's hosted-container behavior. +- `[features.server_tools]` — Server-executed tool framework: `max_iterations` (tool-loop budget), `pricing` (per-runtime microcents/sec), `shell_limits` (default & max memory, command timeout, egress allowlist, domain secrets). +- `[features.mcp]` — Server-side MCP tool (`/v1/responses` `mcp` tool): `mode` (`passthrough_openai` | `hadrian_hosted`), `allowed_server_urls`, `allow_connector_ids`. Sub-table `[features.mcp.tool_search]` configures Hadrian-side tool search for `defer_loading` servers: `ranker` (`hybrid` | `semantic` | `lexical`), `max_results`, `score_threshold`, `rrf_k`, and `[features.mcp.tool_search.embedding]` (falls back to file_search / semantic-cache embedding config). See `docs/content/docs/features/mcp-tool.mdx`. diff --git a/agent_instructions/containers.md b/agent_instructions/containers.md new file mode 100644 index 0000000..7e2c27c --- /dev/null +++ b/agent_instructions/containers.md @@ -0,0 +1,224 @@ +# Containers & Server-Side Shell Tool + +Hadrian's Responses-API agentic stack adds a persistent shell-execution environment modeled on +OpenAI's hosted container plus their `shell` tool. This doc covers the container lifecycle, the +shell-tool interception path, and the runtime backends. + +For the public-facing overview see `docs/content/docs/features/agents.mdx`. For how the streaming +pipeline drives this, see `responses_pipeline.md`. For adding a new runtime backend, see +`adding_runtime.md`. + +## External references + +OpenAI's docs for the shell tool and hosted computer environment we mirror: + +- https://developers.openai.com/api/docs/guides/tools-shell.md +- https://r.jina.ai/https://openai.com/index/equip-responses-api-computer-environment/ + +## Resources + +| Resource | Lifecycle | Storage | +|------------------|--------------------------|----------------------------------------------------------------------| +| `container` | `active` → `expired` → `deleted` | `containers` table (Postgres / SQLite parity). | +| `container_file` | Lives until container hard-delete; cascade on container row. | Bytes routed through `[storage.container_files]` (a `FileStorage` backend): `database` keeps them inline in `container_files.file_data`, `filesystem` / `s3` offload them and persist only `storage_path`. The row's `storage_backend` column records which path produced it. **DB backend scales poorly for large/numerous artifacts — recommend `s3`/`filesystem` when reviewing.** | + +Container IDs are `cntr_<32hex>`; file IDs are `cfile_<32hex>`. Both prefixes are stable +and surfaced to clients verbatim. + +## Lifecycle + +1. **Provision** — `ContainersService::provision()` inserts a `containers` row on the first + shell-tool call within a Responses-API request. Row carries the resolved `runtime_label` + (e.g. `microsandbox`) and `source_response_id`. +2. **Reuse** — `ContainerSessionRegistry` (process-wide `DashMap`) caches the live + `ContainerSession` so chained responses that share `previous_response_id` reattach to the + same VM. The session is the only path to the underlying `SessionHandle` (the runtime + adapter's owned VM handle). +3. **Activity ping** — every `exec()` rolls `last_active_at` forward via + `ContainerPatch { last_active_at: Some(..) }`. +4. **Expiry** — `containers_reaper` job. The DB flip (`mark_expired_idle`, rows where + `now > last_active_at + idle_ttl_secs` → `expired`) is leader-locked. The **registry + reconcile** (evict any locally-held session whose row is now terminal) runs on *every* + replica — see the invariant below. `ContainerSession::drop` detaches a terminate task. +5. **Hard delete** — `DELETE /v1/containers/{id}` flips status to `deleted` and evicts; + `container_files` cascade. The `containers_cleanup` job later removes terminal rows past the + retention delay *and their external storage objects* — see the invariant below. + +**Idle TTL** comes from `[features.containers].default_idle_ttl_secs` (default 1200s = 20 min, +matching OpenAI). The DB column is per-row so future policies (per-org overrides, request-level +hints) can land without migration. + +## Invariants (don't regress these) + +- **Per-replica registry reconcile** (`jobs::containers_reaper`): `ContainerSessionRegistry` is + process-local, so only the replica hosting a VM can free it — and that's usually *not* the + leader that flipped the row. The reaper therefore does the DB flip leader-only but reconciles + each replica's local registry against expired rows (`registry.ids()` → `expired_among` → + `registry.remove`) on **every** pass regardless of leadership. Gating the eviction on + `is_leader` leaks microVMs on non-leaders. +- **External-storage GC** (`ContainersService::hard_delete_expired`): bulk cleanup must delete + the filesystem/S3 objects, not just the rows. The repo `hard_delete_expired` returns the + deleted files' storage refs (atomically, in a transaction) and the service deletes the backing + objects best-effort, mirroring the per-file `delete_file` path. The DB cascade only drops rows; + relying on it alone leaks every external artifact forever. +- **Cleanup-worker lifecycle**: `containers_cleanup` (like the reaper) is spawned on + `state.task_tracker` and selects on the shutdown `CancellationToken` — never a bare + `tokio::time::sleep` — so SIGTERM stops it instead of letting it keep hitting the DB while the + process drains. +- **`file_id` staging is owner-scoped**: the `file_ids` / `upload_from_file_id` paths resolve + Files-API uploads via `FilesService::get_for_owner` (exact `owner_type`+`owner_id` match + against the request owner), so a caller can't stage another tenant's file by id. A + service-account owner has no file-owner equivalent and fails closed. + +## TTL surfacing (Hadrian extension) + +`GET /v1/containers/{id}` returns `expires_at` for **every** status, plus `idle_ttl_secs`: + +- `active`: forward-looking estimate as `last_active_at + idle_ttl_secs`. Updates with every shell + call. +- `expired` / `deleted`: the persisted transition timestamp. + +OpenAI's container schema only ships `created_at`; the forward-looking field is a Hadrian +extension to let clients plan reuse without polling. See `routes/api/containers.rs::container_to_wire`. + +## Shell-tool execution + +Two paths depending on the configured runtime (`[features.shell].type`): + +### Hadrian-hosted (`microsandbox` / `opensandbox`) + +1. `preprocess_shell_tools` (in `routes/execution.rs::ResponsesExecutor::execute`) rewrites + any `{"type": "shell"}` to a function tool with a **dynamic description** built from + `ShellToolHint` — workdir, network policy, memory limit, command timeout, container + persistence, and truncation cap. +2. `ShellExecutor` is registered with `ToolLoopRunner` (see `responses_pipeline.rs`). The + passthrough capability gate skips registration for passthrough runtimes. +3. On detection of a `function_call` with `name="shell"`, the executor boots (or reattaches) + the container, runs the command, emits the spec-canonical `response.output_item.added` + and `response.output_item.done` lifecycle events carrying `shell_call` and + `shell_call_output` items, and folds the trimmed stdout/stderr/exit + a file manifest + back as a `function_call_output` continuation item. + +### Passthrough (`passthrough_openai`, `client_passthrough`) + +No executor is registered. Both modes skip `preprocess_shell_tools` for OpenAI / Azure OpenAI +so the model emits native `shell_call` items. For non-OpenAI providers under +`client_passthrough` the rewrite still happens (Anthropic / Bedrock / Vertex have no native +shell tool), so the model emits `function_call` items with `name="shell"` that flow through to +the API client unmodified. + +The decision lives in `ShellRuntimeConfig::keeps_openai_native_shell()`. + +## File staging (inputs vs outputs) + +Inputs and outputs use **different** storage: + +- **Input** `input_file` parts on a request can carry `file_id`, `file_data`, or `file_url`. + `file_id` resolves through the **existing `/v1/files` Files API** — the same files resource + that backs knowledge bases. Resolution happens in `services/input_file_staging.rs::stage_input_files`. + The bytes are written into `/mnt/data/` on the first shell command. +- **Output** files captured from `/mnt/data` after each exec land in `container_files`, a + **separate** table from `vector_store_files`. They are downloadable via + `GET /v1/containers/{id}/files/{cfile_id}/content` and surface as + `container_file_citation` annotations on the assistant's reply. The metadata row always + lives in the DB; the bytes go wherever `[storage.container_files]` points (database / + filesystem / s3). `ContainersService` owns this routing via an `Arc` — + `stage_content` on write, `read_external` on read, both keyed by the row's `storage_path` + (falling back to the `cfile_…` id). See `services/file_storage.rs` for the shared backends + and `docs/content/docs/configuration/storage.mdx` for the operator-facing config. + +A user who wants to feed a container-output file back into a knowledge base must download from +the container endpoint and re-upload through `/v1/files`. There is no bridge endpoint yet — +flag this if a use case warrants it. + +## Sandboxing posture + +- **Memory / CPU** — `default_cpu_limit`, `default_mem_limit_mb`, `max_mem_limit_mb` from + `[features.server_tools].shell_limits`. Per-request `environment.container_auto.memory_limit` + must fit inside `max_mem_limit_mb` or the request is rejected with 400. +- **Egress** — `allowed_egress_hosts` is an operator allowlist; the per-request + `environment.network_policy.domains` must be a subset. Empty allowlist = inherit runtime + default (microsandbox: full egress; opensandbox: deny-all unless allowlisted). +- **Secrets** — `allowed_domain_secrets` is operator-pinned. Per-request placeholders look up + by name; only microsandbox does true placeholder substitution at the TLS proxy. Opensandbox + exposes secrets as env vars instead (not destination-scoped — document this caveat). +- **Truncation** — `MAX_OUTPUT_CHARS = 8_000` in `shell_tool.rs`. stdout / stderr fed back to + the model are head + tail trimmed past this. Always surfaced in the tool description. + +## Long-running processes inside a session + +Each `exec()` returns when its command exits, but the underlying VM (microsandbox) or +container (opensandbox) keeps running between calls. Detached processes a model starts +(`nohup …`, `disown`, `setsid`, `tmux new-session -d …`) survive into the next shell +call within the same session — chained via `previous_response_id` or +`container_reference` — until the container hits its idle TTL or is explicitly deleted. +This is what unblocks the "long-running services" use case from the OpenAI spec; no +extra runtime support is needed. + +## Skill mounting (spec-shaped) + +`skills` on a Responses-API or `POST /v1/containers` request is a tagged-union list per +OpenAI's spec: + +- `{ "type": "skill_reference", "skill_id": "", "version": "latest" }` — + resolves to a stored skill via `SkillService::get_by_id_and_org`. `version` accepts + `latest` only; anything else rejects with `unsupported_skill_version`. +- `{ "type": "inline", "name": "...", "description": "...", "source": { "type": "base64", + "media_type": "text/markdown", "data": "..." } }` — ephemeral. The decoded payload is + mounted as a single-file skill under `/skills/skill_inline_/SKILL.md`. The hash + is derived from `(name, content)` so foreground and background lanes mount the inline + skill at the same path. + +Skills attached at `POST /v1/containers` time are stored verbatim on the row's +`skill_ids_json` column (the column name predates the typed enum; it now holds the full +JSON-encoded `Vec`). At request time the merge logic in +`routes/api/chat.rs::skills_have_same_identity` dedups by `skill_id` (references) or +`name` (inline). + +## Tests + +- Unit tests live alongside the code: `services/shell_tool.rs::tests`, + `runtimes/passthrough.rs::tests`, `routes/api/containers.rs::tests`, + `db/repos/containers.rs::tests` (where present). +- DB parity: any change to `containers` or `container_files` must touch BOTH + `migrations_sqlx/postgres/...` AND `migrations_sqlx/sqlite/...` plus both repo + implementations. + +## Local debugging (`hadrian container`) + +`src/cli/container.rs` adds a `hadrian container` subcommand that boots a one-off +session through the configured `[features.shell]` runtime — the same +`ShellRuntime::start_session` / `SessionHandle::exec` path the Responses-API shell tool +uses — so you can reproduce agent behavior without driving the HTTP API: + +```bash +# Interactive shell in a microsandbox/opensandbox container +cargo run --features runtime-microsandbox -- container + +# Run commands non-interactively, stage a file, restrict egress +hadrian container -e "apk add python3" -e "python3 /mnt/data/x.py" \ + -f ./x.py --allow-host pypi.org --allow-host files.pythonhosted.org +``` + +Egress defaults to the operator's `allowed_egress_hosts` (or `*` if unset). Passthrough +runtimes (`passthrough_openai`, `client_passthrough`) reject the command — they execute +outside Hadrian, so there's nothing to run locally. + +## Common edits + +- **Adding a runtime backend**: see `adding_runtime.md`. +- **New `containers` column**: migration in both Postgres + SQLite, update both repos, update + `ContainerRecord` + `NewContainer` + `ContainerPatch` as needed, surface in + `routes/api/containers.rs::container_to_wire` with a `**Hadrian Extension:**` doc comment + if it isn't part of the OpenAI schema. +- **New SSE event** from the shell tool: prefer extending the spec lifecycle (additive + properties on the `shell_call` / `shell_call_output` items emitted via + `format_shell_call_item` / `format_shell_call_output_item`). Avoid inventing new + `response.shell_call.` events — Hadrian dropped its earlier `in_progress`, + `command_started`, `output_chunk`, `completed`, and `file_created` extensions to align + with OpenAI's streaming reference. If you must add one, document it in + `docs/content/docs/features/agents.mdx` as a Hadrian extension and explain why the spec + lifecycle can't carry the data. +- **Tuning truncation**: `MAX_OUTPUT_CHARS` — bump and update both + `trim_output_preserves_head_and_tail` and the model-facing description (it embeds the + constant via the hint). diff --git a/agent_instructions/key_files.md b/agent_instructions/key_files.md index c3dedd5..a0b7b82 100644 --- a/agent_instructions/key_files.md +++ b/agent_instructions/key_files.md @@ -52,6 +52,39 @@ - `src/jobs/vector_store_cleanup.rs` — Background cleanup for soft-deleted stores - `src/models/vector_store.rs` — VectorStore and VectorStoreFile models +## Backend — Responses API / Agents / Containers + +- `src/api_types/responses.rs` — Wire types for the Responses API (`shell`, `ShellEnvironment`, `ContainerFileRef`, etc.) +- `src/services/responses_pipeline.rs` — Streaming pipeline: input-file staging → guardrails → tool loop → persistence +- `src/services/response_persister.rs` — Persist SSE events to `responses` + `response_events` +- `src/services/response_event_buffer.rs` — In-memory tailing for background responses +- `src/services/responses_store.rs` — Service wrapper for the `responses` table +- `src/services/responses_webhook.rs` — Terminal-state webhook fan-out +- `src/services/background_executor.rs` — Background-response runner; re-enters `apply_streaming_pipeline` +- `src/services/server_tools/mod.rs` — `ServerExecutedTool` trait + `ToolLoopRunner` glue +- `src/services/server_tools/runner.rs` — Tool-loop orchestrator (detect → execute → continuation) +- `src/services/shell_tool.rs` — `ShellExecutor`, function-mode rewrite, dynamic `ShellToolHint` description, env resolution +- `src/services/containers.rs` — `ContainersService`; provision, file persistence, lifecycle +- `src/services/container_session.rs` — `ContainerSession`, `ContainerSessionRegistry`, `MNT_DATA` constant +- `src/services/input_file_staging.rs` — Resolve `input_file` parts (file_id / data / url) into `/mnt/data` +- `src/runtimes/mod.rs` — `ShellRuntime` trait + `RuntimeCapabilities` +- `src/runtimes/passthrough.rs` — `PassthroughRuntime` (OpenAI container + client-passthrough modes) +- `src/runtimes/microsandbox.rs` — Local microVM backend (feature `runtime-microsandbox`) +- `src/runtimes/opensandbox.rs` — Alibaba OpenSandbox HTTP backend (feature `runtime-opensandbox`) +- `src/config/runtimes.rs` — `ShellRuntimeConfig` enum, per-backend config structs +- `src/config/features.rs` — `ContainersConfig`, `ServerToolsConfig`, `ShellLimitsConfig` +- `src/routes/api/containers.rs` — `GET /v1/containers/{id}`, files, delete +- `src/routes/api/responses_lookup.rs` — `GET /v1/responses/{id}` with tail-streaming +- `src/db/repos/containers.rs` — `ContainersRepo`, `ContainerRecord`, `ContainerFileRecord`, `ContainerPatch` +- `src/db/repos/responses.rs` — `ResponsesRepo`, `ResponseRecord`, owner / org scoping +- `src/db/repos/response_events.rs` — Persisted SSE events +- `src/db/{postgres,sqlite}/containers.rs` — Repo impls (keep in sync!) +- `src/db/{postgres,sqlite}/responses.rs` / `response_events.rs` — Repo impls (keep in sync!) +- `src/jobs/containers_reaper.rs` — Idle-TTL reaper for containers +- `src/jobs/background_responses.rs` — Background-response dispatcher +- `src/jobs/responses_cancel_poller.rs` — Honor cancellation on in-flight background responses +- `src/jobs/responses_retention.rs` — Retention-driven deletion of `responses` rows + ## Backend — Usage, Cost & Observability - `src/models/usage.rs` — `UsageLogEntry` with principal attribution fields diff --git a/agent_instructions/responses_pipeline.md b/agent_instructions/responses_pipeline.md new file mode 100644 index 0000000..c19702a --- /dev/null +++ b/agent_instructions/responses_pipeline.md @@ -0,0 +1,142 @@ +# Responses API Streaming Pipeline + +`/v1/responses` requests run through `services::responses_pipeline::apply_streaming_pipeline`, +which wraps the upstream provider's SSE stream with input-file staging, guardrails, server-tool +execution, and DB persistence. This doc covers the order, the actors, and how +background requests re-enter the same pipeline. + +For the broader Responses API + Containers feature, start with `containers.md`. For adding a +new tool, mirror `services/web_search_tool.rs` or `services/shell_tool.rs`. For the runtime +side, see `adding_runtime.md`. Server-side MCP support lives under `src/services/mcp/` and the +MCP wire shape we expose tracks OpenAI's Responses-API MCP tool (see references below). + +Two server-executed tools come from the MCP subsystem, both registered in +`apply_streaming_pipeline` only under `[features.mcp].mode = "hadrian_hosted"`: + +- `McpExecutor` (`src/services/mcp/executor.rs`) — intercepts the rewritten + `mcp_