diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml new file mode 100644 index 0000000..a58faf7 --- /dev/null +++ b/.github/workflows/packages.yml @@ -0,0 +1,131 @@ +name: Packages + +on: + push: + branches: + - main + paths: + - "proto/**" + - "packages/**" + - "tools/rust-codegen/**" + - "scripts/**" + - "Cargo.toml" + - "Cargo.lock" + - ".github/workflows/packages.yml" + - ".github/workflows/release.yml" + pull_request: + paths: + - "proto/**" + - "packages/**" + - "tools/rust-codegen/**" + - "scripts/**" + - "Cargo.toml" + - "Cargo.lock" + - ".github/workflows/packages.yml" + - ".github/workflows/release.yml" + +permissions: + contents: read + +jobs: + generated: + name: Generated bindings + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.14" + + - name: Set up Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + + - name: Install Python generator + run: python -m pip install grpcio-tools==1.81.1 + + - name: Check generated bindings + run: ./scripts/check-generated.sh + + python: + name: Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.10", "3.14"] + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + + - name: Install build tools + run: python -m pip install build==1.3.0 twine==6.2.0 + + - name: Build distributions + run: python -m build packages/python --outdir dist/python + + - name: Check distribution metadata + run: python -m twine check dist/python/* + + - name: Install wheel + run: python -m pip install dist/python/*.whl + + - name: Test installed bindings + run: python -m unittest discover --start-directory packages/python/tests + + rust: + name: Rust ${{ matrix.toolchain }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + toolchain: ["1.88.0", "stable"] + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Set up Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + + - name: Test crate + run: cargo test --locked --package openengine-proto + + - name: Build publishable crate + run: cargo package --locked --package openengine-proto + + - name: List packaged files + run: cargo package --locked --package openengine-proto --list + + interoperability: + name: Python and Rust interoperability + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.14" + + - name: Set up Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + + - name: Install Python package + run: python -m pip install ./packages/python + + - name: Test both serialization directions + run: ./scripts/test-cross-language.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..fb4bdc3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,155 @@ +name: Release + +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+" + +permissions: + contents: read + +jobs: + build: + name: Build and verify release + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.14" + + - name: Set up Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + + - name: Check release versions + run: python scripts/check_release_version.py "${GITHUB_REF_NAME}" + + - name: Lint schema + uses: bufbuild/buf-action@v1 + with: + version: "1.71.0" + lint: true + format: false + breaking: false + push: false + archive: false + pr_comment: false + + - name: Install Python tools + run: >- + python -m pip install + build==1.3.0 + grpcio-tools==1.81.1 + twine==6.2.0 + + - name: Check generated bindings + run: ./scripts/check-generated.sh + + - name: Test Rust crate + run: cargo test --locked --package openengine-proto + + - name: Build Rust crate + run: cargo package --locked --package openengine-proto + + - name: Build Python distributions + run: python -m build packages/python --outdir dist/python + + - name: Check Python distributions + run: python -m twine check dist/python/* + + - name: Install and test Python wheel + run: | + python -m pip install dist/python/*.whl + python -m unittest discover --start-directory packages/python/tests + + - name: Test cross-language serialization + run: ./scripts/test-cross-language.sh + + - name: Assemble release artifacts + run: | + mkdir -p dist/release + cp dist/python/* dist/release/ + cp target/package/openengine-proto-*.crate dist/release/ + cp packages/rust/openengine-proto/src/generated/openengine_descriptor.bin \ + "dist/release/openengine-${GITHUB_REF_NAME}-descriptor.bin" + tar --create --gzip \ + --file "dist/release/openengine-${GITHUB_REF_NAME}-proto.tar.gz" \ + --directory proto \ + openengine + cd dist/release + sha256sum openengine* > SHA256SUMS + + - name: Upload release artifacts + uses: actions/upload-artifact@v4 + with: + name: openengine-${{ github.ref_name }} + path: dist + if-no-files-found: error + + publish-python: + name: Publish Python package + needs: build + runs-on: ubuntu-latest + environment: release + permissions: + actions: read + contents: read + id-token: write + steps: + - name: Download release artifacts + uses: actions/download-artifact@v4 + with: + name: openengine-${{ github.ref_name }} + path: dist + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist/python + + publish-rust: + name: Publish Rust crate + needs: build + runs-on: ubuntu-latest + environment: release + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Set up Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + + - name: Publish to crates.io + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish --locked --package openengine-proto + + github-release: + name: Create GitHub release + needs: [publish-python, publish-rust] + runs-on: ubuntu-latest + permissions: + actions: read + contents: write + steps: + - name: Download release artifacts + uses: actions/download-artifact@v4 + with: + name: openengine-${{ github.ref_name }} + path: dist + + - name: Create release + env: + GH_TOKEN: ${{ github.token }} + run: >- + gh release create "${GITHUB_REF_NAME}" + dist/release/* + --generate-notes + --title "OpenEngine ${GITHUB_REF_NAME}" diff --git a/.gitignore b/.gitignore index ed1af5a..a681dea 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,10 @@ __pycache__/ *.py[cod] -# Ignore generated Python gRPC stubs if the README example is run locally. -*_pb2.py -*_pb2_grpc.py +# Local Python environments and package artifacts +.venv/ +*.egg-info/ +dist/ + +# Rust build artifacts +target/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6d01c76 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ + + +# Changelog + +All notable changes to the OpenEngine schema and generated packages are +documented here. OpenEngine uses the same version for its Git tag, Python +distribution, and Rust crate. + +## [Unreleased] + +### Added + +- Generated Python protobuf and gRPC bindings. +- Generated Rust Prost and Tonic client/server bindings. +- Reproducible code generation, package CI, and tag-driven releases. + +[Unreleased]: https://github.com/ai-dynamo/openengine/commits/main diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 85ece56..1050dfb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,32 @@ sending a PR. - **Bugs / feedback / design questions**: open a [GitHub issue](https://github.com/ai-dynamo/openengine/issues). - **Pull requests**: open against `main`. Keep changes focused (one logical change per PR). -## Signing Your Work +## Development checks + +The schema under `proto/openengine/v1/` is the source of truth. Generated Python +and Rust bindings are checked in for package consumers and must be updated in +the same pull request as a schema change. + +```bash +buf build +buf lint + +python -m pip install grpcio-tools==1.81.1 +./scripts/generate-python.sh +./scripts/generate-rust.sh +./scripts/check-generated.sh + +cargo test --locked --package openengine-proto +cargo package --locked --package openengine-proto +python -m build packages/python --outdir dist/python +python -m twine check dist/python/* +./scripts/test-cross-language.sh +``` + +The Python generator and Rust code-generation toolchain are pinned. Do not edit +generated files by hand; update the schema or generator and regenerate them. + +## Signing your work We require that all contributors "sign off" on their commits. This certifies that you wrote the contribution, or otherwise have the right to submit it under the diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..51c63bc --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,996 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "axum" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" +dependencies = [ + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + +[[package]] +name = "h2" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "http" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "libc", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mio" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "openengine-proto" +version = "0.1.0" +dependencies = [ + "prost", + "prost-types", + "tonic", + "tonic-prost", +] + +[[package]] +name = "openengine-rust-codegen" +version = "0.0.0" +dependencies = [ + "protoc-bin-vendored", + "tonic-prost-build", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.5", + "indexmap", +] + +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" +dependencies = [ + "heck", + "itertools", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "pulldown-cmark", + "pulldown-cmark-to-cmark", + "regex", + "syn", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" +dependencies = [ + "prost", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-s390_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-aarch_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c" + +[[package]] +name = "protoc-bin-vendored-linux-s390_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78" + +[[package]] +name = "protoc-bin-vendored-macos-aarch_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3" + +[[package]] +name = "pulldown-cmark" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + +[[package]] +name = "pulldown-cmark-to-cmark" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90" +dependencies = [ + "pulldown-cmark", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "regex" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "socket2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tonic" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" +dependencies = [ + "async-trait", + "axum", + "base64", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "socket2", + "sync_wrapper", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tonic-prost" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" +dependencies = [ + "bytes", + "prost", + "tonic", +] + +[[package]] +name = "tonic-prost-build" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn", + "tempfile", + "tonic-build", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project-lite", + "slab", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..eb92e3c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[workspace] +members = [ + "packages/rust/openengine-proto", + "tools/rust-codegen", +] +resolver = "2" + +[workspace.package] +version = "0.1.0" +edition = "2021" +rust-version = "1.88" +license = "Apache-2.0" +repository = "https://github.com/ai-dynamo/openengine" diff --git a/README.md b/README.md index aadc6fc..f866df0 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ SPDX-License-Identifier: Apache-2.0 Why OpenEngine? · API reference · Canonical schema + · Generated packages · Contributing

@@ -43,6 +44,7 @@ SPDX-License-Identifier: Apache-2.0 - [Architecture](#architecture) - [Capabilities](#capabilities) - [Getting started](#getting-started) +- [Generated packages](#generated-packages) - [Project status](#project-status) - [Contributing](#contributing) - [Security](#security) @@ -134,31 +136,68 @@ buf lint Buf lint, Markdown lint, and link checks run in GitHub Actions for relevant pull requests. -### Generate Python bindings +### Regenerate package bindings -Use a proto3 toolchain with explicit-optional support (`protoc` 3.15 or newer). -The contract imports protobuf well-known types, so their include path must be -available to the compiler. +The repository checks in generated Python and Rust bindings so that package +users do not need a protobuf compiler. Contributors changing the schema must +regenerate both packages: ```bash -python -m pip install grpcio-tools +python -m pip install grpcio-tools==1.81.1 +./scripts/generate-python.sh +./scripts/generate-rust.sh +./scripts/check-generated.sh +``` + +Other protobuf-supported languages can generate clients and servers from the +same canonical package. + +## Generated packages -OUT_DIR=/tmp/openengine-python -mkdir -p "$OUT_DIR" +Each OpenEngine release publishes Python and Rust bindings from the same schema +and version tag. The artifacts contain generated code; installing them does not +run Buf or `protoc`. -PROTO_INCLUDE=$(python -c \ - 'import grpc_tools, os; print(os.path.join(os.path.dirname(grpc_tools.__file__), "_proto"))') +### Python -python -m grpc_tools.protoc \ - -I proto \ - -I "$PROTO_INCLUDE" \ - --python_out="$OUT_DIR" \ - --grpc_python_out="$OUT_DIR" \ - proto/openengine/v1/*.proto +```bash +pip install openengine-proto ``` -Other protobuf-supported languages can generate clients and servers from the -same canonical package. +```python +import grpc + +from openengine.v1.generation_pb2 import GenerateRequest +from openengine.v1.openengine_pb2_grpc import OpenEngineStub + +channel = grpc.aio.insecure_channel("localhost:50051") +engine = OpenEngineStub(channel) +request = GenerateRequest(request_id="example", model="model", prompt="Hello") +``` + +### Rust + +```bash +cargo add openengine-proto +``` + +```rust +use openengine_proto::openengine::v1::{ + open_engine_client::OpenEngineClient, + GenerateRequest, +}; +``` + +The package version is the immutable `schema_release` identifier. Both packages +also expose schema revision `1`; a client should still inspect `EngineInfo` to +determine the revision and compatibility advertised by a running engine. + +| Package release | Protobuf package | Schema revision | +| --------------- | ---------------- | --------------- | +| `0.1.x` | `openengine.v1` | `1` | + +See [`RELEASING.md`](RELEASING.md) for the coordinated release process and +[`CHANGELOG.md`](CHANGELOG.md) for schema and package changes. ## Project status @@ -189,7 +228,8 @@ git commit --signoff -m "docs: describe the change" Please validate protobuf changes with Buf and keep [`proto/openengine/v1/`](proto/openengine/v1/) and [`docs/api.md`](docs/api.md) -synchronized. +synchronized. Changes to the schema must also regenerate and commit both +language packages. ## Security diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..96d7f27 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,75 @@ + + +# Releasing OpenEngine + +OpenEngine publishes the canonical schema and generated Python and Rust +bindings from the same `vMAJOR.MINOR.PATCH` tag. Releases are immutable and all +published artifacts must use the same version. + +## One-time repository configuration + +Before the first release: + +1. Register `openengine-proto` on PyPI and crates.io. +2. Configure a PyPI Trusted Publisher for the `Release` workflow, the + `publish-python` job, and the `release` GitHub environment. +3. Add a crates.io publishing token as the `CARGO_REGISTRY_TOKEN` environment + secret. +4. Protect the `release` GitHub environment with the desired approval policy. +5. Add the appropriate project owners on both registries. + +The PyPI job uses OpenID Connect and does not require a stored PyPI token. + +## Prepare a release + +1. Choose the release version and update both version declarations: + - `packages/python/pyproject.toml` under `[project]`. + - `Cargo.toml` under `[workspace.package]`. +2. Move the relevant entries from `Unreleased` in `CHANGELOG.md` into a section + named for the version and release date. +3. Install the pinned Python generator and regenerate bindings: + + ```bash + python -m pip install grpcio-tools==1.81.1 + ./scripts/generate-python.sh + ./scripts/generate-rust.sh + ``` + +4. Run the package checks: + + ```bash + ./scripts/check-generated.sh + cargo test --locked --package openengine-proto + cargo package --locked --package openengine-proto + python -m build packages/python --outdir dist/python + python -m twine check dist/python/* + ./scripts/test-cross-language.sh + ``` + +5. Open and merge the release-preparation pull request. + +## Publish + +Create and push a signed tag from the release commit: + +```bash +python scripts/check_release_version.py v0.1.0 +git tag --sign v0.1.0 -m "OpenEngine v0.1.0" +git push origin v0.1.0 +``` + +The `Release` workflow validates the schema, regenerates and tests both +packages, publishes them, and creates a GitHub release containing: + +- The Python wheel and source distribution. +- The packaged Rust crate. +- The canonical proto source archive. +- The complete protobuf descriptor set. +- SHA-256 checksums. + +If publication fails after one registry accepts a package, do not overwrite or +delete that artifact. Fix the workflow and rerun only if the remaining steps +are safe, or prepare a new patch release. diff --git a/packages/python/README.md b/packages/python/README.md new file mode 100644 index 0000000..6d6a089 --- /dev/null +++ b/packages/python/README.md @@ -0,0 +1,28 @@ + + +# OpenEngine Python bindings + +Generated protobuf messages and gRPC client/server bindings for the +[`openengine.v1`](https://github.com/ai-dynamo/openengine/tree/main/proto/openengine/v1) +protocol. + +```bash +pip install openengine-proto +``` + +```python +import grpc + +from openengine.v1.generation_pb2 import GenerateRequest +from openengine.v1.openengine_pb2_grpc import OpenEngineStub + +channel = grpc.aio.insecure_channel("localhost:50051") +engine = OpenEngineStub(channel) +request = GenerateRequest(request_id="example", model="model", prompt="Hello") +``` + +The package contains generated code. Applications do not need Buf, `protoc`, +or `grpcio-tools`. diff --git a/packages/python/pyproject.toml b/packages/python/pyproject.toml new file mode 100644 index 0000000..830f4cb --- /dev/null +++ b/packages/python/pyproject.toml @@ -0,0 +1,39 @@ +[build-system] +requires = ["hatchling>=1.27,<2"] +build-backend = "hatchling.build" + +[project] +name = "openengine-proto" +version = "0.1.0" +description = "Generated Python bindings for the OpenEngine gRPC protocol" +readme = "README.md" +requires-python = ">=3.10" +license = "Apache-2.0" +authors = [{ name = "OpenEngine contributors" }] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development :: Libraries", + "Topic :: System :: Distributed Computing", +] +dependencies = [ + "grpcio>=1.81.1,<2", + "protobuf>=6.33.5,<8", +] + +[project.urls] +Documentation = "https://github.com/ai-dynamo/openengine/tree/main/docs" +Issues = "https://github.com/ai-dynamo/openengine/issues" +Repository = "https://github.com/ai-dynamo/openengine" + +[tool.hatch.build.targets.sdist] +include = [ + "/README.md", + "/pyproject.toml", + "/src", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/openengine"] diff --git a/packages/python/src/openengine/__init__.py b/packages/python/src/openengine/__init__.py new file mode 100644 index 0000000..3dc6063 --- /dev/null +++ b/packages/python/src/openengine/__init__.py @@ -0,0 +1,15 @@ +"""Generated Python bindings for the OpenEngine protocol.""" + +from importlib.metadata import PackageNotFoundError, version + +try: + __version__ = version("openengine-proto") +except PackageNotFoundError: + __version__ = "0.0.0+local" + +SCHEMA_REVISION = 1 +SCHEMA_RELEASE = ( + "unreleased" if __version__ == "0.0.0+local" else f"v{__version__}" +) + +__all__ = ["SCHEMA_RELEASE", "SCHEMA_REVISION", "__version__"] diff --git a/packages/python/src/openengine/py.typed b/packages/python/src/openengine/py.typed new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/packages/python/src/openengine/py.typed @@ -0,0 +1 @@ + diff --git a/packages/python/src/openengine/v1/__init__.py b/packages/python/src/openengine/v1/__init__.py new file mode 100644 index 0000000..32b0339 --- /dev/null +++ b/packages/python/src/openengine/v1/__init__.py @@ -0,0 +1 @@ +"""The generated ``openengine.v1`` protobuf package.""" diff --git a/packages/python/src/openengine/v1/engine_pb2.py b/packages/python/src/openengine/v1/engine_pb2.py new file mode 100644 index 0000000..30df65b --- /dev/null +++ b/packages/python/src/openengine/v1/engine_pb2.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/engine.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/engine.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from openengine.v1 import kv_pb2 as openengine_dot_v1_dot_kv__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1aopenengine/v1/engine.proto\x12\ropenengine.v1\x1a\x16openengine/v1/kv.proto\"\x16\n\x14GetEngineInfoRequest\"\xce\x02\n\nEngineInfo\x12\x13\n\x0b\x65ngine_name\x18\x01 \x01(\t\x12\x16\n\x0e\x65ngine_version\x18\x02 \x01(\t\x12\'\n\x04role\x18\x03 \x01(\x0e\x32\x19.openengine.v1.EngineRole\x12\x13\n\x0binstance_id\x18\x04 \x01(\t\x12\x18\n\x10supported_models\x18\x05 \x03(\t\x12\x33\n\x0bparallelism\x18\x06 \x01(\x0b\x32\x1e.openengine.v1.ParallelismInfo\x12\x34\n\x0ckv_connector\x18\x07 \x01(\x0b\x32\x1e.openengine.v1.KvConnectorInfo\x12\x17\n\x0fschema_revision\x18\x08 \x01(\r\x12\x1f\n\x17minimum_client_revision\x18\t \x01(\r\x12\x16\n\x0eschema_release\x18\n \x01(\t\"\xc1\x02\n\x0fParallelismInfo\x12!\n\x14tensor_parallel_size\x18\x01 \x01(\rH\x00\x88\x01\x01\x12#\n\x16pipeline_parallel_size\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1f\n\x12\x64\x61ta_parallel_size\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12\x64\x61ta_parallel_rank\x18\x04 \x01(\rH\x03\x88\x01\x01\x12%\n\x18\x64\x61ta_parallel_start_rank\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x17\n\x15_tensor_parallel_sizeB\x19\n\x17_pipeline_parallel_sizeB\x15\n\x13_data_parallel_sizeB\x15\n\x13_data_parallel_rankB\x1b\n\x19_data_parallel_start_rank*v\n\nEngineRole\x12\x1b\n\x17\x45NGINE_ROLE_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x45NGINE_ROLE_AGGREGATED\x10\x01\x12\x17\n\x13\x45NGINE_ROLE_PREFILL\x10\x02\x12\x16\n\x12\x45NGINE_ROLE_DECODE\x10\x03\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.engine_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_ENGINEROLE']._serialized_start=754 + _globals['_ENGINEROLE']._serialized_end=872 + _globals['_GETENGINEINFOREQUEST']._serialized_start=69 + _globals['_GETENGINEINFOREQUEST']._serialized_end=91 + _globals['_ENGINEINFO']._serialized_start=94 + _globals['_ENGINEINFO']._serialized_end=428 + _globals['_PARALLELISMINFO']._serialized_start=431 + _globals['_PARALLELISMINFO']._serialized_end=752 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/engine_pb2.pyi b/packages/python/src/openengine/v1/engine_pb2.pyi new file mode 100644 index 0000000..e07e53b --- /dev/null +++ b/packages/python/src/openengine/v1/engine_pb2.pyi @@ -0,0 +1,62 @@ +from openengine.v1 import kv_pb2 as _kv_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class EngineRole(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + ENGINE_ROLE_UNSPECIFIED: _ClassVar[EngineRole] + ENGINE_ROLE_AGGREGATED: _ClassVar[EngineRole] + ENGINE_ROLE_PREFILL: _ClassVar[EngineRole] + ENGINE_ROLE_DECODE: _ClassVar[EngineRole] +ENGINE_ROLE_UNSPECIFIED: EngineRole +ENGINE_ROLE_AGGREGATED: EngineRole +ENGINE_ROLE_PREFILL: EngineRole +ENGINE_ROLE_DECODE: EngineRole + +class GetEngineInfoRequest(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class EngineInfo(_message.Message): + __slots__ = ("engine_name", "engine_version", "role", "instance_id", "supported_models", "parallelism", "kv_connector", "schema_revision", "minimum_client_revision", "schema_release") + ENGINE_NAME_FIELD_NUMBER: _ClassVar[int] + ENGINE_VERSION_FIELD_NUMBER: _ClassVar[int] + ROLE_FIELD_NUMBER: _ClassVar[int] + INSTANCE_ID_FIELD_NUMBER: _ClassVar[int] + SUPPORTED_MODELS_FIELD_NUMBER: _ClassVar[int] + PARALLELISM_FIELD_NUMBER: _ClassVar[int] + KV_CONNECTOR_FIELD_NUMBER: _ClassVar[int] + SCHEMA_REVISION_FIELD_NUMBER: _ClassVar[int] + MINIMUM_CLIENT_REVISION_FIELD_NUMBER: _ClassVar[int] + SCHEMA_RELEASE_FIELD_NUMBER: _ClassVar[int] + engine_name: str + engine_version: str + role: EngineRole + instance_id: str + supported_models: _containers.RepeatedScalarFieldContainer[str] + parallelism: ParallelismInfo + kv_connector: _kv_pb2.KvConnectorInfo + schema_revision: int + minimum_client_revision: int + schema_release: str + def __init__(self, engine_name: _Optional[str] = ..., engine_version: _Optional[str] = ..., role: _Optional[_Union[EngineRole, str]] = ..., instance_id: _Optional[str] = ..., supported_models: _Optional[_Iterable[str]] = ..., parallelism: _Optional[_Union[ParallelismInfo, _Mapping]] = ..., kv_connector: _Optional[_Union[_kv_pb2.KvConnectorInfo, _Mapping]] = ..., schema_revision: _Optional[int] = ..., minimum_client_revision: _Optional[int] = ..., schema_release: _Optional[str] = ...) -> None: ... + +class ParallelismInfo(_message.Message): + __slots__ = ("tensor_parallel_size", "pipeline_parallel_size", "data_parallel_size", "data_parallel_rank", "data_parallel_start_rank") + TENSOR_PARALLEL_SIZE_FIELD_NUMBER: _ClassVar[int] + PIPELINE_PARALLEL_SIZE_FIELD_NUMBER: _ClassVar[int] + DATA_PARALLEL_SIZE_FIELD_NUMBER: _ClassVar[int] + DATA_PARALLEL_RANK_FIELD_NUMBER: _ClassVar[int] + DATA_PARALLEL_START_RANK_FIELD_NUMBER: _ClassVar[int] + tensor_parallel_size: int + pipeline_parallel_size: int + data_parallel_size: int + data_parallel_rank: int + data_parallel_start_rank: int + def __init__(self, tensor_parallel_size: _Optional[int] = ..., pipeline_parallel_size: _Optional[int] = ..., data_parallel_size: _Optional[int] = ..., data_parallel_rank: _Optional[int] = ..., data_parallel_start_rank: _Optional[int] = ...) -> None: ... diff --git a/packages/python/src/openengine/v1/error_pb2.py b/packages/python/src/openengine/v1/error_pb2.py new file mode 100644 index 0000000..907d15a --- /dev/null +++ b/packages/python/src/openengine/v1/error_pb2.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/error.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/error.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19openengine/v1/error.proto\x12\ropenengine.v1\x1a\x1cgoogle/protobuf/struct.proto\"\xb3\x01\n\x0b\x45ngineError\x12&\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x18.openengine.v1.ErrorCode\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x11\n\tretryable\x18\x03 \x01(\x08\x12\x1b\n\x0eretry_after_ms\x18\x04 \x01(\x04H\x00\x88\x01\x01\x12(\n\x07\x64\x65tails\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructB\x11\n\x0f_retry_after_ms*\x9d\x03\n\tErrorCode\x12\x1a\n\x16\x45RROR_CODE_UNSPECIFIED\x10\x00\x12\x1f\n\x1b\x45RROR_CODE_INVALID_ARGUMENT\x10\x01\x12\"\n\x1e\x45RROR_CODE_UNSUPPORTED_FEATURE\x10\x02\x12\x1c\n\x18\x45RROR_CODE_ROLE_MISMATCH\x10\x03\x12\x1e\n\x1a\x45RROR_CODE_MODEL_NOT_FOUND\x10\x04\x12\x19\n\x15\x45RROR_CODE_OVERLOADED\x10\x05\x12 \n\x1c\x45RROR_CODE_REQUEST_NOT_FOUND\x10\x06\x12 \n\x1c\x45RROR_CODE_DUPLICATE_REQUEST\x10\x07\x12#\n\x1f\x45RROR_CODE_KV_SESSION_NOT_FOUND\x10\x08\x12!\n\x1d\x45RROR_CODE_KV_TRANSFER_FAILED\x10\t\x12\x18\n\x14\x45RROR_CODE_CANCELLED\x10\n\x12\x17\n\x13\x45RROR_CODE_DRAINING\x10\x0b\x12\x17\n\x13\x45RROR_CODE_INTERNAL\x10\x0c\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.error_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_ERRORCODE']._serialized_start=257 + _globals['_ERRORCODE']._serialized_end=670 + _globals['_ENGINEERROR']._serialized_start=75 + _globals['_ENGINEERROR']._serialized_end=254 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/error_pb2.pyi b/packages/python/src/openengine/v1/error_pb2.pyi new file mode 100644 index 0000000..4933b85 --- /dev/null +++ b/packages/python/src/openengine/v1/error_pb2.pyi @@ -0,0 +1,51 @@ +from google.protobuf import struct_pb2 as _struct_pb2 +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class ErrorCode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + ERROR_CODE_UNSPECIFIED: _ClassVar[ErrorCode] + ERROR_CODE_INVALID_ARGUMENT: _ClassVar[ErrorCode] + ERROR_CODE_UNSUPPORTED_FEATURE: _ClassVar[ErrorCode] + ERROR_CODE_ROLE_MISMATCH: _ClassVar[ErrorCode] + ERROR_CODE_MODEL_NOT_FOUND: _ClassVar[ErrorCode] + ERROR_CODE_OVERLOADED: _ClassVar[ErrorCode] + ERROR_CODE_REQUEST_NOT_FOUND: _ClassVar[ErrorCode] + ERROR_CODE_DUPLICATE_REQUEST: _ClassVar[ErrorCode] + ERROR_CODE_KV_SESSION_NOT_FOUND: _ClassVar[ErrorCode] + ERROR_CODE_KV_TRANSFER_FAILED: _ClassVar[ErrorCode] + ERROR_CODE_CANCELLED: _ClassVar[ErrorCode] + ERROR_CODE_DRAINING: _ClassVar[ErrorCode] + ERROR_CODE_INTERNAL: _ClassVar[ErrorCode] +ERROR_CODE_UNSPECIFIED: ErrorCode +ERROR_CODE_INVALID_ARGUMENT: ErrorCode +ERROR_CODE_UNSUPPORTED_FEATURE: ErrorCode +ERROR_CODE_ROLE_MISMATCH: ErrorCode +ERROR_CODE_MODEL_NOT_FOUND: ErrorCode +ERROR_CODE_OVERLOADED: ErrorCode +ERROR_CODE_REQUEST_NOT_FOUND: ErrorCode +ERROR_CODE_DUPLICATE_REQUEST: ErrorCode +ERROR_CODE_KV_SESSION_NOT_FOUND: ErrorCode +ERROR_CODE_KV_TRANSFER_FAILED: ErrorCode +ERROR_CODE_CANCELLED: ErrorCode +ERROR_CODE_DRAINING: ErrorCode +ERROR_CODE_INTERNAL: ErrorCode + +class EngineError(_message.Message): + __slots__ = ("code", "message", "retryable", "retry_after_ms", "details") + CODE_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + RETRYABLE_FIELD_NUMBER: _ClassVar[int] + RETRY_AFTER_MS_FIELD_NUMBER: _ClassVar[int] + DETAILS_FIELD_NUMBER: _ClassVar[int] + code: ErrorCode + message: str + retryable: bool + retry_after_ms: int + details: _struct_pb2.Struct + def __init__(self, code: _Optional[_Union[ErrorCode, str]] = ..., message: _Optional[str] = ..., retryable: _Optional[bool] = ..., retry_after_ms: _Optional[int] = ..., details: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ... diff --git a/packages/python/src/openengine/v1/generation_params_pb2.py b/packages/python/src/openengine/v1/generation_params_pb2.py new file mode 100644 index 0000000..c0ac8c6 --- /dev/null +++ b/packages/python/src/openengine/v1/generation_params_pb2.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/generation_params.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/generation_params.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from openengine.v1 import kv_pb2 as openengine_dot_v1_dot_kv__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%openengine/v1/generation_params.proto\x12\ropenengine.v1\x1a\x16openengine/v1/kv.proto\"\x17\n\x08TokenIds\x12\x0b\n\x03ids\x18\x01 \x03(\r\"\x80\x03\n\x0eSamplingParams\x12\x18\n\x0btemperature\x18\x01 \x01(\x01H\x00\x88\x01\x01\x12\x12\n\x05top_p\x18\x02 \x01(\x01H\x01\x88\x01\x01\x12\x12\n\x05top_k\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x12\n\x05min_p\x18\x04 \x01(\x01H\x03\x88\x01\x01\x12\x1e\n\x11\x66requency_penalty\x18\x05 \x01(\x01H\x04\x88\x01\x01\x12\x1d\n\x10presence_penalty\x18\x06 \x01(\x01H\x05\x88\x01\x01\x12\x1f\n\x12repetition_penalty\x18\x07 \x01(\x01H\x06\x88\x01\x01\x12\x11\n\x04seed\x18\x08 \x01(\x04H\x07\x88\x01\x01\x12\x1a\n\rnum_sequences\x18\t \x01(\rH\x08\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x08\n\x06_top_kB\x08\n\x06_min_pB\x14\n\x12_frequency_penaltyB\x13\n\x11_presence_penaltyB\x15\n\x13_repetition_penaltyB\x07\n\x05_seedB\x10\n\x0e_num_sequences\"\xfb\x01\n\x0fStoppingOptions\x12\x17\n\nmax_tokens\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x17\n\nmin_tokens\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x30\n\nconditions\x18\x03 \x03(\x0b\x32\x1c.openengine.v1.StopCondition\x12\x17\n\nignore_eos\x18\x04 \x01(\x08H\x02\x88\x01\x01\x12#\n\x16include_stop_in_output\x18\x05 \x01(\x08H\x03\x88\x01\x01\x42\r\n\x0b_max_tokensB\r\n\x0b_min_tokensB\r\n\x0b_ignore_eosB\x19\n\x17_include_stop_in_output\"\xd3\x02\n\x0fResponseOptions\x12#\n\x16return_prompt_logprobs\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12\x41\n\x11prompt_candidates\x18\x02 \x01(\x0b\x32&.openengine.v1.CandidateTokenSelection\x12#\n\x16return_output_logprobs\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12\x41\n\x11output_candidates\x18\x04 \x01(\x0b\x32&.openengine.v1.CandidateTokenSelection\x12!\n\x14prompt_logprob_start\x18\x05 \x01(\rH\x02\x88\x01\x01\x42\x19\n\x17_return_prompt_logprobsB\x19\n\x17_return_output_logprobsB\x17\n\x15_prompt_logprob_start\"\x92\x01\n\x17\x43\x61ndidateTokenSelection\x12\x0f\n\x05top_n\x18\x01 \x01(\rH\x00\x12,\n\ttoken_ids\x18\x02 \x01(\x0b\x32\x17.openengine.v1.TokenIdsH\x00\x12+\n\x03\x61ll\x18\x03 \x01(\x0b\x32\x1c.openengine.v1.AllCandidatesH\x00\x42\x0b\n\tselection\"\x0f\n\rAllCandidates\"\xd3\x01\n\tKvOptions\x12,\n\x07session\x18\x01 \x01(\x0b\x32\x1b.openengine.v1.KvSessionRef\x12\x1f\n\x12\x64\x61ta_parallel_rank\x18\x02 \x01(\rH\x00\x88\x01\x01\x12 \n\x13\x62ypass_prefix_cache\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12\x17\n\ncache_salt\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\x15\n\x13_data_parallel_rankB\x16\n\x14_bypass_prefix_cacheB\r\n\x0b_cache_salt\"J\n\rStopCondition\x12\x13\n\tstop_text\x18\x01 \x01(\tH\x00\x12\x17\n\rstop_token_id\x18\x02 \x01(\rH\x00\x42\x0b\n\tcondition\"\xf3\x01\n\x0eGuidedDecoding\x12\x15\n\x0bjson_schema\x18\x01 \x01(\tH\x00\x12\x0f\n\x05regex\x18\x02 \x01(\tH\x00\x12\x16\n\x0c\x65\x62nf_grammar\x18\x03 \x01(\tH\x00\x12\x18\n\x0estructural_tag\x18\x04 \x01(\tH\x00\x12\x31\n\x06\x63hoice\x18\x05 \x01(\x0b\x32\x1f.openengine.v1.ChoiceConstraintH\x00\x12:\n\x0bjson_object\x18\x06 \x01(\x0b\x32#.openengine.v1.JsonObjectConstraintH\x00\x12\x0f\n\x07\x62\x61\x63kend\x18\x07 \x01(\tB\x07\n\x05guide\"#\n\x10\x43hoiceConstraint\x12\x0f\n\x07\x63hoices\x18\x01 \x03(\t\"\x16\n\x14JsonObjectConstraintb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.generation_params_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_TOKENIDS']._serialized_start=80 + _globals['_TOKENIDS']._serialized_end=103 + _globals['_SAMPLINGPARAMS']._serialized_start=106 + _globals['_SAMPLINGPARAMS']._serialized_end=490 + _globals['_STOPPINGOPTIONS']._serialized_start=493 + _globals['_STOPPINGOPTIONS']._serialized_end=744 + _globals['_RESPONSEOPTIONS']._serialized_start=747 + _globals['_RESPONSEOPTIONS']._serialized_end=1086 + _globals['_CANDIDATETOKENSELECTION']._serialized_start=1089 + _globals['_CANDIDATETOKENSELECTION']._serialized_end=1235 + _globals['_ALLCANDIDATES']._serialized_start=1237 + _globals['_ALLCANDIDATES']._serialized_end=1252 + _globals['_KVOPTIONS']._serialized_start=1255 + _globals['_KVOPTIONS']._serialized_end=1466 + _globals['_STOPCONDITION']._serialized_start=1468 + _globals['_STOPCONDITION']._serialized_end=1542 + _globals['_GUIDEDDECODING']._serialized_start=1545 + _globals['_GUIDEDDECODING']._serialized_end=1788 + _globals['_CHOICECONSTRAINT']._serialized_start=1790 + _globals['_CHOICECONSTRAINT']._serialized_end=1825 + _globals['_JSONOBJECTCONSTRAINT']._serialized_start=1827 + _globals['_JSONOBJECTCONSTRAINT']._serialized_end=1849 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/generation_params_pb2.pyi b/packages/python/src/openengine/v1/generation_params_pb2.pyi new file mode 100644 index 0000000..79dc46e --- /dev/null +++ b/packages/python/src/openengine/v1/generation_params_pb2.pyi @@ -0,0 +1,126 @@ +from openengine.v1 import kv_pb2 as _kv_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class TokenIds(_message.Message): + __slots__ = ("ids",) + IDS_FIELD_NUMBER: _ClassVar[int] + ids: _containers.RepeatedScalarFieldContainer[int] + def __init__(self, ids: _Optional[_Iterable[int]] = ...) -> None: ... + +class SamplingParams(_message.Message): + __slots__ = ("temperature", "top_p", "top_k", "min_p", "frequency_penalty", "presence_penalty", "repetition_penalty", "seed", "num_sequences") + TEMPERATURE_FIELD_NUMBER: _ClassVar[int] + TOP_P_FIELD_NUMBER: _ClassVar[int] + TOP_K_FIELD_NUMBER: _ClassVar[int] + MIN_P_FIELD_NUMBER: _ClassVar[int] + FREQUENCY_PENALTY_FIELD_NUMBER: _ClassVar[int] + PRESENCE_PENALTY_FIELD_NUMBER: _ClassVar[int] + REPETITION_PENALTY_FIELD_NUMBER: _ClassVar[int] + SEED_FIELD_NUMBER: _ClassVar[int] + NUM_SEQUENCES_FIELD_NUMBER: _ClassVar[int] + temperature: float + top_p: float + top_k: int + min_p: float + frequency_penalty: float + presence_penalty: float + repetition_penalty: float + seed: int + num_sequences: int + def __init__(self, temperature: _Optional[float] = ..., top_p: _Optional[float] = ..., top_k: _Optional[int] = ..., min_p: _Optional[float] = ..., frequency_penalty: _Optional[float] = ..., presence_penalty: _Optional[float] = ..., repetition_penalty: _Optional[float] = ..., seed: _Optional[int] = ..., num_sequences: _Optional[int] = ...) -> None: ... + +class StoppingOptions(_message.Message): + __slots__ = ("max_tokens", "min_tokens", "conditions", "ignore_eos", "include_stop_in_output") + MAX_TOKENS_FIELD_NUMBER: _ClassVar[int] + MIN_TOKENS_FIELD_NUMBER: _ClassVar[int] + CONDITIONS_FIELD_NUMBER: _ClassVar[int] + IGNORE_EOS_FIELD_NUMBER: _ClassVar[int] + INCLUDE_STOP_IN_OUTPUT_FIELD_NUMBER: _ClassVar[int] + max_tokens: int + min_tokens: int + conditions: _containers.RepeatedCompositeFieldContainer[StopCondition] + ignore_eos: bool + include_stop_in_output: bool + def __init__(self, max_tokens: _Optional[int] = ..., min_tokens: _Optional[int] = ..., conditions: _Optional[_Iterable[_Union[StopCondition, _Mapping]]] = ..., ignore_eos: _Optional[bool] = ..., include_stop_in_output: _Optional[bool] = ...) -> None: ... + +class ResponseOptions(_message.Message): + __slots__ = ("return_prompt_logprobs", "prompt_candidates", "return_output_logprobs", "output_candidates", "prompt_logprob_start") + RETURN_PROMPT_LOGPROBS_FIELD_NUMBER: _ClassVar[int] + PROMPT_CANDIDATES_FIELD_NUMBER: _ClassVar[int] + RETURN_OUTPUT_LOGPROBS_FIELD_NUMBER: _ClassVar[int] + OUTPUT_CANDIDATES_FIELD_NUMBER: _ClassVar[int] + PROMPT_LOGPROB_START_FIELD_NUMBER: _ClassVar[int] + return_prompt_logprobs: bool + prompt_candidates: CandidateTokenSelection + return_output_logprobs: bool + output_candidates: CandidateTokenSelection + prompt_logprob_start: int + def __init__(self, return_prompt_logprobs: _Optional[bool] = ..., prompt_candidates: _Optional[_Union[CandidateTokenSelection, _Mapping]] = ..., return_output_logprobs: _Optional[bool] = ..., output_candidates: _Optional[_Union[CandidateTokenSelection, _Mapping]] = ..., prompt_logprob_start: _Optional[int] = ...) -> None: ... + +class CandidateTokenSelection(_message.Message): + __slots__ = ("top_n", "token_ids", "all") + TOP_N_FIELD_NUMBER: _ClassVar[int] + TOKEN_IDS_FIELD_NUMBER: _ClassVar[int] + ALL_FIELD_NUMBER: _ClassVar[int] + top_n: int + token_ids: TokenIds + all: AllCandidates + def __init__(self, top_n: _Optional[int] = ..., token_ids: _Optional[_Union[TokenIds, _Mapping]] = ..., all: _Optional[_Union[AllCandidates, _Mapping]] = ...) -> None: ... + +class AllCandidates(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class KvOptions(_message.Message): + __slots__ = ("session", "data_parallel_rank", "bypass_prefix_cache", "cache_salt") + SESSION_FIELD_NUMBER: _ClassVar[int] + DATA_PARALLEL_RANK_FIELD_NUMBER: _ClassVar[int] + BYPASS_PREFIX_CACHE_FIELD_NUMBER: _ClassVar[int] + CACHE_SALT_FIELD_NUMBER: _ClassVar[int] + session: _kv_pb2.KvSessionRef + data_parallel_rank: int + bypass_prefix_cache: bool + cache_salt: str + def __init__(self, session: _Optional[_Union[_kv_pb2.KvSessionRef, _Mapping]] = ..., data_parallel_rank: _Optional[int] = ..., bypass_prefix_cache: _Optional[bool] = ..., cache_salt: _Optional[str] = ...) -> None: ... + +class StopCondition(_message.Message): + __slots__ = ("stop_text", "stop_token_id") + STOP_TEXT_FIELD_NUMBER: _ClassVar[int] + STOP_TOKEN_ID_FIELD_NUMBER: _ClassVar[int] + stop_text: str + stop_token_id: int + def __init__(self, stop_text: _Optional[str] = ..., stop_token_id: _Optional[int] = ...) -> None: ... + +class GuidedDecoding(_message.Message): + __slots__ = ("json_schema", "regex", "ebnf_grammar", "structural_tag", "choice", "json_object", "backend") + JSON_SCHEMA_FIELD_NUMBER: _ClassVar[int] + REGEX_FIELD_NUMBER: _ClassVar[int] + EBNF_GRAMMAR_FIELD_NUMBER: _ClassVar[int] + STRUCTURAL_TAG_FIELD_NUMBER: _ClassVar[int] + CHOICE_FIELD_NUMBER: _ClassVar[int] + JSON_OBJECT_FIELD_NUMBER: _ClassVar[int] + BACKEND_FIELD_NUMBER: _ClassVar[int] + json_schema: str + regex: str + ebnf_grammar: str + structural_tag: str + choice: ChoiceConstraint + json_object: JsonObjectConstraint + backend: str + def __init__(self, json_schema: _Optional[str] = ..., regex: _Optional[str] = ..., ebnf_grammar: _Optional[str] = ..., structural_tag: _Optional[str] = ..., choice: _Optional[_Union[ChoiceConstraint, _Mapping]] = ..., json_object: _Optional[_Union[JsonObjectConstraint, _Mapping]] = ..., backend: _Optional[str] = ...) -> None: ... + +class ChoiceConstraint(_message.Message): + __slots__ = ("choices",) + CHOICES_FIELD_NUMBER: _ClassVar[int] + choices: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, choices: _Optional[_Iterable[str]] = ...) -> None: ... + +class JsonObjectConstraint(_message.Message): + __slots__ = () + def __init__(self) -> None: ... diff --git a/packages/python/src/openengine/v1/generation_pb2.py b/packages/python/src/openengine/v1/generation_pb2.py new file mode 100644 index 0000000..0f16498 --- /dev/null +++ b/packages/python/src/openengine/v1/generation_pb2.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/generation.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/generation.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from openengine.v1 import error_pb2 as openengine_dot_v1_dot_error__pb2 +from openengine.v1 import generation_params_pb2 as openengine_dot_v1_dot_generation__params__pb2 +from openengine.v1 import kv_pb2 as openengine_dot_v1_dot_kv__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1eopenengine/v1/generation.proto\x12\ropenengine.v1\x1a\x19openengine/v1/error.proto\x1a%openengine/v1/generation_params.proto\x1a\x16openengine/v1/kv.proto\"\xb8\x04\n\x0fGenerateRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\r\n\x05model\x18\x02 \x01(\t\x12\x10\n\x06prompt\x18\x03 \x01(\tH\x00\x12,\n\ttoken_ids\x18\x04 \x01(\x0b\x32\x17.openengine.v1.TokenIdsH\x00\x12/\n\x08sampling\x18\x05 \x01(\x0b\x32\x1d.openengine.v1.SamplingParams\x12\x30\n\x08stopping\x18\x06 \x01(\x0b\x32\x1e.openengine.v1.StoppingOptions\x12\x30\n\x08response\x18\x07 \x01(\x0b\x32\x1e.openengine.v1.ResponseOptions\x12$\n\x02kv\x18\x08 \x01(\x0b\x32\x18.openengine.v1.KvOptions\x12-\n\x06guided\x18\t \x01(\x0b\x32\x1d.openengine.v1.GuidedDecoding\x12\'\n\x05media\x18\n \x03(\x0b\x32\x18.openengine.v1.MediaItem\x12\x11\n\tlora_name\x18\x0b \x01(\t\x12\x15\n\x08priority\x18\x0c \x01(\x05H\x01\x88\x01\x01\x12>\n\x08metadata\x18\r \x03(\x0b\x32,.openengine.v1.GenerateRequest.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x07\n\x05inputB\x0b\n\t_priority\"\x99\x01\n\tMediaItem\x12)\n\x08modality\x18\x01 \x01(\x0e\x32\x17.openengine.v1.Modality\x12\r\n\x03url\x18\x02 \x01(\tH\x00\x12\x12\n\x08\x64\x61ta_uri\x18\x03 \x01(\tH\x00\x12\x13\n\traw_bytes\x18\x04 \x01(\x0cH\x00\x12\x11\n\tmime_type\x18\x05 \x01(\t\x12\x0c\n\x04uuid\x18\x06 \x01(\tB\x08\n\x06source\"\xca\x02\n\x10GenerateResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12-\n\x06prompt\x18\x02 \x01(\x0b\x32\x1b.openengine.v1.PromptOutputH\x00\x12+\n\x05token\x18\x03 \x01(\x0b\x32\x1a.openengine.v1.TokenOutputH\x00\x12\x34\n\rprefill_ready\x18\x04 \x01(\x0b\x32\x1b.openengine.v1.PrefillReadyH\x00\x12\x35\n\x08\x66inished\x18\x05 \x01(\x0b\x32!.openengine.v1.GenerationFinishedH\x00\x12+\n\x05\x65rror\x18\x06 \x01(\x0b\x32\x1a.openengine.v1.EngineErrorH\x00\x12#\n\x05usage\x18\n \x01(\x0b\x32\x14.openengine.v1.UsageB\x07\n\x05\x65vent\"8\n\x0cPromptOutput\x12(\n\x06tokens\x18\x01 \x03(\x0b\x32\x18.openengine.v1.TokenInfo\"q\n\x0bTokenOutput\x12\x19\n\x0coutput_index\x18\x01 \x01(\rH\x00\x88\x01\x01\x12(\n\x06tokens\x18\x02 \x03(\x0b\x32\x18.openengine.v1.TokenInfo\x12\x0c\n\x04text\x18\x03 \x01(\tB\x0f\n\r_output_index\"\x96\x01\n\tTokenInfo\x12\x10\n\x08token_id\x18\x01 \x01(\r\x12\r\n\x05token\x18\x02 \x01(\t\x12\x14\n\x07logprob\x18\x03 \x01(\x01H\x00\x88\x01\x01\x12\x11\n\x04rank\x18\x04 \x01(\rH\x01\x88\x01\x01\x12*\n\ncandidates\x18\x05 \x03(\x0b\x32\x16.openengine.v1.LogProbB\n\n\x08_logprobB\x07\n\x05_rank\"W\n\x07LogProb\x12\x10\n\x08token_id\x18\x01 \x01(\r\x12\x0f\n\x07logprob\x18\x02 \x01(\x01\x12\r\n\x05token\x18\x03 \x01(\t\x12\x11\n\x04rank\x18\x04 \x01(\rH\x00\x88\x01\x01\x42\x07\n\x05_rank\"?\n\x0cPrefillReady\x12/\n\nkv_session\x18\x01 \x01(\x0b\x32\x1b.openengine.v1.KvSessionRef\"\xac\x01\n\x12GenerationFinished\x12\x19\n\x0coutput_index\x18\x01 \x01(\rH\x00\x88\x01\x01\x12+\n\x06reason\x18\x02 \x01(\x0e\x32\x1b.openengine.v1.FinishReason\x12\x0f\n\x07message\x18\x03 \x01(\t\x12,\n\nstop_match\x18\x04 \x01(\x0b\x32\x18.openengine.v1.StopMatchB\x0f\n\r_output_index\"Z\n\tStopMatch\x12\x17\n\rstop_token_id\x18\x01 \x01(\rH\x00\x12\x13\n\tstop_text\x18\x02 \x01(\tH\x00\x12\x16\n\x0c\x65os_token_id\x18\x03 \x01(\rH\x00\x42\x07\n\x05match\"\xbf\x01\n\x05Usage\x12\x15\n\rprompt_tokens\x18\x01 \x01(\r\x12\x19\n\x11\x63ompletion_tokens\x18\x02 \x01(\r\x12\x14\n\x0ctotal_tokens\x18\x03 \x01(\r\x12!\n\x14\x63\x61\x63hed_prompt_tokens\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1d\n\x10reasoning_tokens\x18\x05 \x01(\rH\x01\x88\x01\x01\x42\x17\n\x15_cached_prompt_tokensB\x13\n\x11_reasoning_tokens*`\n\x08Modality\x12\x18\n\x14MODALITY_UNSPECIFIED\x10\x00\x12\x12\n\x0eMODALITY_IMAGE\x10\x01\x12\x12\n\x0eMODALITY_VIDEO\x10\x02\x12\x12\n\x0eMODALITY_AUDIO\x10\x03*|\n\x0c\x46inishReason\x12\x1d\n\x19\x46INISH_REASON_UNSPECIFIED\x10\x00\x12\x16\n\x12\x46INISH_REASON_STOP\x10\x01\x12\x18\n\x14\x46INISH_REASON_LENGTH\x10\x02\x12\x1b\n\x17\x46INISH_REASON_CANCELLED\x10\x03\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.generation_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_GENERATEREQUEST_METADATAENTRY']._loaded_options = None + _globals['_GENERATEREQUEST_METADATAENTRY']._serialized_options = b'8\001' + _globals['_MODALITY']._serialized_start=2140 + _globals['_MODALITY']._serialized_end=2236 + _globals['_FINISHREASON']._serialized_start=2238 + _globals['_FINISHREASON']._serialized_end=2362 + _globals['_GENERATEREQUEST']._serialized_start=140 + _globals['_GENERATEREQUEST']._serialized_end=708 + _globals['_GENERATEREQUEST_METADATAENTRY']._serialized_start=639 + _globals['_GENERATEREQUEST_METADATAENTRY']._serialized_end=686 + _globals['_MEDIAITEM']._serialized_start=711 + _globals['_MEDIAITEM']._serialized_end=864 + _globals['_GENERATERESPONSE']._serialized_start=867 + _globals['_GENERATERESPONSE']._serialized_end=1197 + _globals['_PROMPTOUTPUT']._serialized_start=1199 + _globals['_PROMPTOUTPUT']._serialized_end=1255 + _globals['_TOKENOUTPUT']._serialized_start=1257 + _globals['_TOKENOUTPUT']._serialized_end=1370 + _globals['_TOKENINFO']._serialized_start=1373 + _globals['_TOKENINFO']._serialized_end=1523 + _globals['_LOGPROB']._serialized_start=1525 + _globals['_LOGPROB']._serialized_end=1612 + _globals['_PREFILLREADY']._serialized_start=1614 + _globals['_PREFILLREADY']._serialized_end=1677 + _globals['_GENERATIONFINISHED']._serialized_start=1680 + _globals['_GENERATIONFINISHED']._serialized_end=1852 + _globals['_STOPMATCH']._serialized_start=1854 + _globals['_STOPMATCH']._serialized_end=1944 + _globals['_USAGE']._serialized_start=1947 + _globals['_USAGE']._serialized_end=2138 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/generation_pb2.pyi b/packages/python/src/openengine/v1/generation_pb2.pyi new file mode 100644 index 0000000..8340f78 --- /dev/null +++ b/packages/python/src/openengine/v1/generation_pb2.pyi @@ -0,0 +1,188 @@ +from openengine.v1 import error_pb2 as _error_pb2 +from openengine.v1 import generation_params_pb2 as _generation_params_pb2 +from openengine.v1 import kv_pb2 as _kv_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class Modality(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + MODALITY_UNSPECIFIED: _ClassVar[Modality] + MODALITY_IMAGE: _ClassVar[Modality] + MODALITY_VIDEO: _ClassVar[Modality] + MODALITY_AUDIO: _ClassVar[Modality] + +class FinishReason(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + FINISH_REASON_UNSPECIFIED: _ClassVar[FinishReason] + FINISH_REASON_STOP: _ClassVar[FinishReason] + FINISH_REASON_LENGTH: _ClassVar[FinishReason] + FINISH_REASON_CANCELLED: _ClassVar[FinishReason] +MODALITY_UNSPECIFIED: Modality +MODALITY_IMAGE: Modality +MODALITY_VIDEO: Modality +MODALITY_AUDIO: Modality +FINISH_REASON_UNSPECIFIED: FinishReason +FINISH_REASON_STOP: FinishReason +FINISH_REASON_LENGTH: FinishReason +FINISH_REASON_CANCELLED: FinishReason + +class GenerateRequest(_message.Message): + __slots__ = ("request_id", "model", "prompt", "token_ids", "sampling", "stopping", "response", "kv", "guided", "media", "lora_name", "priority", "metadata") + class MetadataEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ... + REQUEST_ID_FIELD_NUMBER: _ClassVar[int] + MODEL_FIELD_NUMBER: _ClassVar[int] + PROMPT_FIELD_NUMBER: _ClassVar[int] + TOKEN_IDS_FIELD_NUMBER: _ClassVar[int] + SAMPLING_FIELD_NUMBER: _ClassVar[int] + STOPPING_FIELD_NUMBER: _ClassVar[int] + RESPONSE_FIELD_NUMBER: _ClassVar[int] + KV_FIELD_NUMBER: _ClassVar[int] + GUIDED_FIELD_NUMBER: _ClassVar[int] + MEDIA_FIELD_NUMBER: _ClassVar[int] + LORA_NAME_FIELD_NUMBER: _ClassVar[int] + PRIORITY_FIELD_NUMBER: _ClassVar[int] + METADATA_FIELD_NUMBER: _ClassVar[int] + request_id: str + model: str + prompt: str + token_ids: _generation_params_pb2.TokenIds + sampling: _generation_params_pb2.SamplingParams + stopping: _generation_params_pb2.StoppingOptions + response: _generation_params_pb2.ResponseOptions + kv: _generation_params_pb2.KvOptions + guided: _generation_params_pb2.GuidedDecoding + media: _containers.RepeatedCompositeFieldContainer[MediaItem] + lora_name: str + priority: int + metadata: _containers.ScalarMap[str, str] + def __init__(self, request_id: _Optional[str] = ..., model: _Optional[str] = ..., prompt: _Optional[str] = ..., token_ids: _Optional[_Union[_generation_params_pb2.TokenIds, _Mapping]] = ..., sampling: _Optional[_Union[_generation_params_pb2.SamplingParams, _Mapping]] = ..., stopping: _Optional[_Union[_generation_params_pb2.StoppingOptions, _Mapping]] = ..., response: _Optional[_Union[_generation_params_pb2.ResponseOptions, _Mapping]] = ..., kv: _Optional[_Union[_generation_params_pb2.KvOptions, _Mapping]] = ..., guided: _Optional[_Union[_generation_params_pb2.GuidedDecoding, _Mapping]] = ..., media: _Optional[_Iterable[_Union[MediaItem, _Mapping]]] = ..., lora_name: _Optional[str] = ..., priority: _Optional[int] = ..., metadata: _Optional[_Mapping[str, str]] = ...) -> None: ... + +class MediaItem(_message.Message): + __slots__ = ("modality", "url", "data_uri", "raw_bytes", "mime_type", "uuid") + MODALITY_FIELD_NUMBER: _ClassVar[int] + URL_FIELD_NUMBER: _ClassVar[int] + DATA_URI_FIELD_NUMBER: _ClassVar[int] + RAW_BYTES_FIELD_NUMBER: _ClassVar[int] + MIME_TYPE_FIELD_NUMBER: _ClassVar[int] + UUID_FIELD_NUMBER: _ClassVar[int] + modality: Modality + url: str + data_uri: str + raw_bytes: bytes + mime_type: str + uuid: str + def __init__(self, modality: _Optional[_Union[Modality, str]] = ..., url: _Optional[str] = ..., data_uri: _Optional[str] = ..., raw_bytes: _Optional[bytes] = ..., mime_type: _Optional[str] = ..., uuid: _Optional[str] = ...) -> None: ... + +class GenerateResponse(_message.Message): + __slots__ = ("request_id", "prompt", "token", "prefill_ready", "finished", "error", "usage") + REQUEST_ID_FIELD_NUMBER: _ClassVar[int] + PROMPT_FIELD_NUMBER: _ClassVar[int] + TOKEN_FIELD_NUMBER: _ClassVar[int] + PREFILL_READY_FIELD_NUMBER: _ClassVar[int] + FINISHED_FIELD_NUMBER: _ClassVar[int] + ERROR_FIELD_NUMBER: _ClassVar[int] + USAGE_FIELD_NUMBER: _ClassVar[int] + request_id: str + prompt: PromptOutput + token: TokenOutput + prefill_ready: PrefillReady + finished: GenerationFinished + error: _error_pb2.EngineError + usage: Usage + def __init__(self, request_id: _Optional[str] = ..., prompt: _Optional[_Union[PromptOutput, _Mapping]] = ..., token: _Optional[_Union[TokenOutput, _Mapping]] = ..., prefill_ready: _Optional[_Union[PrefillReady, _Mapping]] = ..., finished: _Optional[_Union[GenerationFinished, _Mapping]] = ..., error: _Optional[_Union[_error_pb2.EngineError, _Mapping]] = ..., usage: _Optional[_Union[Usage, _Mapping]] = ...) -> None: ... + +class PromptOutput(_message.Message): + __slots__ = ("tokens",) + TOKENS_FIELD_NUMBER: _ClassVar[int] + tokens: _containers.RepeatedCompositeFieldContainer[TokenInfo] + def __init__(self, tokens: _Optional[_Iterable[_Union[TokenInfo, _Mapping]]] = ...) -> None: ... + +class TokenOutput(_message.Message): + __slots__ = ("output_index", "tokens", "text") + OUTPUT_INDEX_FIELD_NUMBER: _ClassVar[int] + TOKENS_FIELD_NUMBER: _ClassVar[int] + TEXT_FIELD_NUMBER: _ClassVar[int] + output_index: int + tokens: _containers.RepeatedCompositeFieldContainer[TokenInfo] + text: str + def __init__(self, output_index: _Optional[int] = ..., tokens: _Optional[_Iterable[_Union[TokenInfo, _Mapping]]] = ..., text: _Optional[str] = ...) -> None: ... + +class TokenInfo(_message.Message): + __slots__ = ("token_id", "token", "logprob", "rank", "candidates") + TOKEN_ID_FIELD_NUMBER: _ClassVar[int] + TOKEN_FIELD_NUMBER: _ClassVar[int] + LOGPROB_FIELD_NUMBER: _ClassVar[int] + RANK_FIELD_NUMBER: _ClassVar[int] + CANDIDATES_FIELD_NUMBER: _ClassVar[int] + token_id: int + token: str + logprob: float + rank: int + candidates: _containers.RepeatedCompositeFieldContainer[LogProb] + def __init__(self, token_id: _Optional[int] = ..., token: _Optional[str] = ..., logprob: _Optional[float] = ..., rank: _Optional[int] = ..., candidates: _Optional[_Iterable[_Union[LogProb, _Mapping]]] = ...) -> None: ... + +class LogProb(_message.Message): + __slots__ = ("token_id", "logprob", "token", "rank") + TOKEN_ID_FIELD_NUMBER: _ClassVar[int] + LOGPROB_FIELD_NUMBER: _ClassVar[int] + TOKEN_FIELD_NUMBER: _ClassVar[int] + RANK_FIELD_NUMBER: _ClassVar[int] + token_id: int + logprob: float + token: str + rank: int + def __init__(self, token_id: _Optional[int] = ..., logprob: _Optional[float] = ..., token: _Optional[str] = ..., rank: _Optional[int] = ...) -> None: ... + +class PrefillReady(_message.Message): + __slots__ = ("kv_session",) + KV_SESSION_FIELD_NUMBER: _ClassVar[int] + kv_session: _kv_pb2.KvSessionRef + def __init__(self, kv_session: _Optional[_Union[_kv_pb2.KvSessionRef, _Mapping]] = ...) -> None: ... + +class GenerationFinished(_message.Message): + __slots__ = ("output_index", "reason", "message", "stop_match") + OUTPUT_INDEX_FIELD_NUMBER: _ClassVar[int] + REASON_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + STOP_MATCH_FIELD_NUMBER: _ClassVar[int] + output_index: int + reason: FinishReason + message: str + stop_match: StopMatch + def __init__(self, output_index: _Optional[int] = ..., reason: _Optional[_Union[FinishReason, str]] = ..., message: _Optional[str] = ..., stop_match: _Optional[_Union[StopMatch, _Mapping]] = ...) -> None: ... + +class StopMatch(_message.Message): + __slots__ = ("stop_token_id", "stop_text", "eos_token_id") + STOP_TOKEN_ID_FIELD_NUMBER: _ClassVar[int] + STOP_TEXT_FIELD_NUMBER: _ClassVar[int] + EOS_TOKEN_ID_FIELD_NUMBER: _ClassVar[int] + stop_token_id: int + stop_text: str + eos_token_id: int + def __init__(self, stop_token_id: _Optional[int] = ..., stop_text: _Optional[str] = ..., eos_token_id: _Optional[int] = ...) -> None: ... + +class Usage(_message.Message): + __slots__ = ("prompt_tokens", "completion_tokens", "total_tokens", "cached_prompt_tokens", "reasoning_tokens") + PROMPT_TOKENS_FIELD_NUMBER: _ClassVar[int] + COMPLETION_TOKENS_FIELD_NUMBER: _ClassVar[int] + TOTAL_TOKENS_FIELD_NUMBER: _ClassVar[int] + CACHED_PROMPT_TOKENS_FIELD_NUMBER: _ClassVar[int] + REASONING_TOKENS_FIELD_NUMBER: _ClassVar[int] + prompt_tokens: int + completion_tokens: int + total_tokens: int + cached_prompt_tokens: int + reasoning_tokens: int + def __init__(self, prompt_tokens: _Optional[int] = ..., completion_tokens: _Optional[int] = ..., total_tokens: _Optional[int] = ..., cached_prompt_tokens: _Optional[int] = ..., reasoning_tokens: _Optional[int] = ...) -> None: ... diff --git a/packages/python/src/openengine/v1/kv_pb2.py b/packages/python/src/openengine/v1/kv_pb2.py new file mode 100644 index 0000000..7bab09d --- /dev/null +++ b/packages/python/src/openengine/v1/kv_pb2.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/kv.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/kv.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 +from openengine.v1 import error_pb2 as openengine_dot_v1_dot_error__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16openengine/v1/kv.proto\x12\ropenengine.v1\x1a\x1cgoogle/protobuf/struct.proto\x1a\x19openengine/v1/error.proto\"\xaf\x01\n\x0cKvSessionRef\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x18\n\x10transfer_backend\x18\x02 \x01(\t\x12,\n\tendpoints\x18\x03 \x03(\x0b\x32\x19.openengine.v1.KvEndpoint\x12\x0f\n\x07\x64p_rank\x18\x04 \x01(\r\x12\x32\n\x11\x61ttributes_struct\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\":\n\nKvEndpoint\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x10\n\x08protocol\x18\x03 \x01(\t\"\x1b\n\x19GetKvConnectorInfoRequest\"\xbc\x03\n\x0fKvConnectorInfo\x12\x14\n\x07\x65nabled\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12\x18\n\x10transfer_backend\x18\x02 \x01(\t\x12\x32\n\x0flocal_endpoints\x18\x03 \x03(\x0b\x32\x19.openengine.v1.KvEndpoint\x12\x1b\n\x13supported_protocols\x18\x04 \x03(\t\x12$\n\x17supports_remote_prefill\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12!\n\x14supports_decode_pull\x18\x06 \x01(\x08H\x02\x88\x01\x01\x12#\n\x16supports_abort_cleanup\x18\x07 \x01(\x08H\x03\x88\x01\x01\x12\x1b\n\x0esupports_drain\x18\x08 \x01(\x08H\x04\x88\x01\x01\x12\x1b\n\x0eschema_version\x18\t \x01(\rH\x05\x88\x01\x01\x42\n\n\x08_enabledB\x1a\n\x18_supports_remote_prefillB\x17\n\x15_supports_decode_pullB\x19\n\x17_supports_abort_cleanupB\x11\n\x0f_supports_drainB\x11\n\x0f_schema_version\"7\n\x18GetKvEventSourcesRequest\x12\x1b\n\x13\x64\x61ta_parallel_ranks\x18\x01 \x03(\r\"J\n\x19GetKvEventSourcesResponse\x12-\n\x07sources\x18\x01 \x03(\x0b\x32\x1c.openengine.v1.KvEventSource\"\xec\x02\n\rKvEventSource\x12\x11\n\ttransport\x18\x01 \x01(\t\x12\x30\n\rendpoint_addr\x18\x02 \x01(\x0b\x32\x19.openengine.v1.KvEndpoint\x12\r\n\x05topic\x18\x03 \x01(\t\x12\x17\n\x0freplay_endpoint\x18\x04 \x01(\t\x12\x1f\n\x12\x64\x61ta_parallel_rank\x18\x05 \x01(\rH\x00\x88\x01\x01\x12\x10\n\x08\x65ncoding\x18\x06 \x01(\t\x12\x1b\n\x0eschema_version\x18\x07 \x01(\rH\x01\x88\x01\x01\x12\x19\n\x0c\x62uffer_steps\x18\x08 \x01(\rH\x02\x88\x01\x01\x12\x10\n\x03hwm\x18\t \x01(\rH\x03\x88\x01\x01\x12\x1b\n\x0emax_queue_size\x18\n \x01(\rH\x04\x88\x01\x01\x42\x15\n\x13_data_parallel_rankB\x11\n\x0f_schema_versionB\x0f\n\r_buffer_stepsB\x06\n\x04_hwmB\x11\n\x0f_max_queue_size\"p\n\x18SubscribeKvEventsRequest\x12\x1b\n\x13\x64\x61ta_parallel_ranks\x18\x01 \x03(\r\x12\x18\n\x10include_snapshot\x18\x02 \x01(\x08\x12\x1d\n\x15start_sequence_number\x18\x03 \x01(\x04\"\x7f\n\x19SubscribeKvEventsResponse\x12,\n\x05\x62\x61tch\x18\x01 \x01(\x0b\x32\x1b.openengine.v1.KvEventBatchH\x00\x12+\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x1a.openengine.v1.EngineErrorH\x00\x42\x07\n\x05\x65vent\"\x89\x01\n\x0cKvEventBatch\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x04\x12\x1c\n\x14timestamp_unix_nanos\x18\x02 \x01(\x04\x12\x1a\n\x12\x64\x61ta_parallel_rank\x18\x03 \x01(\r\x12&\n\x06\x65vents\x18\x04 \x03(\x0b\x32\x16.openengine.v1.KvEvent\"\x80\x02\n\x07KvEvent\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12/\n\nkv_session\x18\x02 \x01(\x0b\x32\x1b.openengine.v1.KvSessionRef\x12\x32\n\x0c\x62lock_stored\x18\n \x01(\x0b\x32\x1a.openengine.v1.BlockStoredH\x00\x12\x34\n\rblock_removed\x18\x0b \x01(\x0b\x32\x1b.openengine.v1.BlockRemovedH\x00\x12=\n\x12\x61ll_blocks_cleared\x18\x0c \x01(\x0b\x32\x1f.openengine.v1.AllBlocksClearedH\x00\x42\x07\n\x05\x65vent\"\xf7\x02\n\x0b\x42lockStored\x12\x30\n\x0c\x62lock_hashes\x18\x01 \x03(\x0b\x32\x1a.openengine.v1.KvBlockHash\x12\x35\n\x11parent_block_hash\x18\x02 \x01(\x0b\x32\x1a.openengine.v1.KvBlockHash\x12\x11\n\ttoken_ids\x18\x03 \x03(\r\x12\x12\n\nblock_size\x18\x04 \x01(\r\x12\x0f\n\x07lora_id\x18\x05 \x01(\x03\x12\x11\n\tlora_name\x18\x06 \x01(\t\x12,\n\x06medium\x18\x07 \x01(\x0e\x32\x1c.openengine.v1.StorageMedium\x12\x31\n\nextra_keys\x18\x14 \x03(\x0b\x32\x1d.openengine.v1.OpaqueKeyTuple\x12\x11\n\tgroup_idx\x18\x15 \x01(\r\x12\x1a\n\x12kv_cache_spec_kind\x18\x16 \x01(\t\x12$\n\x1ckv_cache_spec_sliding_window\x18\x17 \x01(\r\"\x81\x01\n\x0c\x42lockRemoved\x12\x30\n\x0c\x62lock_hashes\x18\x01 \x03(\x0b\x32\x1a.openengine.v1.KvBlockHash\x12,\n\x06medium\x18\x02 \x01(\x0e\x32\x1c.openengine.v1.StorageMedium\x12\x11\n\tgroup_idx\x18\x03 \x01(\r\"\x12\n\x10\x41llBlocksCleared\".\n\x0bKvBlockHash\x12\r\n\x05value\x18\x01 \x01(\x0c\x12\x10\n\x08\x65ncoding\x18\x02 \x01(\t\" \n\x0eOpaqueKeyTuple\x12\x0e\n\x06values\x18\x01 \x03(\t*\x9c\x01\n\rStorageMedium\x12\x1e\n\x1aSTORAGE_MEDIUM_UNSPECIFIED\x10\x00\x12\x16\n\x12STORAGE_MEDIUM_GPU\x10\x01\x12\x1d\n\x19STORAGE_MEDIUM_CPU_PINNED\x10\x02\x12\x17\n\x13STORAGE_MEDIUM_DISK\x10\x03\x12\x1b\n\x17STORAGE_MEDIUM_EXTERNAL\x10\x04\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.kv_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_STORAGEMEDIUM']._serialized_start=2567 + _globals['_STORAGEMEDIUM']._serialized_end=2723 + _globals['_KVSESSIONREF']._serialized_start=99 + _globals['_KVSESSIONREF']._serialized_end=274 + _globals['_KVENDPOINT']._serialized_start=276 + _globals['_KVENDPOINT']._serialized_end=334 + _globals['_GETKVCONNECTORINFOREQUEST']._serialized_start=336 + _globals['_GETKVCONNECTORINFOREQUEST']._serialized_end=363 + _globals['_KVCONNECTORINFO']._serialized_start=366 + _globals['_KVCONNECTORINFO']._serialized_end=810 + _globals['_GETKVEVENTSOURCESREQUEST']._serialized_start=812 + _globals['_GETKVEVENTSOURCESREQUEST']._serialized_end=867 + _globals['_GETKVEVENTSOURCESRESPONSE']._serialized_start=869 + _globals['_GETKVEVENTSOURCESRESPONSE']._serialized_end=943 + _globals['_KVEVENTSOURCE']._serialized_start=946 + _globals['_KVEVENTSOURCE']._serialized_end=1310 + _globals['_SUBSCRIBEKVEVENTSREQUEST']._serialized_start=1312 + _globals['_SUBSCRIBEKVEVENTSREQUEST']._serialized_end=1424 + _globals['_SUBSCRIBEKVEVENTSRESPONSE']._serialized_start=1426 + _globals['_SUBSCRIBEKVEVENTSRESPONSE']._serialized_end=1553 + _globals['_KVEVENTBATCH']._serialized_start=1556 + _globals['_KVEVENTBATCH']._serialized_end=1693 + _globals['_KVEVENT']._serialized_start=1696 + _globals['_KVEVENT']._serialized_end=1952 + _globals['_BLOCKSTORED']._serialized_start=1955 + _globals['_BLOCKSTORED']._serialized_end=2330 + _globals['_BLOCKREMOVED']._serialized_start=2333 + _globals['_BLOCKREMOVED']._serialized_end=2462 + _globals['_ALLBLOCKSCLEARED']._serialized_start=2464 + _globals['_ALLBLOCKSCLEARED']._serialized_end=2482 + _globals['_KVBLOCKHASH']._serialized_start=2484 + _globals['_KVBLOCKHASH']._serialized_end=2530 + _globals['_OPAQUEKEYTUPLE']._serialized_start=2532 + _globals['_OPAQUEKEYTUPLE']._serialized_end=2564 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/kv_pb2.pyi b/packages/python/src/openengine/v1/kv_pb2.pyi new file mode 100644 index 0000000..ee42789 --- /dev/null +++ b/packages/python/src/openengine/v1/kv_pb2.pyi @@ -0,0 +1,207 @@ +from google.protobuf import struct_pb2 as _struct_pb2 +from openengine.v1 import error_pb2 as _error_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class StorageMedium(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + STORAGE_MEDIUM_UNSPECIFIED: _ClassVar[StorageMedium] + STORAGE_MEDIUM_GPU: _ClassVar[StorageMedium] + STORAGE_MEDIUM_CPU_PINNED: _ClassVar[StorageMedium] + STORAGE_MEDIUM_DISK: _ClassVar[StorageMedium] + STORAGE_MEDIUM_EXTERNAL: _ClassVar[StorageMedium] +STORAGE_MEDIUM_UNSPECIFIED: StorageMedium +STORAGE_MEDIUM_GPU: StorageMedium +STORAGE_MEDIUM_CPU_PINNED: StorageMedium +STORAGE_MEDIUM_DISK: StorageMedium +STORAGE_MEDIUM_EXTERNAL: StorageMedium + +class KvSessionRef(_message.Message): + __slots__ = ("session_id", "transfer_backend", "endpoints", "dp_rank", "attributes_struct") + SESSION_ID_FIELD_NUMBER: _ClassVar[int] + TRANSFER_BACKEND_FIELD_NUMBER: _ClassVar[int] + ENDPOINTS_FIELD_NUMBER: _ClassVar[int] + DP_RANK_FIELD_NUMBER: _ClassVar[int] + ATTRIBUTES_STRUCT_FIELD_NUMBER: _ClassVar[int] + session_id: str + transfer_backend: str + endpoints: _containers.RepeatedCompositeFieldContainer[KvEndpoint] + dp_rank: int + attributes_struct: _struct_pb2.Struct + def __init__(self, session_id: _Optional[str] = ..., transfer_backend: _Optional[str] = ..., endpoints: _Optional[_Iterable[_Union[KvEndpoint, _Mapping]]] = ..., dp_rank: _Optional[int] = ..., attributes_struct: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ... + +class KvEndpoint(_message.Message): + __slots__ = ("host", "port", "protocol") + HOST_FIELD_NUMBER: _ClassVar[int] + PORT_FIELD_NUMBER: _ClassVar[int] + PROTOCOL_FIELD_NUMBER: _ClassVar[int] + host: str + port: int + protocol: str + def __init__(self, host: _Optional[str] = ..., port: _Optional[int] = ..., protocol: _Optional[str] = ...) -> None: ... + +class GetKvConnectorInfoRequest(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class KvConnectorInfo(_message.Message): + __slots__ = ("enabled", "transfer_backend", "local_endpoints", "supported_protocols", "supports_remote_prefill", "supports_decode_pull", "supports_abort_cleanup", "supports_drain", "schema_version") + ENABLED_FIELD_NUMBER: _ClassVar[int] + TRANSFER_BACKEND_FIELD_NUMBER: _ClassVar[int] + LOCAL_ENDPOINTS_FIELD_NUMBER: _ClassVar[int] + SUPPORTED_PROTOCOLS_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_REMOTE_PREFILL_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_DECODE_PULL_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_ABORT_CLEANUP_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_DRAIN_FIELD_NUMBER: _ClassVar[int] + SCHEMA_VERSION_FIELD_NUMBER: _ClassVar[int] + enabled: bool + transfer_backend: str + local_endpoints: _containers.RepeatedCompositeFieldContainer[KvEndpoint] + supported_protocols: _containers.RepeatedScalarFieldContainer[str] + supports_remote_prefill: bool + supports_decode_pull: bool + supports_abort_cleanup: bool + supports_drain: bool + schema_version: int + def __init__(self, enabled: _Optional[bool] = ..., transfer_backend: _Optional[str] = ..., local_endpoints: _Optional[_Iterable[_Union[KvEndpoint, _Mapping]]] = ..., supported_protocols: _Optional[_Iterable[str]] = ..., supports_remote_prefill: _Optional[bool] = ..., supports_decode_pull: _Optional[bool] = ..., supports_abort_cleanup: _Optional[bool] = ..., supports_drain: _Optional[bool] = ..., schema_version: _Optional[int] = ...) -> None: ... + +class GetKvEventSourcesRequest(_message.Message): + __slots__ = ("data_parallel_ranks",) + DATA_PARALLEL_RANKS_FIELD_NUMBER: _ClassVar[int] + data_parallel_ranks: _containers.RepeatedScalarFieldContainer[int] + def __init__(self, data_parallel_ranks: _Optional[_Iterable[int]] = ...) -> None: ... + +class GetKvEventSourcesResponse(_message.Message): + __slots__ = ("sources",) + SOURCES_FIELD_NUMBER: _ClassVar[int] + sources: _containers.RepeatedCompositeFieldContainer[KvEventSource] + def __init__(self, sources: _Optional[_Iterable[_Union[KvEventSource, _Mapping]]] = ...) -> None: ... + +class KvEventSource(_message.Message): + __slots__ = ("transport", "endpoint_addr", "topic", "replay_endpoint", "data_parallel_rank", "encoding", "schema_version", "buffer_steps", "hwm", "max_queue_size") + TRANSPORT_FIELD_NUMBER: _ClassVar[int] + ENDPOINT_ADDR_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + REPLAY_ENDPOINT_FIELD_NUMBER: _ClassVar[int] + DATA_PARALLEL_RANK_FIELD_NUMBER: _ClassVar[int] + ENCODING_FIELD_NUMBER: _ClassVar[int] + SCHEMA_VERSION_FIELD_NUMBER: _ClassVar[int] + BUFFER_STEPS_FIELD_NUMBER: _ClassVar[int] + HWM_FIELD_NUMBER: _ClassVar[int] + MAX_QUEUE_SIZE_FIELD_NUMBER: _ClassVar[int] + transport: str + endpoint_addr: KvEndpoint + topic: str + replay_endpoint: str + data_parallel_rank: int + encoding: str + schema_version: int + buffer_steps: int + hwm: int + max_queue_size: int + def __init__(self, transport: _Optional[str] = ..., endpoint_addr: _Optional[_Union[KvEndpoint, _Mapping]] = ..., topic: _Optional[str] = ..., replay_endpoint: _Optional[str] = ..., data_parallel_rank: _Optional[int] = ..., encoding: _Optional[str] = ..., schema_version: _Optional[int] = ..., buffer_steps: _Optional[int] = ..., hwm: _Optional[int] = ..., max_queue_size: _Optional[int] = ...) -> None: ... + +class SubscribeKvEventsRequest(_message.Message): + __slots__ = ("data_parallel_ranks", "include_snapshot", "start_sequence_number") + DATA_PARALLEL_RANKS_FIELD_NUMBER: _ClassVar[int] + INCLUDE_SNAPSHOT_FIELD_NUMBER: _ClassVar[int] + START_SEQUENCE_NUMBER_FIELD_NUMBER: _ClassVar[int] + data_parallel_ranks: _containers.RepeatedScalarFieldContainer[int] + include_snapshot: bool + start_sequence_number: int + def __init__(self, data_parallel_ranks: _Optional[_Iterable[int]] = ..., include_snapshot: _Optional[bool] = ..., start_sequence_number: _Optional[int] = ...) -> None: ... + +class SubscribeKvEventsResponse(_message.Message): + __slots__ = ("batch", "error") + BATCH_FIELD_NUMBER: _ClassVar[int] + ERROR_FIELD_NUMBER: _ClassVar[int] + batch: KvEventBatch + error: _error_pb2.EngineError + def __init__(self, batch: _Optional[_Union[KvEventBatch, _Mapping]] = ..., error: _Optional[_Union[_error_pb2.EngineError, _Mapping]] = ...) -> None: ... + +class KvEventBatch(_message.Message): + __slots__ = ("sequence_number", "timestamp_unix_nanos", "data_parallel_rank", "events") + SEQUENCE_NUMBER_FIELD_NUMBER: _ClassVar[int] + TIMESTAMP_UNIX_NANOS_FIELD_NUMBER: _ClassVar[int] + DATA_PARALLEL_RANK_FIELD_NUMBER: _ClassVar[int] + EVENTS_FIELD_NUMBER: _ClassVar[int] + sequence_number: int + timestamp_unix_nanos: int + data_parallel_rank: int + events: _containers.RepeatedCompositeFieldContainer[KvEvent] + def __init__(self, sequence_number: _Optional[int] = ..., timestamp_unix_nanos: _Optional[int] = ..., data_parallel_rank: _Optional[int] = ..., events: _Optional[_Iterable[_Union[KvEvent, _Mapping]]] = ...) -> None: ... + +class KvEvent(_message.Message): + __slots__ = ("request_id", "kv_session", "block_stored", "block_removed", "all_blocks_cleared") + REQUEST_ID_FIELD_NUMBER: _ClassVar[int] + KV_SESSION_FIELD_NUMBER: _ClassVar[int] + BLOCK_STORED_FIELD_NUMBER: _ClassVar[int] + BLOCK_REMOVED_FIELD_NUMBER: _ClassVar[int] + ALL_BLOCKS_CLEARED_FIELD_NUMBER: _ClassVar[int] + request_id: str + kv_session: KvSessionRef + block_stored: BlockStored + block_removed: BlockRemoved + all_blocks_cleared: AllBlocksCleared + def __init__(self, request_id: _Optional[str] = ..., kv_session: _Optional[_Union[KvSessionRef, _Mapping]] = ..., block_stored: _Optional[_Union[BlockStored, _Mapping]] = ..., block_removed: _Optional[_Union[BlockRemoved, _Mapping]] = ..., all_blocks_cleared: _Optional[_Union[AllBlocksCleared, _Mapping]] = ...) -> None: ... + +class BlockStored(_message.Message): + __slots__ = ("block_hashes", "parent_block_hash", "token_ids", "block_size", "lora_id", "lora_name", "medium", "extra_keys", "group_idx", "kv_cache_spec_kind", "kv_cache_spec_sliding_window") + BLOCK_HASHES_FIELD_NUMBER: _ClassVar[int] + PARENT_BLOCK_HASH_FIELD_NUMBER: _ClassVar[int] + TOKEN_IDS_FIELD_NUMBER: _ClassVar[int] + BLOCK_SIZE_FIELD_NUMBER: _ClassVar[int] + LORA_ID_FIELD_NUMBER: _ClassVar[int] + LORA_NAME_FIELD_NUMBER: _ClassVar[int] + MEDIUM_FIELD_NUMBER: _ClassVar[int] + EXTRA_KEYS_FIELD_NUMBER: _ClassVar[int] + GROUP_IDX_FIELD_NUMBER: _ClassVar[int] + KV_CACHE_SPEC_KIND_FIELD_NUMBER: _ClassVar[int] + KV_CACHE_SPEC_SLIDING_WINDOW_FIELD_NUMBER: _ClassVar[int] + block_hashes: _containers.RepeatedCompositeFieldContainer[KvBlockHash] + parent_block_hash: KvBlockHash + token_ids: _containers.RepeatedScalarFieldContainer[int] + block_size: int + lora_id: int + lora_name: str + medium: StorageMedium + extra_keys: _containers.RepeatedCompositeFieldContainer[OpaqueKeyTuple] + group_idx: int + kv_cache_spec_kind: str + kv_cache_spec_sliding_window: int + def __init__(self, block_hashes: _Optional[_Iterable[_Union[KvBlockHash, _Mapping]]] = ..., parent_block_hash: _Optional[_Union[KvBlockHash, _Mapping]] = ..., token_ids: _Optional[_Iterable[int]] = ..., block_size: _Optional[int] = ..., lora_id: _Optional[int] = ..., lora_name: _Optional[str] = ..., medium: _Optional[_Union[StorageMedium, str]] = ..., extra_keys: _Optional[_Iterable[_Union[OpaqueKeyTuple, _Mapping]]] = ..., group_idx: _Optional[int] = ..., kv_cache_spec_kind: _Optional[str] = ..., kv_cache_spec_sliding_window: _Optional[int] = ...) -> None: ... + +class BlockRemoved(_message.Message): + __slots__ = ("block_hashes", "medium", "group_idx") + BLOCK_HASHES_FIELD_NUMBER: _ClassVar[int] + MEDIUM_FIELD_NUMBER: _ClassVar[int] + GROUP_IDX_FIELD_NUMBER: _ClassVar[int] + block_hashes: _containers.RepeatedCompositeFieldContainer[KvBlockHash] + medium: StorageMedium + group_idx: int + def __init__(self, block_hashes: _Optional[_Iterable[_Union[KvBlockHash, _Mapping]]] = ..., medium: _Optional[_Union[StorageMedium, str]] = ..., group_idx: _Optional[int] = ...) -> None: ... + +class AllBlocksCleared(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class KvBlockHash(_message.Message): + __slots__ = ("value", "encoding") + VALUE_FIELD_NUMBER: _ClassVar[int] + ENCODING_FIELD_NUMBER: _ClassVar[int] + value: bytes + encoding: str + def __init__(self, value: _Optional[bytes] = ..., encoding: _Optional[str] = ...) -> None: ... + +class OpaqueKeyTuple(_message.Message): + __slots__ = ("values",) + VALUES_FIELD_NUMBER: _ClassVar[int] + values: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, values: _Optional[_Iterable[str]] = ...) -> None: ... diff --git a/packages/python/src/openengine/v1/lifecycle_pb2.py b/packages/python/src/openengine/v1/lifecycle_pb2.py new file mode 100644 index 0000000..69a44ca --- /dev/null +++ b/packages/python/src/openengine/v1/lifecycle_pb2.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/lifecycle.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/lifecycle.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from openengine.v1 import engine_pb2 as openengine_dot_v1_dot_engine__pb2 +from openengine.v1 import error_pb2 as openengine_dot_v1_dot_error__pb2 +from openengine.v1 import kv_pb2 as openengine_dot_v1_dot_kv__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1dopenengine/v1/lifecycle.proto\x12\ropenengine.v1\x1a\x1aopenengine/v1/engine.proto\x1a\x19openengine/v1/error.proto\x1a\x16openengine/v1/kv.proto\"h\n\rHealthRequest\x12\x1f\n\x17include_inference_probe\x18\x01 \x01(\x08\x12\r\n\x05model\x18\x02 \x01(\t\x12\'\n\x04role\x18\x03 \x01(\x0e\x32\x19.openengine.v1.EngineRole\"g\n\x0eHealthResponse\x12)\n\x05state\x18\x01 \x01(\x0e\x32\x1a.openengine.v1.HealthState\x12*\n\x06\x63hecks\x18\x02 \x03(\x0b\x32\x1a.openengine.v1.HealthCheck\"W\n\x0bHealthCheck\x12\x0c\n\x04name\x18\x01 \x01(\t\x12)\n\x05state\x18\x02 \x01(\x0e\x32\x1a.openengine.v1.HealthState\x12\x0f\n\x07message\x18\x03 \x01(\t\"\x95\x01\n\x0c\x41\x62ortRequest\x12\x14\n\nrequest_id\x18\x01 \x01(\tH\x00\x12\x31\n\nkv_session\x18\x02 \x01(\x0b\x32\x1b.openengine.v1.KvSessionRefH\x00\x12\x32\n\x0c\x61ll_requests\x18\x03 \x01(\x0b\x32\x1a.openengine.v1.AllRequestsH\x00\x42\x08\n\x06target\"\r\n\x0b\x41llRequests\"L\n\rAbortResponse\x12*\n\x06status\x18\x01 \x01(\x0e\x32\x1a.openengine.v1.AbortStatus\x12\x0f\n\x07message\x18\x02 \x01(\t\"{\n\x0c\x44rainRequest\x12#\n\x1bstop_accepting_new_requests\x18\x01 \x01(\x08\x12\x18\n\x0b\x64\x65\x61\x64line_ms\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x14\x61\x62ort_after_deadline\x18\x03 \x01(\x08\x42\x0e\n\x0c_deadline_ms\"\xee\x01\n\rDrainResponse\x12*\n\x05state\x18\x01 \x01(\x0e\x32\x19.openengine.v1.DrainStateH\x00\x12+\n\x05\x65rror\x18\x05 \x01(\x0b\x32\x1a.openengine.v1.EngineErrorH\x00\x12\x1f\n\x12in_flight_requests\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10open_kv_sessions\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x0f\n\x07message\x18\x04 \x01(\tB\x07\n\x05\x65ventB\x15\n\x13_in_flight_requestsB\x13\n\x11_open_kv_sessions*\xb0\x01\n\x0bHealthState\x12\x1c\n\x18HEALTH_STATE_UNSPECIFIED\x10\x00\x12\x19\n\x15HEALTH_STATE_STARTING\x10\x01\x12\x16\n\x12HEALTH_STATE_READY\x10\x02\x12\x19\n\x15HEALTH_STATE_DEGRADED\x10\x03\x12\x19\n\x15HEALTH_STATE_DRAINING\x10\x04\x12\x1a\n\x16HEALTH_STATE_NOT_READY\x10\x05*h\n\x0b\x41\x62ortStatus\x12\x1c\n\x18\x41\x42ORT_STATUS_UNSPECIFIED\x10\x00\x12\x18\n\x14\x41\x42ORT_STATUS_ABORTED\x10\x01\x12!\n\x1d\x41\x42ORT_STATUS_ALREADY_FINISHED\x10\x02*y\n\nDrainState\x12\x1b\n\x17\x44RAIN_STATE_UNSPECIFIED\x10\x00\x12\x17\n\x13\x44RAIN_STATE_STARTED\x10\x01\x12\x1b\n\x17\x44RAIN_STATE_IN_PROGRESS\x10\x02\x12\x18\n\x14\x44RAIN_STATE_COMPLETE\x10\x03\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.lifecycle_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_HEALTHSTATE']._serialized_start=1039 + _globals['_HEALTHSTATE']._serialized_end=1215 + _globals['_ABORTSTATUS']._serialized_start=1217 + _globals['_ABORTSTATUS']._serialized_end=1321 + _globals['_DRAINSTATE']._serialized_start=1323 + _globals['_DRAINSTATE']._serialized_end=1444 + _globals['_HEALTHREQUEST']._serialized_start=127 + _globals['_HEALTHREQUEST']._serialized_end=231 + _globals['_HEALTHRESPONSE']._serialized_start=233 + _globals['_HEALTHRESPONSE']._serialized_end=336 + _globals['_HEALTHCHECK']._serialized_start=338 + _globals['_HEALTHCHECK']._serialized_end=425 + _globals['_ABORTREQUEST']._serialized_start=428 + _globals['_ABORTREQUEST']._serialized_end=577 + _globals['_ALLREQUESTS']._serialized_start=579 + _globals['_ALLREQUESTS']._serialized_end=592 + _globals['_ABORTRESPONSE']._serialized_start=594 + _globals['_ABORTRESPONSE']._serialized_end=670 + _globals['_DRAINREQUEST']._serialized_start=672 + _globals['_DRAINREQUEST']._serialized_end=795 + _globals['_DRAINRESPONSE']._serialized_start=798 + _globals['_DRAINRESPONSE']._serialized_end=1036 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/lifecycle_pb2.pyi b/packages/python/src/openengine/v1/lifecycle_pb2.pyi new file mode 100644 index 0000000..329d52d --- /dev/null +++ b/packages/python/src/openengine/v1/lifecycle_pb2.pyi @@ -0,0 +1,120 @@ +from openengine.v1 import engine_pb2 as _engine_pb2 +from openengine.v1 import error_pb2 as _error_pb2 +from openengine.v1 import kv_pb2 as _kv_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class HealthState(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + HEALTH_STATE_UNSPECIFIED: _ClassVar[HealthState] + HEALTH_STATE_STARTING: _ClassVar[HealthState] + HEALTH_STATE_READY: _ClassVar[HealthState] + HEALTH_STATE_DEGRADED: _ClassVar[HealthState] + HEALTH_STATE_DRAINING: _ClassVar[HealthState] + HEALTH_STATE_NOT_READY: _ClassVar[HealthState] + +class AbortStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + ABORT_STATUS_UNSPECIFIED: _ClassVar[AbortStatus] + ABORT_STATUS_ABORTED: _ClassVar[AbortStatus] + ABORT_STATUS_ALREADY_FINISHED: _ClassVar[AbortStatus] + +class DrainState(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + DRAIN_STATE_UNSPECIFIED: _ClassVar[DrainState] + DRAIN_STATE_STARTED: _ClassVar[DrainState] + DRAIN_STATE_IN_PROGRESS: _ClassVar[DrainState] + DRAIN_STATE_COMPLETE: _ClassVar[DrainState] +HEALTH_STATE_UNSPECIFIED: HealthState +HEALTH_STATE_STARTING: HealthState +HEALTH_STATE_READY: HealthState +HEALTH_STATE_DEGRADED: HealthState +HEALTH_STATE_DRAINING: HealthState +HEALTH_STATE_NOT_READY: HealthState +ABORT_STATUS_UNSPECIFIED: AbortStatus +ABORT_STATUS_ABORTED: AbortStatus +ABORT_STATUS_ALREADY_FINISHED: AbortStatus +DRAIN_STATE_UNSPECIFIED: DrainState +DRAIN_STATE_STARTED: DrainState +DRAIN_STATE_IN_PROGRESS: DrainState +DRAIN_STATE_COMPLETE: DrainState + +class HealthRequest(_message.Message): + __slots__ = ("include_inference_probe", "model", "role") + INCLUDE_INFERENCE_PROBE_FIELD_NUMBER: _ClassVar[int] + MODEL_FIELD_NUMBER: _ClassVar[int] + ROLE_FIELD_NUMBER: _ClassVar[int] + include_inference_probe: bool + model: str + role: _engine_pb2.EngineRole + def __init__(self, include_inference_probe: _Optional[bool] = ..., model: _Optional[str] = ..., role: _Optional[_Union[_engine_pb2.EngineRole, str]] = ...) -> None: ... + +class HealthResponse(_message.Message): + __slots__ = ("state", "checks") + STATE_FIELD_NUMBER: _ClassVar[int] + CHECKS_FIELD_NUMBER: _ClassVar[int] + state: HealthState + checks: _containers.RepeatedCompositeFieldContainer[HealthCheck] + def __init__(self, state: _Optional[_Union[HealthState, str]] = ..., checks: _Optional[_Iterable[_Union[HealthCheck, _Mapping]]] = ...) -> None: ... + +class HealthCheck(_message.Message): + __slots__ = ("name", "state", "message") + NAME_FIELD_NUMBER: _ClassVar[int] + STATE_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + name: str + state: HealthState + message: str + def __init__(self, name: _Optional[str] = ..., state: _Optional[_Union[HealthState, str]] = ..., message: _Optional[str] = ...) -> None: ... + +class AbortRequest(_message.Message): + __slots__ = ("request_id", "kv_session", "all_requests") + REQUEST_ID_FIELD_NUMBER: _ClassVar[int] + KV_SESSION_FIELD_NUMBER: _ClassVar[int] + ALL_REQUESTS_FIELD_NUMBER: _ClassVar[int] + request_id: str + kv_session: _kv_pb2.KvSessionRef + all_requests: AllRequests + def __init__(self, request_id: _Optional[str] = ..., kv_session: _Optional[_Union[_kv_pb2.KvSessionRef, _Mapping]] = ..., all_requests: _Optional[_Union[AllRequests, _Mapping]] = ...) -> None: ... + +class AllRequests(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class AbortResponse(_message.Message): + __slots__ = ("status", "message") + STATUS_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + status: AbortStatus + message: str + def __init__(self, status: _Optional[_Union[AbortStatus, str]] = ..., message: _Optional[str] = ...) -> None: ... + +class DrainRequest(_message.Message): + __slots__ = ("stop_accepting_new_requests", "deadline_ms", "abort_after_deadline") + STOP_ACCEPTING_NEW_REQUESTS_FIELD_NUMBER: _ClassVar[int] + DEADLINE_MS_FIELD_NUMBER: _ClassVar[int] + ABORT_AFTER_DEADLINE_FIELD_NUMBER: _ClassVar[int] + stop_accepting_new_requests: bool + deadline_ms: int + abort_after_deadline: bool + def __init__(self, stop_accepting_new_requests: _Optional[bool] = ..., deadline_ms: _Optional[int] = ..., abort_after_deadline: _Optional[bool] = ...) -> None: ... + +class DrainResponse(_message.Message): + __slots__ = ("state", "error", "in_flight_requests", "open_kv_sessions", "message") + STATE_FIELD_NUMBER: _ClassVar[int] + ERROR_FIELD_NUMBER: _ClassVar[int] + IN_FLIGHT_REQUESTS_FIELD_NUMBER: _ClassVar[int] + OPEN_KV_SESSIONS_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + state: DrainState + error: _error_pb2.EngineError + in_flight_requests: int + open_kv_sessions: int + message: str + def __init__(self, state: _Optional[_Union[DrainState, str]] = ..., error: _Optional[_Union[_error_pb2.EngineError, _Mapping]] = ..., in_flight_requests: _Optional[int] = ..., open_kv_sessions: _Optional[int] = ..., message: _Optional[str] = ...) -> None: ... diff --git a/packages/python/src/openengine/v1/lora_pb2.py b/packages/python/src/openengine/v1/lora_pb2.py new file mode 100644 index 0000000..a53d2a8 --- /dev/null +++ b/packages/python/src/openengine/v1/lora_pb2.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/lora.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/lora.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18openengine/v1/lora.proto\x12\ropenengine.v1\"F\n\x0bLoraAdapter\x12\x0f\n\x07lora_id\x18\x01 \x01(\x03\x12\x11\n\tlora_name\x18\x02 \x01(\t\x12\x13\n\x0bsource_path\x18\x03 \x01(\t\">\n\x0fLoadLoraRequest\x12+\n\x07\x61\x64\x61pter\x18\x01 \x01(\x0b\x32\x1a.openengine.v1.LoraAdapter\"W\n\x10LoadLoraResponse\x12+\n\x07\x61\x64\x61pter\x18\x01 \x01(\x0b\x32\x1a.openengine.v1.LoraAdapter\x12\x16\n\x0e\x61lready_loaded\x18\x02 \x01(\x08\"&\n\x11UnloadLoraRequest\x12\x11\n\tlora_name\x18\x01 \x01(\t\"A\n\x12UnloadLoraResponse\x12+\n\x07\x61\x64\x61pter\x18\x01 \x01(\x0b\x32\x1a.openengine.v1.LoraAdapter\"\x12\n\x10ListLorasRequest\"A\n\x11ListLorasResponse\x12,\n\x08\x61\x64\x61pters\x18\x01 \x03(\x0b\x32\x1a.openengine.v1.LoraAdapterb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.lora_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_LORAADAPTER']._serialized_start=43 + _globals['_LORAADAPTER']._serialized_end=113 + _globals['_LOADLORAREQUEST']._serialized_start=115 + _globals['_LOADLORAREQUEST']._serialized_end=177 + _globals['_LOADLORARESPONSE']._serialized_start=179 + _globals['_LOADLORARESPONSE']._serialized_end=266 + _globals['_UNLOADLORAREQUEST']._serialized_start=268 + _globals['_UNLOADLORAREQUEST']._serialized_end=306 + _globals['_UNLOADLORARESPONSE']._serialized_start=308 + _globals['_UNLOADLORARESPONSE']._serialized_end=373 + _globals['_LISTLORASREQUEST']._serialized_start=375 + _globals['_LISTLORASREQUEST']._serialized_end=393 + _globals['_LISTLORASRESPONSE']._serialized_start=395 + _globals['_LISTLORASRESPONSE']._serialized_end=460 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/lora_pb2.pyi b/packages/python/src/openengine/v1/lora_pb2.pyi new file mode 100644 index 0000000..e5a6064 --- /dev/null +++ b/packages/python/src/openengine/v1/lora_pb2.pyi @@ -0,0 +1,53 @@ +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class LoraAdapter(_message.Message): + __slots__ = ("lora_id", "lora_name", "source_path") + LORA_ID_FIELD_NUMBER: _ClassVar[int] + LORA_NAME_FIELD_NUMBER: _ClassVar[int] + SOURCE_PATH_FIELD_NUMBER: _ClassVar[int] + lora_id: int + lora_name: str + source_path: str + def __init__(self, lora_id: _Optional[int] = ..., lora_name: _Optional[str] = ..., source_path: _Optional[str] = ...) -> None: ... + +class LoadLoraRequest(_message.Message): + __slots__ = ("adapter",) + ADAPTER_FIELD_NUMBER: _ClassVar[int] + adapter: LoraAdapter + def __init__(self, adapter: _Optional[_Union[LoraAdapter, _Mapping]] = ...) -> None: ... + +class LoadLoraResponse(_message.Message): + __slots__ = ("adapter", "already_loaded") + ADAPTER_FIELD_NUMBER: _ClassVar[int] + ALREADY_LOADED_FIELD_NUMBER: _ClassVar[int] + adapter: LoraAdapter + already_loaded: bool + def __init__(self, adapter: _Optional[_Union[LoraAdapter, _Mapping]] = ..., already_loaded: _Optional[bool] = ...) -> None: ... + +class UnloadLoraRequest(_message.Message): + __slots__ = ("lora_name",) + LORA_NAME_FIELD_NUMBER: _ClassVar[int] + lora_name: str + def __init__(self, lora_name: _Optional[str] = ...) -> None: ... + +class UnloadLoraResponse(_message.Message): + __slots__ = ("adapter",) + ADAPTER_FIELD_NUMBER: _ClassVar[int] + adapter: LoraAdapter + def __init__(self, adapter: _Optional[_Union[LoraAdapter, _Mapping]] = ...) -> None: ... + +class ListLorasRequest(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class ListLorasResponse(_message.Message): + __slots__ = ("adapters",) + ADAPTERS_FIELD_NUMBER: _ClassVar[int] + adapters: _containers.RepeatedCompositeFieldContainer[LoraAdapter] + def __init__(self, adapters: _Optional[_Iterable[_Union[LoraAdapter, _Mapping]]] = ...) -> None: ... diff --git a/packages/python/src/openengine/v1/model_pb2.py b/packages/python/src/openengine/v1/model_pb2.py new file mode 100644 index 0000000..dab46f0 --- /dev/null +++ b/packages/python/src/openengine/v1/model_pb2.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/model.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/model.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19openengine/v1/model.proto\x12\ropenengine.v1\"$\n\x13GetModelInfoRequest\x12\r\n\x05model\x18\x01 \x01(\t\"\x86\x06\n\tModelInfo\x12\x10\n\x08model_id\x18\x01 \x01(\t\x12\x19\n\x11served_model_name\x18\x02 \x01(\t\x12\x1c\n\x14served_model_aliases\x18\x03 \x03(\t\x12\x1f\n\x12max_context_length\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1e\n\x11max_output_tokens\x18\x05 \x01(\rH\x01\x88\x01\x01\x12\x1a\n\rkv_block_size\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1c\n\x0ftotal_kv_blocks\x18\x07 \x01(\x04H\x03\x88\x01\x01\x12!\n\x14max_running_requests\x18\x08 \x01(\x04H\x04\x88\x01\x01\x12\x1f\n\x12max_batched_tokens\x18\t \x01(\x04H\x05\x88\x01\x01\x12\x17\n\x0ftokenizer_modes\x18\n \x03(\t\x12 \n\x13supports_text_input\x18\x14 \x01(\x08H\x06\x88\x01\x01\x12%\n\x18supports_token_ids_input\x18\x15 \x01(\x08H\x07\x88\x01\x01\x12\x39\n\ngeneration\x18\x16 \x01(\x0b\x32%.openengine.v1.GenerationCapabilities\x12\x1a\n\rsupports_lora\x18\x17 \x01(\x08H\x08\x88\x01\x01\x12 \n\x13supports_multimodal\x18\x18 \x01(\x08H\t\x88\x01\x01\x12\x18\n\x10reasoning_parser\x18\x19 \x01(\t\x12\x18\n\x10tool_call_parser\x18\x1a \x01(\tB\x15\n\x13_max_context_lengthB\x14\n\x12_max_output_tokensB\x10\n\x0e_kv_block_sizeB\x12\n\x10_total_kv_blocksB\x17\n\x15_max_running_requestsB\x15\n\x13_max_batched_tokensB\x16\n\x14_supports_text_inputB\x1b\n\x19_supports_token_ids_inputB\x10\n\x0e_supports_loraB\x16\n\x14_supports_multimodal\"\x8a\x04\n\x16GenerationCapabilities\x12;\n\x0fprompt_logprobs\x18\x01 \x01(\x0b\x32\".openengine.v1.LogprobCapabilities\x12;\n\x0foutput_logprobs\x18\x02 \x01(\x0b\x32\".openengine.v1.LogprobCapabilities\x12\x42\n\x0fguided_decoding\x18\x03 \x01(\x0b\x32).openengine.v1.GuidedDecodingCapabilities\x12\x1e\n\x11max_num_sequences\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1e\n\x11supports_priority\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12$\n\x17supports_stop_in_output\x18\x06 \x01(\x08H\x02\x88\x01\x01\x12 \n\x13supports_cache_salt\x18\x07 \x01(\x08H\x03\x88\x01\x01\x12)\n\x1csupports_prefix_cache_bypass\x18\x08 \x01(\x08H\x04\x88\x01\x01\x42\x14\n\x12_max_num_sequencesB\x14\n\x12_supports_priorityB\x1a\n\x18_supports_stop_in_outputB\x16\n\x14_supports_cache_saltB\x1f\n\x1d_supports_prefix_cache_bypass\"\xb0\x01\n\x13LogprobCapabilities\x12\x16\n\tsupported\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12M\n\x19\x63\x61ndidate_selection_modes\x18\x02 \x03(\x0e\x32*.openengine.v1.CandidateTokenSelectionMode\x12\x16\n\tmax_top_n\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x0c\n\n_supportedB\x0c\n\n_max_top_n\"t\n\x1aGuidedDecodingCapabilities\x12\x16\n\tsupported\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12\x30\n\x05modes\x18\x02 \x03(\x0e\x32!.openengine.v1.GuidedDecodingModeB\x0c\n\n_supported*\xcd\x01\n\x1b\x43\x61ndidateTokenSelectionMode\x12.\n*CANDIDATE_TOKEN_SELECTION_MODE_UNSPECIFIED\x10\x00\x12(\n$CANDIDATE_TOKEN_SELECTION_MODE_TOP_N\x10\x01\x12,\n(CANDIDATE_TOKEN_SELECTION_MODE_TOKEN_IDS\x10\x02\x12&\n\"CANDIDATE_TOKEN_SELECTION_MODE_ALL\x10\x03*\x97\x02\n\x12GuidedDecodingMode\x12$\n GUIDED_DECODING_MODE_UNSPECIFIED\x10\x00\x12$\n GUIDED_DECODING_MODE_JSON_SCHEMA\x10\x01\x12\x1e\n\x1aGUIDED_DECODING_MODE_REGEX\x10\x02\x12%\n!GUIDED_DECODING_MODE_EBNF_GRAMMAR\x10\x03\x12\'\n#GUIDED_DECODING_MODE_STRUCTURAL_TAG\x10\x04\x12\x1f\n\x1bGUIDED_DECODING_MODE_CHOICE\x10\x05\x12$\n GUIDED_DECODING_MODE_JSON_OBJECT\x10\x06\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.model_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_CANDIDATETOKENSELECTIONMODE']._serialized_start=1682 + _globals['_CANDIDATETOKENSELECTIONMODE']._serialized_end=1887 + _globals['_GUIDEDDECODINGMODE']._serialized_start=1890 + _globals['_GUIDEDDECODINGMODE']._serialized_end=2169 + _globals['_GETMODELINFOREQUEST']._serialized_start=44 + _globals['_GETMODELINFOREQUEST']._serialized_end=80 + _globals['_MODELINFO']._serialized_start=83 + _globals['_MODELINFO']._serialized_end=857 + _globals['_GENERATIONCAPABILITIES']._serialized_start=860 + _globals['_GENERATIONCAPABILITIES']._serialized_end=1382 + _globals['_LOGPROBCAPABILITIES']._serialized_start=1385 + _globals['_LOGPROBCAPABILITIES']._serialized_end=1561 + _globals['_GUIDEDDECODINGCAPABILITIES']._serialized_start=1563 + _globals['_GUIDEDDECODINGCAPABILITIES']._serialized_end=1679 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/model_pb2.pyi b/packages/python/src/openengine/v1/model_pb2.pyi new file mode 100644 index 0000000..27779fc --- /dev/null +++ b/packages/python/src/openengine/v1/model_pb2.pyi @@ -0,0 +1,118 @@ +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class CandidateTokenSelectionMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + CANDIDATE_TOKEN_SELECTION_MODE_UNSPECIFIED: _ClassVar[CandidateTokenSelectionMode] + CANDIDATE_TOKEN_SELECTION_MODE_TOP_N: _ClassVar[CandidateTokenSelectionMode] + CANDIDATE_TOKEN_SELECTION_MODE_TOKEN_IDS: _ClassVar[CandidateTokenSelectionMode] + CANDIDATE_TOKEN_SELECTION_MODE_ALL: _ClassVar[CandidateTokenSelectionMode] + +class GuidedDecodingMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + GUIDED_DECODING_MODE_UNSPECIFIED: _ClassVar[GuidedDecodingMode] + GUIDED_DECODING_MODE_JSON_SCHEMA: _ClassVar[GuidedDecodingMode] + GUIDED_DECODING_MODE_REGEX: _ClassVar[GuidedDecodingMode] + GUIDED_DECODING_MODE_EBNF_GRAMMAR: _ClassVar[GuidedDecodingMode] + GUIDED_DECODING_MODE_STRUCTURAL_TAG: _ClassVar[GuidedDecodingMode] + GUIDED_DECODING_MODE_CHOICE: _ClassVar[GuidedDecodingMode] + GUIDED_DECODING_MODE_JSON_OBJECT: _ClassVar[GuidedDecodingMode] +CANDIDATE_TOKEN_SELECTION_MODE_UNSPECIFIED: CandidateTokenSelectionMode +CANDIDATE_TOKEN_SELECTION_MODE_TOP_N: CandidateTokenSelectionMode +CANDIDATE_TOKEN_SELECTION_MODE_TOKEN_IDS: CandidateTokenSelectionMode +CANDIDATE_TOKEN_SELECTION_MODE_ALL: CandidateTokenSelectionMode +GUIDED_DECODING_MODE_UNSPECIFIED: GuidedDecodingMode +GUIDED_DECODING_MODE_JSON_SCHEMA: GuidedDecodingMode +GUIDED_DECODING_MODE_REGEX: GuidedDecodingMode +GUIDED_DECODING_MODE_EBNF_GRAMMAR: GuidedDecodingMode +GUIDED_DECODING_MODE_STRUCTURAL_TAG: GuidedDecodingMode +GUIDED_DECODING_MODE_CHOICE: GuidedDecodingMode +GUIDED_DECODING_MODE_JSON_OBJECT: GuidedDecodingMode + +class GetModelInfoRequest(_message.Message): + __slots__ = ("model",) + MODEL_FIELD_NUMBER: _ClassVar[int] + model: str + def __init__(self, model: _Optional[str] = ...) -> None: ... + +class ModelInfo(_message.Message): + __slots__ = ("model_id", "served_model_name", "served_model_aliases", "max_context_length", "max_output_tokens", "kv_block_size", "total_kv_blocks", "max_running_requests", "max_batched_tokens", "tokenizer_modes", "supports_text_input", "supports_token_ids_input", "generation", "supports_lora", "supports_multimodal", "reasoning_parser", "tool_call_parser") + MODEL_ID_FIELD_NUMBER: _ClassVar[int] + SERVED_MODEL_NAME_FIELD_NUMBER: _ClassVar[int] + SERVED_MODEL_ALIASES_FIELD_NUMBER: _ClassVar[int] + MAX_CONTEXT_LENGTH_FIELD_NUMBER: _ClassVar[int] + MAX_OUTPUT_TOKENS_FIELD_NUMBER: _ClassVar[int] + KV_BLOCK_SIZE_FIELD_NUMBER: _ClassVar[int] + TOTAL_KV_BLOCKS_FIELD_NUMBER: _ClassVar[int] + MAX_RUNNING_REQUESTS_FIELD_NUMBER: _ClassVar[int] + MAX_BATCHED_TOKENS_FIELD_NUMBER: _ClassVar[int] + TOKENIZER_MODES_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_TEXT_INPUT_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_TOKEN_IDS_INPUT_FIELD_NUMBER: _ClassVar[int] + GENERATION_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_LORA_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_MULTIMODAL_FIELD_NUMBER: _ClassVar[int] + REASONING_PARSER_FIELD_NUMBER: _ClassVar[int] + TOOL_CALL_PARSER_FIELD_NUMBER: _ClassVar[int] + model_id: str + served_model_name: str + served_model_aliases: _containers.RepeatedScalarFieldContainer[str] + max_context_length: int + max_output_tokens: int + kv_block_size: int + total_kv_blocks: int + max_running_requests: int + max_batched_tokens: int + tokenizer_modes: _containers.RepeatedScalarFieldContainer[str] + supports_text_input: bool + supports_token_ids_input: bool + generation: GenerationCapabilities + supports_lora: bool + supports_multimodal: bool + reasoning_parser: str + tool_call_parser: str + def __init__(self, model_id: _Optional[str] = ..., served_model_name: _Optional[str] = ..., served_model_aliases: _Optional[_Iterable[str]] = ..., max_context_length: _Optional[int] = ..., max_output_tokens: _Optional[int] = ..., kv_block_size: _Optional[int] = ..., total_kv_blocks: _Optional[int] = ..., max_running_requests: _Optional[int] = ..., max_batched_tokens: _Optional[int] = ..., tokenizer_modes: _Optional[_Iterable[str]] = ..., supports_text_input: _Optional[bool] = ..., supports_token_ids_input: _Optional[bool] = ..., generation: _Optional[_Union[GenerationCapabilities, _Mapping]] = ..., supports_lora: _Optional[bool] = ..., supports_multimodal: _Optional[bool] = ..., reasoning_parser: _Optional[str] = ..., tool_call_parser: _Optional[str] = ...) -> None: ... + +class GenerationCapabilities(_message.Message): + __slots__ = ("prompt_logprobs", "output_logprobs", "guided_decoding", "max_num_sequences", "supports_priority", "supports_stop_in_output", "supports_cache_salt", "supports_prefix_cache_bypass") + PROMPT_LOGPROBS_FIELD_NUMBER: _ClassVar[int] + OUTPUT_LOGPROBS_FIELD_NUMBER: _ClassVar[int] + GUIDED_DECODING_FIELD_NUMBER: _ClassVar[int] + MAX_NUM_SEQUENCES_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_PRIORITY_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_STOP_IN_OUTPUT_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_CACHE_SALT_FIELD_NUMBER: _ClassVar[int] + SUPPORTS_PREFIX_CACHE_BYPASS_FIELD_NUMBER: _ClassVar[int] + prompt_logprobs: LogprobCapabilities + output_logprobs: LogprobCapabilities + guided_decoding: GuidedDecodingCapabilities + max_num_sequences: int + supports_priority: bool + supports_stop_in_output: bool + supports_cache_salt: bool + supports_prefix_cache_bypass: bool + def __init__(self, prompt_logprobs: _Optional[_Union[LogprobCapabilities, _Mapping]] = ..., output_logprobs: _Optional[_Union[LogprobCapabilities, _Mapping]] = ..., guided_decoding: _Optional[_Union[GuidedDecodingCapabilities, _Mapping]] = ..., max_num_sequences: _Optional[int] = ..., supports_priority: _Optional[bool] = ..., supports_stop_in_output: _Optional[bool] = ..., supports_cache_salt: _Optional[bool] = ..., supports_prefix_cache_bypass: _Optional[bool] = ...) -> None: ... + +class LogprobCapabilities(_message.Message): + __slots__ = ("supported", "candidate_selection_modes", "max_top_n") + SUPPORTED_FIELD_NUMBER: _ClassVar[int] + CANDIDATE_SELECTION_MODES_FIELD_NUMBER: _ClassVar[int] + MAX_TOP_N_FIELD_NUMBER: _ClassVar[int] + supported: bool + candidate_selection_modes: _containers.RepeatedScalarFieldContainer[CandidateTokenSelectionMode] + max_top_n: int + def __init__(self, supported: _Optional[bool] = ..., candidate_selection_modes: _Optional[_Iterable[_Union[CandidateTokenSelectionMode, str]]] = ..., max_top_n: _Optional[int] = ...) -> None: ... + +class GuidedDecodingCapabilities(_message.Message): + __slots__ = ("supported", "modes") + SUPPORTED_FIELD_NUMBER: _ClassVar[int] + MODES_FIELD_NUMBER: _ClassVar[int] + supported: bool + modes: _containers.RepeatedScalarFieldContainer[GuidedDecodingMode] + def __init__(self, supported: _Optional[bool] = ..., modes: _Optional[_Iterable[_Union[GuidedDecodingMode, str]]] = ...) -> None: ... diff --git a/packages/python/src/openengine/v1/observability_pb2.py b/packages/python/src/openengine/v1/observability_pb2.py new file mode 100644 index 0000000..63ede5f --- /dev/null +++ b/packages/python/src/openengine/v1/observability_pb2.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/observability.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/observability.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from openengine.v1 import error_pb2 as openengine_dot_v1_dot_error__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!openengine/v1/observability.proto\x12\ropenengine.v1\x1a\x19openengine/v1/error.proto\"*\n\x0eGetLoadRequest\x12\x18\n\x10include_per_rank\x18\x01 \x01(\x08\"\xc5\x05\n\x08LoadInfo\x12\x13\n\x0binstance_id\x18\x01 \x01(\t\x12!\n\x14timestamp_unix_nanos\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x1d\n\x10running_requests\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x0fqueued_requests\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12\x61\x63tive_kv_sessions\x18\x05 \x01(\rH\x03\x88\x01\x01\x12\x1b\n\x0eused_kv_blocks\x18\x06 \x01(\x04H\x04\x88\x01\x01\x12\x1c\n\x0ftotal_kv_blocks\x18\x07 \x01(\x04H\x05\x88\x01\x01\x12\x1b\n\x0erunning_tokens\x18\x08 \x01(\x04H\x06\x88\x01\x01\x12\x1b\n\x0ewaiting_tokens\x18\t \x01(\x04H\x07\x88\x01\x01\x12\x1f\n\x12prefill_batch_size\x18\n \x01(\rH\x08\x88\x01\x01\x12\x1e\n\x11\x64\x65\x63ode_batch_size\x18\x0b \x01(\rH\t\x88\x01\x01\x12*\n\x05ranks\x18\x14 \x03(\x0b\x32\x1b.openengine.v1.RankLoadInfo\x12;\n\nattributes\x18\x1e \x03(\x0b\x32\'.openengine.v1.LoadInfo.AttributesEntry\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x17\n\x15_timestamp_unix_nanosB\x13\n\x11_running_requestsB\x12\n\x10_queued_requestsB\x15\n\x13_active_kv_sessionsB\x11\n\x0f_used_kv_blocksB\x12\n\x10_total_kv_blocksB\x11\n\x0f_running_tokensB\x11\n\x0f_waiting_tokensB\x15\n\x13_prefill_batch_sizeB\x14\n\x12_decode_batch_size\"\xfc\x02\n\x0cRankLoadInfo\x12\x1f\n\x12\x64\x61ta_parallel_rank\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1d\n\x10running_requests\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x0fqueued_requests\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1b\n\x0eused_kv_blocks\x18\x04 \x01(\x04H\x03\x88\x01\x01\x12\x1c\n\x0ftotal_kv_blocks\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x1f\n\x12prefill_batch_size\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1e\n\x11\x64\x65\x63ode_batch_size\x18\x07 \x01(\rH\x06\x88\x01\x01\x42\x15\n\x13_data_parallel_rankB\x13\n\x11_running_requestsB\x12\n\x10_queued_requestsB\x11\n\x0f_used_kv_blocksB\x12\n\x10_total_kv_blocksB\x15\n\x13_prefill_batch_sizeB\x14\n\x12_decode_batch_size\"O\n\x1dSubscribeRuntimeEventsRequest\x12.\n\x05types\x18\x01 \x03(\x0e\x32\x1f.openengine.v1.RuntimeEventType\"\x8c\x01\n\x1eSubscribeRuntimeEventsResponse\x12\x34\n\rruntime_event\x18\x01 \x01(\x0b\x32\x1b.openengine.v1.RuntimeEventH\x00\x12+\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x1a.openengine.v1.EngineErrorH\x00\x42\x07\n\x05\x65vent\"\xe1\x01\n\x0cRuntimeEvent\x12\x10\n\x08\x65vent_id\x18\x01 \x01(\t\x12\x1c\n\x14timestamp_unix_nanos\x18\x02 \x01(\x04\x12-\n\x04type\x18\x03 \x01(\x0e\x32\x1f.openengine.v1.RuntimeEventType\x12?\n\nattributes\x18\x04 \x03(\x0b\x32+.openengine.v1.RuntimeEvent.AttributesEntry\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01*\xb8\x01\n\x10RuntimeEventType\x12\"\n\x1eRUNTIME_EVENT_TYPE_UNSPECIFIED\x10\x00\x12#\n\x1fRUNTIME_EVENT_TYPE_FORWARD_PASS\x10\x01\x12\x1c\n\x18RUNTIME_EVENT_TYPE_BATCH\x10\x02\x12\x1c\n\x18RUNTIME_EVENT_TYPE_QUEUE\x10\x03\x12\x1f\n\x1bRUNTIME_EVENT_TYPE_TRANSFER\x10\x04\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.observability_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_LOADINFO_ATTRIBUTESENTRY']._loaded_options = None + _globals['_LOADINFO_ATTRIBUTESENTRY']._serialized_options = b'8\001' + _globals['_RUNTIMEEVENT_ATTRIBUTESENTRY']._loaded_options = None + _globals['_RUNTIMEEVENT_ATTRIBUTESENTRY']._serialized_options = b'8\001' + _globals['_RUNTIMEEVENTTYPE']._serialized_start=1671 + _globals['_RUNTIMEEVENTTYPE']._serialized_end=1855 + _globals['_GETLOADREQUEST']._serialized_start=79 + _globals['_GETLOADREQUEST']._serialized_end=121 + _globals['_LOADINFO']._serialized_start=124 + _globals['_LOADINFO']._serialized_end=833 + _globals['_LOADINFO_ATTRIBUTESENTRY']._serialized_start=573 + _globals['_LOADINFO_ATTRIBUTESENTRY']._serialized_end=622 + _globals['_RANKLOADINFO']._serialized_start=836 + _globals['_RANKLOADINFO']._serialized_end=1216 + _globals['_SUBSCRIBERUNTIMEEVENTSREQUEST']._serialized_start=1218 + _globals['_SUBSCRIBERUNTIMEEVENTSREQUEST']._serialized_end=1297 + _globals['_SUBSCRIBERUNTIMEEVENTSRESPONSE']._serialized_start=1300 + _globals['_SUBSCRIBERUNTIMEEVENTSRESPONSE']._serialized_end=1440 + _globals['_RUNTIMEEVENT']._serialized_start=1443 + _globals['_RUNTIMEEVENT']._serialized_end=1668 + _globals['_RUNTIMEEVENT_ATTRIBUTESENTRY']._serialized_start=573 + _globals['_RUNTIMEEVENT_ATTRIBUTESENTRY']._serialized_end=622 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/observability_pb2.pyi b/packages/python/src/openengine/v1/observability_pb2.pyi new file mode 100644 index 0000000..7b4de09 --- /dev/null +++ b/packages/python/src/openengine/v1/observability_pb2.pyi @@ -0,0 +1,116 @@ +from openengine.v1 import error_pb2 as _error_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class RuntimeEventType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + RUNTIME_EVENT_TYPE_UNSPECIFIED: _ClassVar[RuntimeEventType] + RUNTIME_EVENT_TYPE_FORWARD_PASS: _ClassVar[RuntimeEventType] + RUNTIME_EVENT_TYPE_BATCH: _ClassVar[RuntimeEventType] + RUNTIME_EVENT_TYPE_QUEUE: _ClassVar[RuntimeEventType] + RUNTIME_EVENT_TYPE_TRANSFER: _ClassVar[RuntimeEventType] +RUNTIME_EVENT_TYPE_UNSPECIFIED: RuntimeEventType +RUNTIME_EVENT_TYPE_FORWARD_PASS: RuntimeEventType +RUNTIME_EVENT_TYPE_BATCH: RuntimeEventType +RUNTIME_EVENT_TYPE_QUEUE: RuntimeEventType +RUNTIME_EVENT_TYPE_TRANSFER: RuntimeEventType + +class GetLoadRequest(_message.Message): + __slots__ = ("include_per_rank",) + INCLUDE_PER_RANK_FIELD_NUMBER: _ClassVar[int] + include_per_rank: bool + def __init__(self, include_per_rank: _Optional[bool] = ...) -> None: ... + +class LoadInfo(_message.Message): + __slots__ = ("instance_id", "timestamp_unix_nanos", "running_requests", "queued_requests", "active_kv_sessions", "used_kv_blocks", "total_kv_blocks", "running_tokens", "waiting_tokens", "prefill_batch_size", "decode_batch_size", "ranks", "attributes") + class AttributesEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ... + INSTANCE_ID_FIELD_NUMBER: _ClassVar[int] + TIMESTAMP_UNIX_NANOS_FIELD_NUMBER: _ClassVar[int] + RUNNING_REQUESTS_FIELD_NUMBER: _ClassVar[int] + QUEUED_REQUESTS_FIELD_NUMBER: _ClassVar[int] + ACTIVE_KV_SESSIONS_FIELD_NUMBER: _ClassVar[int] + USED_KV_BLOCKS_FIELD_NUMBER: _ClassVar[int] + TOTAL_KV_BLOCKS_FIELD_NUMBER: _ClassVar[int] + RUNNING_TOKENS_FIELD_NUMBER: _ClassVar[int] + WAITING_TOKENS_FIELD_NUMBER: _ClassVar[int] + PREFILL_BATCH_SIZE_FIELD_NUMBER: _ClassVar[int] + DECODE_BATCH_SIZE_FIELD_NUMBER: _ClassVar[int] + RANKS_FIELD_NUMBER: _ClassVar[int] + ATTRIBUTES_FIELD_NUMBER: _ClassVar[int] + instance_id: str + timestamp_unix_nanos: int + running_requests: int + queued_requests: int + active_kv_sessions: int + used_kv_blocks: int + total_kv_blocks: int + running_tokens: int + waiting_tokens: int + prefill_batch_size: int + decode_batch_size: int + ranks: _containers.RepeatedCompositeFieldContainer[RankLoadInfo] + attributes: _containers.ScalarMap[str, str] + def __init__(self, instance_id: _Optional[str] = ..., timestamp_unix_nanos: _Optional[int] = ..., running_requests: _Optional[int] = ..., queued_requests: _Optional[int] = ..., active_kv_sessions: _Optional[int] = ..., used_kv_blocks: _Optional[int] = ..., total_kv_blocks: _Optional[int] = ..., running_tokens: _Optional[int] = ..., waiting_tokens: _Optional[int] = ..., prefill_batch_size: _Optional[int] = ..., decode_batch_size: _Optional[int] = ..., ranks: _Optional[_Iterable[_Union[RankLoadInfo, _Mapping]]] = ..., attributes: _Optional[_Mapping[str, str]] = ...) -> None: ... + +class RankLoadInfo(_message.Message): + __slots__ = ("data_parallel_rank", "running_requests", "queued_requests", "used_kv_blocks", "total_kv_blocks", "prefill_batch_size", "decode_batch_size") + DATA_PARALLEL_RANK_FIELD_NUMBER: _ClassVar[int] + RUNNING_REQUESTS_FIELD_NUMBER: _ClassVar[int] + QUEUED_REQUESTS_FIELD_NUMBER: _ClassVar[int] + USED_KV_BLOCKS_FIELD_NUMBER: _ClassVar[int] + TOTAL_KV_BLOCKS_FIELD_NUMBER: _ClassVar[int] + PREFILL_BATCH_SIZE_FIELD_NUMBER: _ClassVar[int] + DECODE_BATCH_SIZE_FIELD_NUMBER: _ClassVar[int] + data_parallel_rank: int + running_requests: int + queued_requests: int + used_kv_blocks: int + total_kv_blocks: int + prefill_batch_size: int + decode_batch_size: int + def __init__(self, data_parallel_rank: _Optional[int] = ..., running_requests: _Optional[int] = ..., queued_requests: _Optional[int] = ..., used_kv_blocks: _Optional[int] = ..., total_kv_blocks: _Optional[int] = ..., prefill_batch_size: _Optional[int] = ..., decode_batch_size: _Optional[int] = ...) -> None: ... + +class SubscribeRuntimeEventsRequest(_message.Message): + __slots__ = ("types",) + TYPES_FIELD_NUMBER: _ClassVar[int] + types: _containers.RepeatedScalarFieldContainer[RuntimeEventType] + def __init__(self, types: _Optional[_Iterable[_Union[RuntimeEventType, str]]] = ...) -> None: ... + +class SubscribeRuntimeEventsResponse(_message.Message): + __slots__ = ("runtime_event", "error") + RUNTIME_EVENT_FIELD_NUMBER: _ClassVar[int] + ERROR_FIELD_NUMBER: _ClassVar[int] + runtime_event: RuntimeEvent + error: _error_pb2.EngineError + def __init__(self, runtime_event: _Optional[_Union[RuntimeEvent, _Mapping]] = ..., error: _Optional[_Union[_error_pb2.EngineError, _Mapping]] = ...) -> None: ... + +class RuntimeEvent(_message.Message): + __slots__ = ("event_id", "timestamp_unix_nanos", "type", "attributes") + class AttributesEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ... + EVENT_ID_FIELD_NUMBER: _ClassVar[int] + TIMESTAMP_UNIX_NANOS_FIELD_NUMBER: _ClassVar[int] + TYPE_FIELD_NUMBER: _ClassVar[int] + ATTRIBUTES_FIELD_NUMBER: _ClassVar[int] + event_id: str + timestamp_unix_nanos: int + type: RuntimeEventType + attributes: _containers.ScalarMap[str, str] + def __init__(self, event_id: _Optional[str] = ..., timestamp_unix_nanos: _Optional[int] = ..., type: _Optional[_Union[RuntimeEventType, str]] = ..., attributes: _Optional[_Mapping[str, str]] = ...) -> None: ... diff --git a/packages/python/src/openengine/v1/openengine_pb2.py b/packages/python/src/openengine/v1/openengine_pb2.py new file mode 100644 index 0000000..8fc18d7 --- /dev/null +++ b/packages/python/src/openengine/v1/openengine_pb2.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: openengine/v1/openengine.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + '', + 'openengine/v1/openengine.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from openengine.v1 import engine_pb2 as openengine_dot_v1_dot_engine__pb2 +from openengine.v1 import generation_pb2 as openengine_dot_v1_dot_generation__pb2 +from openengine.v1 import kv_pb2 as openengine_dot_v1_dot_kv__pb2 +from openengine.v1 import lifecycle_pb2 as openengine_dot_v1_dot_lifecycle__pb2 +from openengine.v1 import lora_pb2 as openengine_dot_v1_dot_lora__pb2 +from openengine.v1 import model_pb2 as openengine_dot_v1_dot_model__pb2 +from openengine.v1 import observability_pb2 as openengine_dot_v1_dot_observability__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1eopenengine/v1/openengine.proto\x12\ropenengine.v1\x1a\x1aopenengine/v1/engine.proto\x1a\x1eopenengine/v1/generation.proto\x1a\x16openengine/v1/kv.proto\x1a\x1dopenengine/v1/lifecycle.proto\x1a\x18openengine/v1/lora.proto\x1a\x19openengine/v1/model.proto\x1a!openengine/v1/observability.proto2\xa9\t\n\nOpenEngine\x12M\n\x08Generate\x12\x1e.openengine.v1.GenerateRequest\x1a\x1f.openengine.v1.GenerateResponse0\x01\x12O\n\rGetEngineInfo\x12#.openengine.v1.GetEngineInfoRequest\x1a\x19.openengine.v1.EngineInfo\x12L\n\x0cGetModelInfo\x12\".openengine.v1.GetModelInfoRequest\x1a\x18.openengine.v1.ModelInfo\x12\x41\n\x07GetLoad\x12\x1d.openengine.v1.GetLoadRequest\x1a\x17.openengine.v1.LoadInfo\x12\x45\n\x06Health\x12\x1c.openengine.v1.HealthRequest\x1a\x1d.openengine.v1.HealthResponse\x12\x42\n\x05\x41\x62ort\x12\x1b.openengine.v1.AbortRequest\x1a\x1c.openengine.v1.AbortResponse\x12\x44\n\x05\x44rain\x12\x1b.openengine.v1.DrainRequest\x1a\x1c.openengine.v1.DrainResponse0\x01\x12K\n\x08LoadLora\x12\x1e.openengine.v1.LoadLoraRequest\x1a\x1f.openengine.v1.LoadLoraResponse\x12Q\n\nUnloadLora\x12 .openengine.v1.UnloadLoraRequest\x1a!.openengine.v1.UnloadLoraResponse\x12N\n\tListLoras\x12\x1f.openengine.v1.ListLorasRequest\x1a .openengine.v1.ListLorasResponse\x12^\n\x12GetKvConnectorInfo\x12(.openengine.v1.GetKvConnectorInfoRequest\x1a\x1e.openengine.v1.KvConnectorInfo\x12\x66\n\x11GetKvEventSources\x12\'.openengine.v1.GetKvEventSourcesRequest\x1a(.openengine.v1.GetKvEventSourcesResponse\x12h\n\x11SubscribeKvEvents\x12\'.openengine.v1.SubscribeKvEventsRequest\x1a(.openengine.v1.SubscribeKvEventsResponse0\x01\x12w\n\x16SubscribeRuntimeEvents\x12,.openengine.v1.SubscribeRuntimeEventsRequest\x1a-.openengine.v1.SubscribeRuntimeEventsResponse0\x01\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'openengine.v1.openengine_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_OPENENGINE']._serialized_start=253 + _globals['_OPENENGINE']._serialized_end=1446 +# @@protoc_insertion_point(module_scope) diff --git a/packages/python/src/openengine/v1/openengine_pb2.pyi b/packages/python/src/openengine/v1/openengine_pb2.pyi new file mode 100644 index 0000000..27db98d --- /dev/null +++ b/packages/python/src/openengine/v1/openengine_pb2.pyi @@ -0,0 +1,11 @@ +from openengine.v1 import engine_pb2 as _engine_pb2 +from openengine.v1 import generation_pb2 as _generation_pb2 +from openengine.v1 import kv_pb2 as _kv_pb2 +from openengine.v1 import lifecycle_pb2 as _lifecycle_pb2 +from openengine.v1 import lora_pb2 as _lora_pb2 +from openengine.v1 import model_pb2 as _model_pb2 +from openengine.v1 import observability_pb2 as _observability_pb2 +from google.protobuf import descriptor as _descriptor +from typing import ClassVar as _ClassVar + +DESCRIPTOR: _descriptor.FileDescriptor diff --git a/packages/python/src/openengine/v1/openengine_pb2_grpc.py b/packages/python/src/openengine/v1/openengine_pb2_grpc.py new file mode 100644 index 0000000..3290cac --- /dev/null +++ b/packages/python/src/openengine/v1/openengine_pb2_grpc.py @@ -0,0 +1,668 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc +import warnings + +from openengine.v1 import engine_pb2 as openengine_dot_v1_dot_engine__pb2 +from openengine.v1 import generation_pb2 as openengine_dot_v1_dot_generation__pb2 +from openengine.v1 import kv_pb2 as openengine_dot_v1_dot_kv__pb2 +from openengine.v1 import lifecycle_pb2 as openengine_dot_v1_dot_lifecycle__pb2 +from openengine.v1 import lora_pb2 as openengine_dot_v1_dot_lora__pb2 +from openengine.v1 import model_pb2 as openengine_dot_v1_dot_model__pb2 +from openengine.v1 import observability_pb2 as openengine_dot_v1_dot_observability__pb2 + +GRPC_GENERATED_VERSION = '1.81.1' +GRPC_VERSION = grpc.__version__ +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + raise RuntimeError( + f'The grpc package installed is at version {GRPC_VERSION},' + + ' but the generated code in openengine/v1/openengine_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + ) + + +class OpenEngineStub: + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.Generate = channel.unary_stream( + '/openengine.v1.OpenEngine/Generate', + request_serializer=openengine_dot_v1_dot_generation__pb2.GenerateRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_generation__pb2.GenerateResponse.FromString, + _registered_method=True) + self.GetEngineInfo = channel.unary_unary( + '/openengine.v1.OpenEngine/GetEngineInfo', + request_serializer=openengine_dot_v1_dot_engine__pb2.GetEngineInfoRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_engine__pb2.EngineInfo.FromString, + _registered_method=True) + self.GetModelInfo = channel.unary_unary( + '/openengine.v1.OpenEngine/GetModelInfo', + request_serializer=openengine_dot_v1_dot_model__pb2.GetModelInfoRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_model__pb2.ModelInfo.FromString, + _registered_method=True) + self.GetLoad = channel.unary_unary( + '/openengine.v1.OpenEngine/GetLoad', + request_serializer=openengine_dot_v1_dot_observability__pb2.GetLoadRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_observability__pb2.LoadInfo.FromString, + _registered_method=True) + self.Health = channel.unary_unary( + '/openengine.v1.OpenEngine/Health', + request_serializer=openengine_dot_v1_dot_lifecycle__pb2.HealthRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_lifecycle__pb2.HealthResponse.FromString, + _registered_method=True) + self.Abort = channel.unary_unary( + '/openengine.v1.OpenEngine/Abort', + request_serializer=openengine_dot_v1_dot_lifecycle__pb2.AbortRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_lifecycle__pb2.AbortResponse.FromString, + _registered_method=True) + self.Drain = channel.unary_stream( + '/openengine.v1.OpenEngine/Drain', + request_serializer=openengine_dot_v1_dot_lifecycle__pb2.DrainRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_lifecycle__pb2.DrainResponse.FromString, + _registered_method=True) + self.LoadLora = channel.unary_unary( + '/openengine.v1.OpenEngine/LoadLora', + request_serializer=openengine_dot_v1_dot_lora__pb2.LoadLoraRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_lora__pb2.LoadLoraResponse.FromString, + _registered_method=True) + self.UnloadLora = channel.unary_unary( + '/openengine.v1.OpenEngine/UnloadLora', + request_serializer=openengine_dot_v1_dot_lora__pb2.UnloadLoraRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_lora__pb2.UnloadLoraResponse.FromString, + _registered_method=True) + self.ListLoras = channel.unary_unary( + '/openengine.v1.OpenEngine/ListLoras', + request_serializer=openengine_dot_v1_dot_lora__pb2.ListLorasRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_lora__pb2.ListLorasResponse.FromString, + _registered_method=True) + self.GetKvConnectorInfo = channel.unary_unary( + '/openengine.v1.OpenEngine/GetKvConnectorInfo', + request_serializer=openengine_dot_v1_dot_kv__pb2.GetKvConnectorInfoRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_kv__pb2.KvConnectorInfo.FromString, + _registered_method=True) + self.GetKvEventSources = channel.unary_unary( + '/openengine.v1.OpenEngine/GetKvEventSources', + request_serializer=openengine_dot_v1_dot_kv__pb2.GetKvEventSourcesRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_kv__pb2.GetKvEventSourcesResponse.FromString, + _registered_method=True) + self.SubscribeKvEvents = channel.unary_stream( + '/openengine.v1.OpenEngine/SubscribeKvEvents', + request_serializer=openengine_dot_v1_dot_kv__pb2.SubscribeKvEventsRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_kv__pb2.SubscribeKvEventsResponse.FromString, + _registered_method=True) + self.SubscribeRuntimeEvents = channel.unary_stream( + '/openengine.v1.OpenEngine/SubscribeRuntimeEvents', + request_serializer=openengine_dot_v1_dot_observability__pb2.SubscribeRuntimeEventsRequest.SerializeToString, + response_deserializer=openengine_dot_v1_dot_observability__pb2.SubscribeRuntimeEventsResponse.FromString, + _registered_method=True) + + +class OpenEngineServicer: + """Missing associated documentation comment in .proto file.""" + + def Generate(self, request, context): + """Core inference path. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetEngineInfo(self, request, context): + """Runtime metadata and scheduling state. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetModelInfo(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetLoad(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Health(self, request, context): + """Health and lifecycle. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Abort(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Drain(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def LoadLora(self, request, context): + """LoRA lifecycle. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def UnloadLora(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListLoras(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetKvConnectorInfo(self, request, context): + """Disaggregated serving / KV transfer. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetKvEventSources(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SubscribeKvEvents(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SubscribeRuntimeEvents(self, request, context): + """Structured runtime events for planners/controllers. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_OpenEngineServicer_to_server(servicer, server): + rpc_method_handlers = { + 'Generate': grpc.unary_stream_rpc_method_handler( + servicer.Generate, + request_deserializer=openengine_dot_v1_dot_generation__pb2.GenerateRequest.FromString, + response_serializer=openengine_dot_v1_dot_generation__pb2.GenerateResponse.SerializeToString, + ), + 'GetEngineInfo': grpc.unary_unary_rpc_method_handler( + servicer.GetEngineInfo, + request_deserializer=openengine_dot_v1_dot_engine__pb2.GetEngineInfoRequest.FromString, + response_serializer=openengine_dot_v1_dot_engine__pb2.EngineInfo.SerializeToString, + ), + 'GetModelInfo': grpc.unary_unary_rpc_method_handler( + servicer.GetModelInfo, + request_deserializer=openengine_dot_v1_dot_model__pb2.GetModelInfoRequest.FromString, + response_serializer=openengine_dot_v1_dot_model__pb2.ModelInfo.SerializeToString, + ), + 'GetLoad': grpc.unary_unary_rpc_method_handler( + servicer.GetLoad, + request_deserializer=openengine_dot_v1_dot_observability__pb2.GetLoadRequest.FromString, + response_serializer=openengine_dot_v1_dot_observability__pb2.LoadInfo.SerializeToString, + ), + 'Health': grpc.unary_unary_rpc_method_handler( + servicer.Health, + request_deserializer=openengine_dot_v1_dot_lifecycle__pb2.HealthRequest.FromString, + response_serializer=openengine_dot_v1_dot_lifecycle__pb2.HealthResponse.SerializeToString, + ), + 'Abort': grpc.unary_unary_rpc_method_handler( + servicer.Abort, + request_deserializer=openengine_dot_v1_dot_lifecycle__pb2.AbortRequest.FromString, + response_serializer=openengine_dot_v1_dot_lifecycle__pb2.AbortResponse.SerializeToString, + ), + 'Drain': grpc.unary_stream_rpc_method_handler( + servicer.Drain, + request_deserializer=openengine_dot_v1_dot_lifecycle__pb2.DrainRequest.FromString, + response_serializer=openengine_dot_v1_dot_lifecycle__pb2.DrainResponse.SerializeToString, + ), + 'LoadLora': grpc.unary_unary_rpc_method_handler( + servicer.LoadLora, + request_deserializer=openengine_dot_v1_dot_lora__pb2.LoadLoraRequest.FromString, + response_serializer=openengine_dot_v1_dot_lora__pb2.LoadLoraResponse.SerializeToString, + ), + 'UnloadLora': grpc.unary_unary_rpc_method_handler( + servicer.UnloadLora, + request_deserializer=openengine_dot_v1_dot_lora__pb2.UnloadLoraRequest.FromString, + response_serializer=openengine_dot_v1_dot_lora__pb2.UnloadLoraResponse.SerializeToString, + ), + 'ListLoras': grpc.unary_unary_rpc_method_handler( + servicer.ListLoras, + request_deserializer=openengine_dot_v1_dot_lora__pb2.ListLorasRequest.FromString, + response_serializer=openengine_dot_v1_dot_lora__pb2.ListLorasResponse.SerializeToString, + ), + 'GetKvConnectorInfo': grpc.unary_unary_rpc_method_handler( + servicer.GetKvConnectorInfo, + request_deserializer=openengine_dot_v1_dot_kv__pb2.GetKvConnectorInfoRequest.FromString, + response_serializer=openengine_dot_v1_dot_kv__pb2.KvConnectorInfo.SerializeToString, + ), + 'GetKvEventSources': grpc.unary_unary_rpc_method_handler( + servicer.GetKvEventSources, + request_deserializer=openengine_dot_v1_dot_kv__pb2.GetKvEventSourcesRequest.FromString, + response_serializer=openengine_dot_v1_dot_kv__pb2.GetKvEventSourcesResponse.SerializeToString, + ), + 'SubscribeKvEvents': grpc.unary_stream_rpc_method_handler( + servicer.SubscribeKvEvents, + request_deserializer=openengine_dot_v1_dot_kv__pb2.SubscribeKvEventsRequest.FromString, + response_serializer=openengine_dot_v1_dot_kv__pb2.SubscribeKvEventsResponse.SerializeToString, + ), + 'SubscribeRuntimeEvents': grpc.unary_stream_rpc_method_handler( + servicer.SubscribeRuntimeEvents, + request_deserializer=openengine_dot_v1_dot_observability__pb2.SubscribeRuntimeEventsRequest.FromString, + response_serializer=openengine_dot_v1_dot_observability__pb2.SubscribeRuntimeEventsResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'openengine.v1.OpenEngine', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('openengine.v1.OpenEngine', rpc_method_handlers) + + + # This class is part of an EXPERIMENTAL API. +class OpenEngine: + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def Generate(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream( + request, + target, + '/openengine.v1.OpenEngine/Generate', + openengine_dot_v1_dot_generation__pb2.GenerateRequest.SerializeToString, + openengine_dot_v1_dot_generation__pb2.GenerateResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetEngineInfo(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/GetEngineInfo', + openengine_dot_v1_dot_engine__pb2.GetEngineInfoRequest.SerializeToString, + openengine_dot_v1_dot_engine__pb2.EngineInfo.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetModelInfo(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/GetModelInfo', + openengine_dot_v1_dot_model__pb2.GetModelInfoRequest.SerializeToString, + openengine_dot_v1_dot_model__pb2.ModelInfo.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetLoad(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/GetLoad', + openengine_dot_v1_dot_observability__pb2.GetLoadRequest.SerializeToString, + openengine_dot_v1_dot_observability__pb2.LoadInfo.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Health(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/Health', + openengine_dot_v1_dot_lifecycle__pb2.HealthRequest.SerializeToString, + openengine_dot_v1_dot_lifecycle__pb2.HealthResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Abort(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/Abort', + openengine_dot_v1_dot_lifecycle__pb2.AbortRequest.SerializeToString, + openengine_dot_v1_dot_lifecycle__pb2.AbortResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Drain(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream( + request, + target, + '/openengine.v1.OpenEngine/Drain', + openengine_dot_v1_dot_lifecycle__pb2.DrainRequest.SerializeToString, + openengine_dot_v1_dot_lifecycle__pb2.DrainResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LoadLora(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/LoadLora', + openengine_dot_v1_dot_lora__pb2.LoadLoraRequest.SerializeToString, + openengine_dot_v1_dot_lora__pb2.LoadLoraResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def UnloadLora(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/UnloadLora', + openengine_dot_v1_dot_lora__pb2.UnloadLoraRequest.SerializeToString, + openengine_dot_v1_dot_lora__pb2.UnloadLoraResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ListLoras(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/ListLoras', + openengine_dot_v1_dot_lora__pb2.ListLorasRequest.SerializeToString, + openengine_dot_v1_dot_lora__pb2.ListLorasResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetKvConnectorInfo(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/GetKvConnectorInfo', + openengine_dot_v1_dot_kv__pb2.GetKvConnectorInfoRequest.SerializeToString, + openengine_dot_v1_dot_kv__pb2.KvConnectorInfo.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetKvEventSources(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/openengine.v1.OpenEngine/GetKvEventSources', + openengine_dot_v1_dot_kv__pb2.GetKvEventSourcesRequest.SerializeToString, + openengine_dot_v1_dot_kv__pb2.GetKvEventSourcesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SubscribeKvEvents(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream( + request, + target, + '/openengine.v1.OpenEngine/SubscribeKvEvents', + openengine_dot_v1_dot_kv__pb2.SubscribeKvEventsRequest.SerializeToString, + openengine_dot_v1_dot_kv__pb2.SubscribeKvEventsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SubscribeRuntimeEvents(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream( + request, + target, + '/openengine.v1.OpenEngine/SubscribeRuntimeEvents', + openengine_dot_v1_dot_observability__pb2.SubscribeRuntimeEventsRequest.SerializeToString, + openengine_dot_v1_dot_observability__pb2.SubscribeRuntimeEventsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/packages/python/tests/test_bindings.py b/packages/python/tests/test_bindings.py new file mode 100644 index 0000000..09442db --- /dev/null +++ b/packages/python/tests/test_bindings.py @@ -0,0 +1,41 @@ +import unittest + +import grpc + +from openengine import SCHEMA_RELEASE, SCHEMA_REVISION, __version__ +from openengine.v1.generation_pb2 import GenerateRequest +from openengine.v1.openengine_pb2_grpc import OpenEngineStub + + +class BindingsTest(unittest.TestCase): + def test_request_round_trip_preserves_optional_zero(self) -> None: + request = GenerateRequest( + request_id="python-smoke", + model="test-model", + prompt="Hello", + priority=0, + ) + + decoded = GenerateRequest.FromString(request.SerializeToString()) + + self.assertEqual(decoded.request_id, "python-smoke") + self.assertEqual(decoded.WhichOneof("input"), "prompt") + self.assertTrue(decoded.HasField("priority")) + self.assertEqual(decoded.priority, 0) + + def test_client_stub_can_be_constructed(self) -> None: + channel = grpc.insecure_channel("localhost:1") + self.addCleanup(channel.close) + + stub = OpenEngineStub(channel) + + self.assertTrue(callable(stub.Generate)) + self.assertTrue(callable(stub.GetEngineInfo)) + + def test_package_metadata_matches_schema(self) -> None: + self.assertEqual(SCHEMA_REVISION, 1) + self.assertEqual(SCHEMA_RELEASE, f"v{__version__}") + + +if __name__ == "__main__": + unittest.main() diff --git a/packages/rust/openengine-proto/Cargo.toml b/packages/rust/openengine-proto/Cargo.toml new file mode 100644 index 0000000..63f8e89 --- /dev/null +++ b/packages/rust/openengine-proto/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "openengine-proto" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true +description = "Generated Rust bindings for the OpenEngine gRPC protocol" +readme = "README.md" +keywords = ["grpc", "inference", "protobuf"] +categories = ["api-bindings", "network-programming"] + +[dependencies] +prost = "0.14.4" +prost-types = "0.14.4" +tonic = "0.14.6" +tonic-prost = "0.14.6" diff --git a/packages/rust/openengine-proto/README.md b/packages/rust/openengine-proto/README.md new file mode 100644 index 0000000..21d2706 --- /dev/null +++ b/packages/rust/openengine-proto/README.md @@ -0,0 +1,24 @@ + + +# OpenEngine Rust bindings + +Generated Prost messages and Tonic client/server bindings for the +[`openengine.v1`](https://github.com/ai-dynamo/openengine/tree/main/proto/openengine/v1) +protocol. + +```bash +cargo add openengine-proto +``` + +```rust +use openengine_proto::openengine::v1::{ + open_engine_client::OpenEngineClient, + GenerateRequest, +}; +``` + +The crate contains generated Rust source and a protobuf descriptor set. +Consumer builds do not run `protoc`. diff --git a/packages/rust/openengine-proto/examples/cross_language_fixture.rs b/packages/rust/openengine-proto/examples/cross_language_fixture.rs new file mode 100644 index 0000000..3842981 --- /dev/null +++ b/packages/rust/openengine-proto/examples/cross_language_fixture.rs @@ -0,0 +1,39 @@ +use std::env; +use std::fs; +use std::path::Path; + +use openengine_proto::openengine::v1::{generate_request, GenerateRequest}; +use prost::Message; + +fn fixture() -> GenerateRequest { + GenerateRequest { + request_id: "cross-language".into(), + model: "test-model".into(), + input: Some(generate_request::Input::Prompt("Hello".into())), + priority: Some(0), + ..Default::default() + } +} + +fn encode(path: &Path) { + fs::write(path, fixture().encode_to_vec()).unwrap(); +} + +fn decode(path: &Path) { + let bytes = fs::read(path).unwrap(); + let request = GenerateRequest::decode(bytes.as_slice()).unwrap(); + assert_eq!(request, fixture()); +} + +fn main() { + let mut args = env::args_os().skip(1); + let operation = args.next().expect("expected encode or decode"); + let path = args.next().expect("expected fixture path"); + assert!(args.next().is_none(), "unexpected additional arguments"); + + match operation.to_str() { + Some("encode") => encode(Path::new(&path)), + Some("decode") => decode(Path::new(&path)), + _ => panic!("expected encode or decode"), + } +} diff --git a/packages/rust/openengine-proto/src/generated/openengine.v1.rs b/packages/rust/openengine-proto/src/generated/openengine.v1.rs new file mode 100644 index 0000000..a7ea8bb --- /dev/null +++ b/packages/rust/openengine-proto/src/generated/openengine.v1.rs @@ -0,0 +1,2594 @@ +// This file is @generated by prost-build. +/// Accepted failures emit one terminal EngineError and close with OK. +/// Validation and transport failures use non-OK gRPC status instead. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct EngineError { + #[prost(enumeration = "ErrorCode", tag = "1")] + pub code: i32, + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, + /// Retry may succeed without changing the request. + #[prost(bool, tag = "3")] + pub retryable: bool, + /// Zero permits immediate retry. + #[prost(uint64, optional, tag = "4")] + pub retry_after_ms: ::core::option::Option, + /// Machine-readable context. + #[prost(message, optional, tag = "5")] + pub details: ::core::option::Option<::prost_types::Struct>, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ErrorCode { + Unspecified = 0, + InvalidArgument = 1, + UnsupportedFeature = 2, + RoleMismatch = 3, + ModelNotFound = 4, + Overloaded = 5, + RequestNotFound = 6, + DuplicateRequest = 7, + KvSessionNotFound = 8, + KvTransferFailed = 9, + Cancelled = 10, + Draining = 11, + Internal = 12, +} +impl ErrorCode { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ERROR_CODE_UNSPECIFIED", + Self::InvalidArgument => "ERROR_CODE_INVALID_ARGUMENT", + Self::UnsupportedFeature => "ERROR_CODE_UNSUPPORTED_FEATURE", + Self::RoleMismatch => "ERROR_CODE_ROLE_MISMATCH", + Self::ModelNotFound => "ERROR_CODE_MODEL_NOT_FOUND", + Self::Overloaded => "ERROR_CODE_OVERLOADED", + Self::RequestNotFound => "ERROR_CODE_REQUEST_NOT_FOUND", + Self::DuplicateRequest => "ERROR_CODE_DUPLICATE_REQUEST", + Self::KvSessionNotFound => "ERROR_CODE_KV_SESSION_NOT_FOUND", + Self::KvTransferFailed => "ERROR_CODE_KV_TRANSFER_FAILED", + Self::Cancelled => "ERROR_CODE_CANCELLED", + Self::Draining => "ERROR_CODE_DRAINING", + Self::Internal => "ERROR_CODE_INTERNAL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ERROR_CODE_UNSPECIFIED" => Some(Self::Unspecified), + "ERROR_CODE_INVALID_ARGUMENT" => Some(Self::InvalidArgument), + "ERROR_CODE_UNSUPPORTED_FEATURE" => Some(Self::UnsupportedFeature), + "ERROR_CODE_ROLE_MISMATCH" => Some(Self::RoleMismatch), + "ERROR_CODE_MODEL_NOT_FOUND" => Some(Self::ModelNotFound), + "ERROR_CODE_OVERLOADED" => Some(Self::Overloaded), + "ERROR_CODE_REQUEST_NOT_FOUND" => Some(Self::RequestNotFound), + "ERROR_CODE_DUPLICATE_REQUEST" => Some(Self::DuplicateRequest), + "ERROR_CODE_KV_SESSION_NOT_FOUND" => Some(Self::KvSessionNotFound), + "ERROR_CODE_KV_TRANSFER_FAILED" => Some(Self::KvTransferFailed), + "ERROR_CODE_CANCELLED" => Some(Self::Cancelled), + "ERROR_CODE_DRAINING" => Some(Self::Draining), + "ERROR_CODE_INTERNAL" => Some(Self::Internal), + _ => None, + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct KvSessionRef { + #[prost(string, tag = "1")] + pub session_id: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub transfer_backend: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "3")] + pub endpoints: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "4")] + pub dp_rank: u32, + /// Engine-specific KV-transfer parameters (e.g. NixlConnector + /// remote_host / remote_port / tp_size / remote_block_ids / do_remote\_\*), + /// carried as a Struct so numbers, booleans, and arrays survive the wire with + /// their JSON type intact. Struct numbers are IEEE-754 doubles (exact only to + /// 2^53); carry larger integer values as strings or use a dedicated field. + #[prost(message, optional, tag = "5")] + pub attributes_struct: ::core::option::Option<::prost_types::Struct>, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct KvEndpoint { + #[prost(string, tag = "1")] + pub host: ::prost::alloc::string::String, + #[prost(uint32, tag = "2")] + pub port: u32, + /// grpc, nixl, ucx, tcp, shm, etc. + #[prost(string, tag = "3")] + pub protocol: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GetKvConnectorInfoRequest {} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct KvConnectorInfo { + #[prost(bool, optional, tag = "1")] + pub enabled: ::core::option::Option, + #[prost(string, tag = "2")] + pub transfer_backend: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "3")] + pub local_endpoints: ::prost::alloc::vec::Vec, + #[prost(string, repeated, tag = "4")] + pub supported_protocols: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, optional, tag = "5")] + pub supports_remote_prefill: ::core::option::Option, + #[prost(bool, optional, tag = "6")] + pub supports_decode_pull: ::core::option::Option, + #[prost(bool, optional, tag = "7")] + pub supports_abort_cleanup: ::core::option::Option, + #[prost(bool, optional, tag = "8")] + pub supports_drain: ::core::option::Option, + #[prost(uint32, optional, tag = "9")] + pub schema_version: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GetKvEventSourcesRequest { + #[prost(uint32, repeated, tag = "1")] + pub data_parallel_ranks: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetKvEventSourcesResponse { + #[prost(message, repeated, tag = "1")] + pub sources: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct KvEventSource { + /// grpc, zmq + #[prost(string, tag = "1")] + pub transport: ::prost::alloc::string::String, + /// Connectable address. MUST use a routable host, never a bind wildcard. + #[prost(message, optional, tag = "2")] + pub endpoint_addr: ::core::option::Option, + #[prost(string, tag = "3")] + pub topic: ::prost::alloc::string::String, + /// optional, for ZMQ replay + #[prost(string, tag = "4")] + pub replay_endpoint: ::prost::alloc::string::String, + #[prost(uint32, optional, tag = "5")] + pub data_parallel_rank: ::core::option::Option, + /// protobuf, msgpack + #[prost(string, tag = "6")] + pub encoding: ::prost::alloc::string::String, + #[prost(uint32, optional, tag = "7")] + pub schema_version: ::core::option::Option, + #[prost(uint32, optional, tag = "8")] + pub buffer_steps: ::core::option::Option, + #[prost(uint32, optional, tag = "9")] + pub hwm: ::core::option::Option, + #[prost(uint32, optional, tag = "10")] + pub max_queue_size: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct SubscribeKvEventsRequest { + #[prost(uint32, repeated, tag = "1")] + pub data_parallel_ranks: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "2")] + pub include_snapshot: bool, + #[prost(uint64, tag = "3")] + pub start_sequence_number: u64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SubscribeKvEventsResponse { + #[prost(oneof = "subscribe_kv_events_response::Event", tags = "1, 2")] + pub event: ::core::option::Option, +} +/// Nested message and enum types in `SubscribeKvEventsResponse`. +pub mod subscribe_kv_events_response { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Event { + #[prost(message, tag = "1")] + Batch(super::KvEventBatch), + /// Terminal. + #[prost(message, tag = "2")] + Error(super::EngineError), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct KvEventBatch { + #[prost(uint64, tag = "1")] + pub sequence_number: u64, + #[prost(uint64, tag = "2")] + pub timestamp_unix_nanos: u64, + #[prost(uint32, tag = "3")] + pub data_parallel_rank: u32, + #[prost(message, repeated, tag = "4")] + pub events: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct KvEvent { + #[prost(string, tag = "1")] + pub request_id: ::prost::alloc::string::String, + #[prost(message, optional, tag = "2")] + pub kv_session: ::core::option::Option, + #[prost(oneof = "kv_event::Event", tags = "10, 11, 12")] + pub event: ::core::option::Option, +} +/// Nested message and enum types in `KvEvent`. +pub mod kv_event { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Event { + #[prost(message, tag = "10")] + BlockStored(super::BlockStored), + #[prost(message, tag = "11")] + BlockRemoved(super::BlockRemoved), + #[prost(message, tag = "12")] + AllBlocksCleared(super::AllBlocksCleared), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlockStored { + #[prost(message, repeated, tag = "1")] + pub block_hashes: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub parent_block_hash: ::core::option::Option, + #[prost(uint32, repeated, tag = "3")] + pub token_ids: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "4")] + pub block_size: u32, + #[prost(int64, tag = "5")] + pub lora_id: i64, + #[prost(string, tag = "6")] + pub lora_name: ::prost::alloc::string::String, + #[prost(enumeration = "StorageMedium", tag = "7")] + pub medium: i32, + /// vLLM-compatible optional metadata for reconstructing block keys. + #[prost(message, repeated, tag = "20")] + pub extra_keys: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "21")] + pub group_idx: u32, + #[prost(string, tag = "22")] + pub kv_cache_spec_kind: ::prost::alloc::string::String, + #[prost(uint32, tag = "23")] + pub kv_cache_spec_sliding_window: u32, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlockRemoved { + #[prost(message, repeated, tag = "1")] + pub block_hashes: ::prost::alloc::vec::Vec, + #[prost(enumeration = "StorageMedium", tag = "2")] + pub medium: i32, + #[prost(uint32, tag = "3")] + pub group_idx: u32, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct AllBlocksCleared {} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct KvBlockHash { + #[prost(bytes = "vec", tag = "1")] + pub value: ::prost::alloc::vec::Vec, + /// int64, string, bytes, engine_specific + #[prost(string, tag = "2")] + pub encoding: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct OpaqueKeyTuple { + #[prost(string, repeated, tag = "1")] + pub values: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum StorageMedium { + Unspecified = 0, + Gpu = 1, + CpuPinned = 2, + Disk = 3, + External = 4, +} +impl StorageMedium { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "STORAGE_MEDIUM_UNSPECIFIED", + Self::Gpu => "STORAGE_MEDIUM_GPU", + Self::CpuPinned => "STORAGE_MEDIUM_CPU_PINNED", + Self::Disk => "STORAGE_MEDIUM_DISK", + Self::External => "STORAGE_MEDIUM_EXTERNAL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "STORAGE_MEDIUM_UNSPECIFIED" => Some(Self::Unspecified), + "STORAGE_MEDIUM_GPU" => Some(Self::Gpu), + "STORAGE_MEDIUM_CPU_PINNED" => Some(Self::CpuPinned), + "STORAGE_MEDIUM_DISK" => Some(Self::Disk), + "STORAGE_MEDIUM_EXTERNAL" => Some(Self::External), + _ => None, + } + } +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GetEngineInfoRequest {} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct EngineInfo { + /// sglang, vllm, tensorrt_llm, etc. + #[prost(string, tag = "1")] + pub engine_name: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub engine_version: ::prost::alloc::string::String, + #[prost(enumeration = "EngineRole", tag = "3")] + pub role: i32, + #[prost(string, tag = "4")] + pub instance_id: ::prost::alloc::string::String, + #[prost(string, repeated, tag = "5")] + pub supported_models: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(message, optional, tag = "6")] + pub parallelism: ::core::option::Option, + #[prost(message, optional, tag = "7")] + pub kv_connector: ::core::option::Option, + /// Monotonic wire contract revision; zero is invalid. + #[prost(uint32, tag = "8")] + pub schema_revision: u32, + /// Oldest compatible client revision. + #[prost(uint32, tag = "9")] + pub minimum_client_revision: u32, + /// Immutable release or source tag for this schema. + #[prost(string, tag = "10")] + pub schema_release: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ParallelismInfo { + #[prost(uint32, optional, tag = "1")] + pub tensor_parallel_size: ::core::option::Option, + #[prost(uint32, optional, tag = "2")] + pub pipeline_parallel_size: ::core::option::Option, + #[prost(uint32, optional, tag = "3")] + pub data_parallel_size: ::core::option::Option, + #[prost(uint32, optional, tag = "4")] + pub data_parallel_rank: ::core::option::Option, + #[prost(uint32, optional, tag = "5")] + pub data_parallel_start_rank: ::core::option::Option, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum EngineRole { + Unspecified = 0, + Aggregated = 1, + Prefill = 2, + Decode = 3, +} +impl EngineRole { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ENGINE_ROLE_UNSPECIFIED", + Self::Aggregated => "ENGINE_ROLE_AGGREGATED", + Self::Prefill => "ENGINE_ROLE_PREFILL", + Self::Decode => "ENGINE_ROLE_DECODE", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ENGINE_ROLE_UNSPECIFIED" => Some(Self::Unspecified), + "ENGINE_ROLE_AGGREGATED" => Some(Self::Aggregated), + "ENGINE_ROLE_PREFILL" => Some(Self::Prefill), + "ENGINE_ROLE_DECODE" => Some(Self::Decode), + _ => None, + } + } +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct TokenIds { + #[prost(uint32, repeated, tag = "1")] + pub ids: ::prost::alloc::vec::Vec, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct SamplingParams { + #[prost(double, optional, tag = "1")] + pub temperature: ::core::option::Option, + #[prost(double, optional, tag = "2")] + pub top_p: ::core::option::Option, + #[prost(int32, optional, tag = "3")] + pub top_k: ::core::option::Option, + #[prost(double, optional, tag = "4")] + pub min_p: ::core::option::Option, + #[prost(double, optional, tag = "5")] + pub frequency_penalty: ::core::option::Option, + #[prost(double, optional, tag = "6")] + pub presence_penalty: ::core::option::Option, + #[prost(double, optional, tag = "7")] + pub repetition_penalty: ::core::option::Option, + #[prost(uint64, optional, tag = "8")] + pub seed: ::core::option::Option, + #[prost(uint32, optional, tag = "9")] + pub num_sequences: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StoppingOptions { + #[prost(uint32, optional, tag = "1")] + pub max_tokens: ::core::option::Option, + #[prost(uint32, optional, tag = "2")] + pub min_tokens: ::core::option::Option, + #[prost(message, repeated, tag = "3")] + pub conditions: ::prost::alloc::vec::Vec, + #[prost(bool, optional, tag = "4")] + pub ignore_eos: ::core::option::Option, + #[prost(bool, optional, tag = "5")] + pub include_stop_in_output: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ResponseOptions { + #[prost(bool, optional, tag = "1")] + pub return_prompt_logprobs: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub prompt_candidates: ::core::option::Option, + #[prost(bool, optional, tag = "3")] + pub return_output_logprobs: ::core::option::Option, + #[prost(message, optional, tag = "4")] + pub output_candidates: ::core::option::Option, + #[prost(uint32, optional, tag = "5")] + pub prompt_logprob_start: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct CandidateTokenSelection { + #[prost(oneof = "candidate_token_selection::Selection", tags = "1, 2, 3")] + pub selection: ::core::option::Option, +} +/// Nested message and enum types in `CandidateTokenSelection`. +pub mod candidate_token_selection { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum Selection { + #[prost(uint32, tag = "1")] + TopN(u32), + #[prost(message, tag = "2")] + TokenIds(super::TokenIds), + #[prost(message, tag = "3")] + All(super::AllCandidates), + } +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct AllCandidates {} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct KvOptions { + #[prost(message, optional, tag = "1")] + pub session: ::core::option::Option, + #[prost(uint32, optional, tag = "2")] + pub data_parallel_rank: ::core::option::Option, + #[prost(bool, optional, tag = "3")] + pub bypass_prefix_cache: ::core::option::Option, + #[prost(string, optional, tag = "4")] + pub cache_salt: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct StopCondition { + #[prost(oneof = "stop_condition::Condition", tags = "1, 2")] + pub condition: ::core::option::Option, +} +/// Nested message and enum types in `StopCondition`. +pub mod stop_condition { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum Condition { + #[prost(string, tag = "1")] + StopText(::prost::alloc::string::String), + #[prost(uint32, tag = "2")] + StopTokenId(u32), + } +} +/// Constrained / guided decoding spec. At most one of `guide` should be set. +/// The engine enforces the constraint during sampling via its grammar backend +/// (xgrammar / outlines / llguidance); clients cannot apply it post-hoc. +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GuidedDecoding { + /// Optional grammar backend override (e.g. "xgrammar", "outlines", + /// "llguidance"). Empty = engine default. + #[prost(string, tag = "7")] + pub backend: ::prost::alloc::string::String, + #[prost(oneof = "guided_decoding::Guide", tags = "1, 2, 3, 4, 5, 6")] + pub guide: ::core::option::Option, +} +/// Nested message and enum types in `GuidedDecoding`. +pub mod guided_decoding { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum Guide { + /// output conforms to this JSON schema + #[prost(string, tag = "1")] + JsonSchema(::prost::alloc::string::String), + /// output matches this regex + #[prost(string, tag = "2")] + Regex(::prost::alloc::string::String), + /// output follows this EBNF / context-free grammar + #[prost(string, tag = "3")] + EbnfGrammar(::prost::alloc::string::String), + /// xgrammar structural-tag constraint (JSON string) + #[prost(string, tag = "4")] + StructuralTag(::prost::alloc::string::String), + #[prost(message, tag = "5")] + Choice(super::ChoiceConstraint), + #[prost(message, tag = "6")] + JsonObject(super::JsonObjectConstraint), + } +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ChoiceConstraint { + #[prost(string, repeated, tag = "1")] + pub choices: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct JsonObjectConstraint {} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenerateRequest { + #[prost(string, tag = "1")] + pub request_id: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub model: ::prost::alloc::string::String, + #[prost(message, optional, tag = "5")] + pub sampling: ::core::option::Option, + #[prost(message, optional, tag = "6")] + pub stopping: ::core::option::Option, + #[prost(message, optional, tag = "7")] + pub response: ::core::option::Option, + #[prost(message, optional, tag = "8")] + pub kv: ::core::option::Option, + #[prost(message, optional, tag = "9")] + pub guided: ::core::option::Option, + /// Multimodal inputs. Order is significant: the i-th item aligns with the + /// i-th (un-expanded) placeholder marker carried in the prompt/token_ids. + /// The engine fetches/decodes and preprocesses each item, then expands the + /// marker into the model's replacement run. Empty for text-only requests. + #[prost(message, repeated, tag = "10")] + pub media: ::prost::alloc::vec::Vec, + /// Loaded LoRA adapter name to apply to this request. Empty = base model. + /// ModelInfo.supports_lora advertises whether lifecycle and selection are + /// available through OpenEngine. + #[prost(string, tag = "11")] + pub lora_name: ::prost::alloc::string::String, + /// Higher values receive higher scheduling priority. + #[prost(int32, optional, tag = "12")] + pub priority: ::core::option::Option, + /// Optional request metadata for tracing/admission/routing. + #[prost(map = "string, string", tag = "13")] + pub metadata: ::std::collections::HashMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, + #[prost(oneof = "generate_request::Input", tags = "3, 4")] + pub input: ::core::option::Option, +} +/// Nested message and enum types in `GenerateRequest`. +pub mod generate_request { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum Input { + #[prost(string, tag = "3")] + Prompt(::prost::alloc::string::String), + #[prost(message, tag = "4")] + TokenIds(super::TokenIds), + } +} +/// A single multimodal input. Exactly one `source` should be set. The engine +/// owns fetch, decode, and preprocessing, so pre-decoded or RDMA media +/// descriptors are not represented here. +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct MediaItem { + #[prost(enumeration = "Modality", tag = "1")] + pub modality: i32, + /// optional, hints raw_bytes decode + #[prost(string, tag = "5")] + pub mime_type: ::prost::alloc::string::String, + /// optional caller id / mm_hash + #[prost(string, tag = "6")] + pub uuid: ::prost::alloc::string::String, + #[prost(oneof = "media_item::Source", tags = "2, 3, 4")] + pub source: ::core::option::Option, +} +/// Nested message and enum types in `MediaItem`. +pub mod media_item { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum Source { + /// http(s):// -- engine fetches + #[prost(string, tag = "2")] + Url(::prost::alloc::string::String), + /// data:;base64,\<...> -- engine decodes + #[prost(string, tag = "3")] + DataUri(::prost::alloc::string::String), + /// pre-fetched bytes -- engine still preprocesses + #[prost(bytes, tag = "4")] + RawBytes(::prost::alloc::vec::Vec), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenerateResponse { + #[prost(string, tag = "1")] + pub request_id: ::prost::alloc::string::String, + /// Cumulative request usage; only set on the final response. + #[prost(message, optional, tag = "10")] + pub usage: ::core::option::Option, + /// PromptOutput, PrefillReady, and EngineError are request-scoped. + /// TokenOutput and GenerationFinished are output-scoped. + #[prost(oneof = "generate_response::Event", tags = "2, 3, 4, 5, 6")] + pub event: ::core::option::Option, +} +/// Nested message and enum types in `GenerateResponse`. +pub mod generate_response { + /// PromptOutput, PrefillReady, and EngineError are request-scoped. + /// TokenOutput and GenerationFinished are output-scoped. + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Event { + #[prost(message, tag = "2")] + Prompt(super::PromptOutput), + #[prost(message, tag = "3")] + Token(super::TokenOutput), + #[prost(message, tag = "4")] + PrefillReady(super::PrefillReady), + #[prost(message, tag = "5")] + Finished(super::GenerationFinished), + #[prost(message, tag = "6")] + Error(super::EngineError), + } +} +/// Request-scoped prompt token information, emitted at most once. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PromptOutput { + #[prost(message, repeated, tag = "1")] + pub tokens: ::prost::alloc::vec::Vec, +} +/// An incremental output delta. Tokens and text are never cumulative. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TokenOutput { + /// Required, including for output zero. + #[prost(uint32, optional, tag = "1")] + pub output_index: ::core::option::Option, + #[prost(message, repeated, tag = "2")] + pub tokens: ::prost::alloc::vec::Vec, + #[prost(string, tag = "3")] + pub text: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TokenInfo { + #[prost(uint32, tag = "1")] + pub token_id: u32, + #[prost(string, tag = "2")] + pub token: ::prost::alloc::string::String, + #[prost(double, optional, tag = "3")] + pub logprob: ::core::option::Option, + #[prost(uint32, optional, tag = "4")] + pub rank: ::core::option::Option, + #[prost(message, repeated, tag = "5")] + pub candidates: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LogProb { + #[prost(uint32, tag = "1")] + pub token_id: u32, + #[prost(double, tag = "2")] + pub logprob: f64, + #[prost(string, tag = "3")] + pub token: ::prost::alloc::string::String, + #[prost(uint32, optional, tag = "4")] + pub rank: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PrefillReady { + #[prost(message, optional, tag = "1")] + pub kv_session: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GenerationFinished { + /// Required, including for output zero. + #[prost(uint32, optional, tag = "1")] + pub output_index: ::core::option::Option, + #[prost(enumeration = "FinishReason", tag = "2")] + pub reason: i32, + #[prost(string, tag = "3")] + pub message: ::prost::alloc::string::String, + #[prost(message, optional, tag = "4")] + pub stop_match: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct StopMatch { + #[prost(oneof = "stop_match::Match", tags = "1, 2, 3")] + pub r#match: ::core::option::Option, +} +/// Nested message and enum types in `StopMatch`. +pub mod stop_match { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum Match { + #[prost(uint32, tag = "1")] + StopTokenId(u32), + #[prost(string, tag = "2")] + StopText(::prost::alloc::string::String), + #[prost(uint32, tag = "3")] + EosTokenId(u32), + } +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct Usage { + #[prost(uint32, tag = "1")] + pub prompt_tokens: u32, + #[prost(uint32, tag = "2")] + pub completion_tokens: u32, + #[prost(uint32, tag = "3")] + pub total_tokens: u32, + #[prost(uint32, optional, tag = "4")] + pub cached_prompt_tokens: ::core::option::Option, + #[prost(uint32, optional, tag = "5")] + pub reasoning_tokens: ::core::option::Option, +} +/// Multimodal modality discriminator. 0 is treated as image for forward +/// compatibility with senders that omit the field. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum Modality { + Unspecified = 0, + Image = 1, + Video = 2, + Audio = 3, +} +impl Modality { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "MODALITY_UNSPECIFIED", + Self::Image => "MODALITY_IMAGE", + Self::Video => "MODALITY_VIDEO", + Self::Audio => "MODALITY_AUDIO", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "MODALITY_UNSPECIFIED" => Some(Self::Unspecified), + "MODALITY_IMAGE" => Some(Self::Image), + "MODALITY_VIDEO" => Some(Self::Video), + "MODALITY_AUDIO" => Some(Self::Audio), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum FinishReason { + Unspecified = 0, + Stop = 1, + Length = 2, + Cancelled = 3, +} +impl FinishReason { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "FINISH_REASON_UNSPECIFIED", + Self::Stop => "FINISH_REASON_STOP", + Self::Length => "FINISH_REASON_LENGTH", + Self::Cancelled => "FINISH_REASON_CANCELLED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "FINISH_REASON_UNSPECIFIED" => Some(Self::Unspecified), + "FINISH_REASON_STOP" => Some(Self::Stop), + "FINISH_REASON_LENGTH" => Some(Self::Length), + "FINISH_REASON_CANCELLED" => Some(Self::Cancelled), + _ => None, + } + } +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct HealthRequest { + /// False means a lightweight readiness/liveness check. True asks the engine to + /// run a role-appropriate minimal inference probe and report it as a check. + #[prost(bool, tag = "1")] + pub include_inference_probe: bool, + /// Optional. Used when include_inference_probe is true. Empty means engine + /// default served model. + #[prost(string, tag = "2")] + pub model: ::prost::alloc::string::String, + /// Optional expected role for role-specific inference probes. + #[prost(enumeration = "EngineRole", tag = "3")] + pub role: i32, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HealthResponse { + #[prost(enumeration = "HealthState", tag = "1")] + pub state: i32, + #[prost(message, repeated, tag = "2")] + pub checks: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct HealthCheck { + /// grpc, scheduler, model, kv_connector, role, inference_probe + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(enumeration = "HealthState", tag = "2")] + pub state: i32, + #[prost(string, tag = "3")] + pub message: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AbortRequest { + #[prost(oneof = "abort_request::Target", tags = "1, 2, 3")] + pub target: ::core::option::Option, +} +/// Nested message and enum types in `AbortRequest`. +pub mod abort_request { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Target { + #[prost(string, tag = "1")] + RequestId(::prost::alloc::string::String), + #[prost(message, tag = "2")] + KvSession(super::KvSessionRef), + #[prost(message, tag = "3")] + AllRequests(super::AllRequests), + } +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct AllRequests {} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct AbortResponse { + #[prost(enumeration = "AbortStatus", tag = "1")] + pub status: i32, + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct DrainRequest { + #[prost(bool, tag = "1")] + pub stop_accepting_new_requests: bool, + /// Absent means no deadline; zero is immediate. + #[prost(uint32, optional, tag = "2")] + pub deadline_ms: ::core::option::Option, + #[prost(bool, tag = "3")] + pub abort_after_deadline: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DrainResponse { + #[prost(uint32, optional, tag = "2")] + pub in_flight_requests: ::core::option::Option, + #[prost(uint32, optional, tag = "3")] + pub open_kv_sessions: ::core::option::Option, + #[prost(string, tag = "4")] + pub message: ::prost::alloc::string::String, + #[prost(oneof = "drain_response::Event", tags = "1, 5")] + pub event: ::core::option::Option, +} +/// Nested message and enum types in `DrainResponse`. +pub mod drain_response { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Event { + /// Progress or successful completion. + #[prost(enumeration = "super::DrainState", tag = "1")] + State(i32), + /// Terminal failure. + #[prost(message, tag = "5")] + Error(super::EngineError), + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum HealthState { + Unspecified = 0, + Starting = 1, + Ready = 2, + Degraded = 3, + Draining = 4, + NotReady = 5, +} +impl HealthState { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "HEALTH_STATE_UNSPECIFIED", + Self::Starting => "HEALTH_STATE_STARTING", + Self::Ready => "HEALTH_STATE_READY", + Self::Degraded => "HEALTH_STATE_DEGRADED", + Self::Draining => "HEALTH_STATE_DRAINING", + Self::NotReady => "HEALTH_STATE_NOT_READY", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "HEALTH_STATE_UNSPECIFIED" => Some(Self::Unspecified), + "HEALTH_STATE_STARTING" => Some(Self::Starting), + "HEALTH_STATE_READY" => Some(Self::Ready), + "HEALTH_STATE_DEGRADED" => Some(Self::Degraded), + "HEALTH_STATE_DRAINING" => Some(Self::Draining), + "HEALTH_STATE_NOT_READY" => Some(Self::NotReady), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AbortStatus { + Unspecified = 0, + Aborted = 1, + AlreadyFinished = 2, +} +impl AbortStatus { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ABORT_STATUS_UNSPECIFIED", + Self::Aborted => "ABORT_STATUS_ABORTED", + Self::AlreadyFinished => "ABORT_STATUS_ALREADY_FINISHED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ABORT_STATUS_UNSPECIFIED" => Some(Self::Unspecified), + "ABORT_STATUS_ABORTED" => Some(Self::Aborted), + "ABORT_STATUS_ALREADY_FINISHED" => Some(Self::AlreadyFinished), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum DrainState { + Unspecified = 0, + Started = 1, + InProgress = 2, + Complete = 3, +} +impl DrainState { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "DRAIN_STATE_UNSPECIFIED", + Self::Started => "DRAIN_STATE_STARTED", + Self::InProgress => "DRAIN_STATE_IN_PROGRESS", + Self::Complete => "DRAIN_STATE_COMPLETE", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "DRAIN_STATE_UNSPECIFIED" => Some(Self::Unspecified), + "DRAIN_STATE_STARTED" => Some(Self::Started), + "DRAIN_STATE_IN_PROGRESS" => Some(Self::InProgress), + "DRAIN_STATE_COMPLETE" => Some(Self::Complete), + _ => None, + } + } +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct LoraAdapter { + #[prost(int64, tag = "1")] + pub lora_id: i64, + #[prost(string, tag = "2")] + pub lora_name: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub source_path: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct LoadLoraRequest { + #[prost(message, optional, tag = "1")] + pub adapter: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct LoadLoraResponse { + #[prost(message, optional, tag = "1")] + pub adapter: ::core::option::Option, + #[prost(bool, tag = "2")] + pub already_loaded: bool, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct UnloadLoraRequest { + #[prost(string, tag = "1")] + pub lora_name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct UnloadLoraResponse { + #[prost(message, optional, tag = "1")] + pub adapter: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ListLorasRequest {} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListLorasResponse { + #[prost(message, repeated, tag = "1")] + pub adapters: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GetModelInfoRequest { + #[prost(string, tag = "1")] + pub model: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ModelInfo { + #[prost(string, tag = "1")] + pub model_id: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub served_model_name: ::prost::alloc::string::String, + #[prost(string, repeated, tag = "3")] + pub served_model_aliases: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(uint32, optional, tag = "4")] + pub max_context_length: ::core::option::Option, + #[prost(uint32, optional, tag = "5")] + pub max_output_tokens: ::core::option::Option, + #[prost(uint32, optional, tag = "6")] + pub kv_block_size: ::core::option::Option, + #[prost(uint64, optional, tag = "7")] + pub total_kv_blocks: ::core::option::Option, + #[prost(uint64, optional, tag = "8")] + pub max_running_requests: ::core::option::Option, + #[prost(uint64, optional, tag = "9")] + pub max_batched_tokens: ::core::option::Option, + #[prost(string, repeated, tag = "10")] + pub tokenizer_modes: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, optional, tag = "20")] + pub supports_text_input: ::core::option::Option, + #[prost(bool, optional, tag = "21")] + pub supports_token_ids_input: ::core::option::Option, + #[prost(message, optional, tag = "22")] + pub generation: ::core::option::Option, + #[prost(bool, optional, tag = "23")] + pub supports_lora: ::core::option::Option, + #[prost(bool, optional, tag = "24")] + pub supports_multimodal: ::core::option::Option, + /// Engine-advertised response parser names. Clients can apply these to a + /// model's output stream for tool-call extraction or reasoning separation. + /// Empty means no parser is configured for this model. + #[prost(string, tag = "25")] + pub reasoning_parser: ::prost::alloc::string::String, + #[prost(string, tag = "26")] + pub tool_call_parser: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GenerationCapabilities { + #[prost(message, optional, tag = "1")] + pub prompt_logprobs: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub output_logprobs: ::core::option::Option, + #[prost(message, optional, tag = "3")] + pub guided_decoding: ::core::option::Option, + #[prost(uint32, optional, tag = "4")] + pub max_num_sequences: ::core::option::Option, + #[prost(bool, optional, tag = "5")] + pub supports_priority: ::core::option::Option, + #[prost(bool, optional, tag = "6")] + pub supports_stop_in_output: ::core::option::Option, + #[prost(bool, optional, tag = "7")] + pub supports_cache_salt: ::core::option::Option, + #[prost(bool, optional, tag = "8")] + pub supports_prefix_cache_bypass: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct LogprobCapabilities { + #[prost(bool, optional, tag = "1")] + pub supported: ::core::option::Option, + #[prost(enumeration = "CandidateTokenSelectionMode", repeated, tag = "2")] + pub candidate_selection_modes: ::prost::alloc::vec::Vec, + #[prost(uint32, optional, tag = "3")] + pub max_top_n: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GuidedDecodingCapabilities { + #[prost(bool, optional, tag = "1")] + pub supported: ::core::option::Option, + #[prost(enumeration = "GuidedDecodingMode", repeated, tag = "2")] + pub modes: ::prost::alloc::vec::Vec, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum CandidateTokenSelectionMode { + Unspecified = 0, + TopN = 1, + TokenIds = 2, + All = 3, +} +impl CandidateTokenSelectionMode { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "CANDIDATE_TOKEN_SELECTION_MODE_UNSPECIFIED", + Self::TopN => "CANDIDATE_TOKEN_SELECTION_MODE_TOP_N", + Self::TokenIds => "CANDIDATE_TOKEN_SELECTION_MODE_TOKEN_IDS", + Self::All => "CANDIDATE_TOKEN_SELECTION_MODE_ALL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "CANDIDATE_TOKEN_SELECTION_MODE_UNSPECIFIED" => Some(Self::Unspecified), + "CANDIDATE_TOKEN_SELECTION_MODE_TOP_N" => Some(Self::TopN), + "CANDIDATE_TOKEN_SELECTION_MODE_TOKEN_IDS" => Some(Self::TokenIds), + "CANDIDATE_TOKEN_SELECTION_MODE_ALL" => Some(Self::All), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum GuidedDecodingMode { + Unspecified = 0, + JsonSchema = 1, + Regex = 2, + EbnfGrammar = 3, + StructuralTag = 4, + Choice = 5, + JsonObject = 6, +} +impl GuidedDecodingMode { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "GUIDED_DECODING_MODE_UNSPECIFIED", + Self::JsonSchema => "GUIDED_DECODING_MODE_JSON_SCHEMA", + Self::Regex => "GUIDED_DECODING_MODE_REGEX", + Self::EbnfGrammar => "GUIDED_DECODING_MODE_EBNF_GRAMMAR", + Self::StructuralTag => "GUIDED_DECODING_MODE_STRUCTURAL_TAG", + Self::Choice => "GUIDED_DECODING_MODE_CHOICE", + Self::JsonObject => "GUIDED_DECODING_MODE_JSON_OBJECT", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "GUIDED_DECODING_MODE_UNSPECIFIED" => Some(Self::Unspecified), + "GUIDED_DECODING_MODE_JSON_SCHEMA" => Some(Self::JsonSchema), + "GUIDED_DECODING_MODE_REGEX" => Some(Self::Regex), + "GUIDED_DECODING_MODE_EBNF_GRAMMAR" => Some(Self::EbnfGrammar), + "GUIDED_DECODING_MODE_STRUCTURAL_TAG" => Some(Self::StructuralTag), + "GUIDED_DECODING_MODE_CHOICE" => Some(Self::Choice), + "GUIDED_DECODING_MODE_JSON_OBJECT" => Some(Self::JsonObject), + _ => None, + } + } +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GetLoadRequest { + #[prost(bool, tag = "1")] + pub include_per_rank: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LoadInfo { + #[prost(string, tag = "1")] + pub instance_id: ::prost::alloc::string::String, + #[prost(uint64, optional, tag = "2")] + pub timestamp_unix_nanos: ::core::option::Option, + #[prost(uint32, optional, tag = "3")] + pub running_requests: ::core::option::Option, + #[prost(uint32, optional, tag = "4")] + pub queued_requests: ::core::option::Option, + #[prost(uint32, optional, tag = "5")] + pub active_kv_sessions: ::core::option::Option, + #[prost(uint64, optional, tag = "6")] + pub used_kv_blocks: ::core::option::Option, + #[prost(uint64, optional, tag = "7")] + pub total_kv_blocks: ::core::option::Option, + #[prost(uint64, optional, tag = "8")] + pub running_tokens: ::core::option::Option, + #[prost(uint64, optional, tag = "9")] + pub waiting_tokens: ::core::option::Option, + #[prost(uint32, optional, tag = "10")] + pub prefill_batch_size: ::core::option::Option, + #[prost(uint32, optional, tag = "11")] + pub decode_batch_size: ::core::option::Option, + #[prost(message, repeated, tag = "20")] + pub ranks: ::prost::alloc::vec::Vec, + #[prost(map = "string, string", tag = "30")] + pub attributes: ::std::collections::HashMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct RankLoadInfo { + #[prost(uint32, optional, tag = "1")] + pub data_parallel_rank: ::core::option::Option, + #[prost(uint32, optional, tag = "2")] + pub running_requests: ::core::option::Option, + #[prost(uint32, optional, tag = "3")] + pub queued_requests: ::core::option::Option, + #[prost(uint64, optional, tag = "4")] + pub used_kv_blocks: ::core::option::Option, + #[prost(uint64, optional, tag = "5")] + pub total_kv_blocks: ::core::option::Option, + #[prost(uint32, optional, tag = "6")] + pub prefill_batch_size: ::core::option::Option, + #[prost(uint32, optional, tag = "7")] + pub decode_batch_size: ::core::option::Option, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct SubscribeRuntimeEventsRequest { + #[prost(enumeration = "RuntimeEventType", repeated, tag = "1")] + pub types: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SubscribeRuntimeEventsResponse { + #[prost(oneof = "subscribe_runtime_events_response::Event", tags = "1, 2")] + pub event: ::core::option::Option, +} +/// Nested message and enum types in `SubscribeRuntimeEventsResponse`. +pub mod subscribe_runtime_events_response { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Event { + #[prost(message, tag = "1")] + RuntimeEvent(super::RuntimeEvent), + /// Terminal. + #[prost(message, tag = "2")] + Error(super::EngineError), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RuntimeEvent { + #[prost(string, tag = "1")] + pub event_id: ::prost::alloc::string::String, + #[prost(uint64, tag = "2")] + pub timestamp_unix_nanos: u64, + #[prost(enumeration = "RuntimeEventType", tag = "3")] + pub r#type: i32, + #[prost(map = "string, string", tag = "4")] + pub attributes: ::std::collections::HashMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum RuntimeEventType { + Unspecified = 0, + ForwardPass = 1, + Batch = 2, + Queue = 3, + Transfer = 4, +} +impl RuntimeEventType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "RUNTIME_EVENT_TYPE_UNSPECIFIED", + Self::ForwardPass => "RUNTIME_EVENT_TYPE_FORWARD_PASS", + Self::Batch => "RUNTIME_EVENT_TYPE_BATCH", + Self::Queue => "RUNTIME_EVENT_TYPE_QUEUE", + Self::Transfer => "RUNTIME_EVENT_TYPE_TRANSFER", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "RUNTIME_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "RUNTIME_EVENT_TYPE_FORWARD_PASS" => Some(Self::ForwardPass), + "RUNTIME_EVENT_TYPE_BATCH" => Some(Self::Batch), + "RUNTIME_EVENT_TYPE_QUEUE" => Some(Self::Queue), + "RUNTIME_EVENT_TYPE_TRANSFER" => Some(Self::Transfer), + _ => None, + } + } +} +/// Generated client implementations. +pub mod open_engine_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct OpenEngineClient { + inner: tonic::client::Grpc, + } + impl OpenEngineClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl OpenEngineClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> OpenEngineClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + std::marker::Send + std::marker::Sync, + { + OpenEngineClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// Core inference path. + pub async fn generate( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response>, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/Generate", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "Generate")); + self.inner.server_streaming(req, path, codec).await + } + /// Runtime metadata and scheduling state. + pub async fn get_engine_info( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/GetEngineInfo", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "GetEngineInfo")); + self.inner.unary(req, path, codec).await + } + pub async fn get_model_info( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/GetModelInfo", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "GetModelInfo")); + self.inner.unary(req, path, codec).await + } + pub async fn get_load( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/GetLoad", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "GetLoad")); + self.inner.unary(req, path, codec).await + } + /// Health and lifecycle. + pub async fn health( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/Health", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "Health")); + self.inner.unary(req, path, codec).await + } + pub async fn abort( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/Abort", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "Abort")); + self.inner.unary(req, path, codec).await + } + pub async fn drain( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response>, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/Drain", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "Drain")); + self.inner.server_streaming(req, path, codec).await + } + /// LoRA lifecycle. + pub async fn load_lora( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/LoadLora", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "LoadLora")); + self.inner.unary(req, path, codec).await + } + pub async fn unload_lora( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/UnloadLora", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "UnloadLora")); + self.inner.unary(req, path, codec).await + } + pub async fn list_loras( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/ListLoras", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("openengine.v1.OpenEngine", "ListLoras")); + self.inner.unary(req, path, codec).await + } + /// Disaggregated serving / KV transfer. + pub async fn get_kv_connector_info( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/GetKvConnectorInfo", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new("openengine.v1.OpenEngine", "GetKvConnectorInfo"), + ); + self.inner.unary(req, path, codec).await + } + pub async fn get_kv_event_sources( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/GetKvEventSources", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new("openengine.v1.OpenEngine", "GetKvEventSources"), + ); + self.inner.unary(req, path, codec).await + } + pub async fn subscribe_kv_events( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response>, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/SubscribeKvEvents", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new("openengine.v1.OpenEngine", "SubscribeKvEvents"), + ); + self.inner.server_streaming(req, path, codec).await + } + /// Structured runtime events for planners/controllers. + pub async fn subscribe_runtime_events( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response< + tonic::codec::Streaming, + >, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/openengine.v1.OpenEngine/SubscribeRuntimeEvents", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new("openengine.v1.OpenEngine", "SubscribeRuntimeEvents"), + ); + self.inner.server_streaming(req, path, codec).await + } + } +} +/// Generated server implementations. +pub mod open_engine_server { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with OpenEngineServer. + #[async_trait] + pub trait OpenEngine: std::marker::Send + std::marker::Sync + 'static { + /// Server streaming response type for the Generate method. + type GenerateStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, + > + + std::marker::Send + + 'static; + /// Core inference path. + async fn generate( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + /// Runtime metadata and scheduling state. + async fn get_engine_info( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn get_model_info( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn get_load( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + /// Health and lifecycle. + async fn health( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn abort( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + /// Server streaming response type for the Drain method. + type DrainStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, + > + + std::marker::Send + + 'static; + async fn drain( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + /// LoRA lifecycle. + async fn load_lora( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn unload_lora( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn list_loras( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + /// Disaggregated serving / KV transfer. + async fn get_kv_connector_info( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn get_kv_event_sources( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + /// Server streaming response type for the SubscribeKvEvents method. + type SubscribeKvEventsStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result< + super::SubscribeKvEventsResponse, + tonic::Status, + >, + > + + std::marker::Send + + 'static; + async fn subscribe_kv_events( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + /// Server streaming response type for the SubscribeRuntimeEvents method. + type SubscribeRuntimeEventsStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result< + super::SubscribeRuntimeEventsResponse, + tonic::Status, + >, + > + + std::marker::Send + + 'static; + /// Structured runtime events for planners/controllers. + async fn subscribe_runtime_events( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + } + #[derive(Debug)] + pub struct OpenEngineServer { + inner: Arc, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + impl OpenEngineServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for OpenEngineServer + where + T: OpenEngine, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + match req.uri().path() { + "/openengine.v1.OpenEngine/Generate" => { + #[allow(non_camel_case_types)] + struct GenerateSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::ServerStreamingService + for GenerateSvc { + type Response = super::GenerateResponse; + type ResponseStream = T::GenerateStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::generate(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GenerateSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/GetEngineInfo" => { + #[allow(non_camel_case_types)] + struct GetEngineInfoSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::UnaryService + for GetEngineInfoSvc { + type Response = super::EngineInfo; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_engine_info(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetEngineInfoSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/GetModelInfo" => { + #[allow(non_camel_case_types)] + struct GetModelInfoSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::UnaryService + for GetModelInfoSvc { + type Response = super::ModelInfo; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_model_info(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetModelInfoSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/GetLoad" => { + #[allow(non_camel_case_types)] + struct GetLoadSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::UnaryService + for GetLoadSvc { + type Response = super::LoadInfo; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_load(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetLoadSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/Health" => { + #[allow(non_camel_case_types)] + struct HealthSvc(pub Arc); + impl tonic::server::UnaryService + for HealthSvc { + type Response = super::HealthResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::health(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = HealthSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/Abort" => { + #[allow(non_camel_case_types)] + struct AbortSvc(pub Arc); + impl tonic::server::UnaryService + for AbortSvc { + type Response = super::AbortResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::abort(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = AbortSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/Drain" => { + #[allow(non_camel_case_types)] + struct DrainSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::ServerStreamingService + for DrainSvc { + type Response = super::DrainResponse; + type ResponseStream = T::DrainStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::drain(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = DrainSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/LoadLora" => { + #[allow(non_camel_case_types)] + struct LoadLoraSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::UnaryService + for LoadLoraSvc { + type Response = super::LoadLoraResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::load_lora(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = LoadLoraSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/UnloadLora" => { + #[allow(non_camel_case_types)] + struct UnloadLoraSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::UnaryService + for UnloadLoraSvc { + type Response = super::UnloadLoraResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::unload_lora(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = UnloadLoraSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/ListLoras" => { + #[allow(non_camel_case_types)] + struct ListLorasSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::UnaryService + for ListLorasSvc { + type Response = super::ListLorasResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::list_loras(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = ListLorasSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/GetKvConnectorInfo" => { + #[allow(non_camel_case_types)] + struct GetKvConnectorInfoSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::UnaryService + for GetKvConnectorInfoSvc { + type Response = super::KvConnectorInfo; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_kv_connector_info(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetKvConnectorInfoSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/GetKvEventSources" => { + #[allow(non_camel_case_types)] + struct GetKvEventSourcesSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::UnaryService + for GetKvEventSourcesSvc { + type Response = super::GetKvEventSourcesResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_kv_event_sources(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetKvEventSourcesSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/SubscribeKvEvents" => { + #[allow(non_camel_case_types)] + struct SubscribeKvEventsSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::ServerStreamingService< + super::SubscribeKvEventsRequest, + > for SubscribeKvEventsSvc { + type Response = super::SubscribeKvEventsResponse; + type ResponseStream = T::SubscribeKvEventsStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::subscribe_kv_events(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = SubscribeKvEventsSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/openengine.v1.OpenEngine/SubscribeRuntimeEvents" => { + #[allow(non_camel_case_types)] + struct SubscribeRuntimeEventsSvc(pub Arc); + impl< + T: OpenEngine, + > tonic::server::ServerStreamingService< + super::SubscribeRuntimeEventsRequest, + > for SubscribeRuntimeEventsSvc { + type Response = super::SubscribeRuntimeEventsResponse; + type ResponseStream = T::SubscribeRuntimeEventsStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::subscribe_runtime_events(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = SubscribeRuntimeEventsSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + let mut response = http::Response::new( + tonic::body::Body::default(), + ); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) + }) + } + } + } + } + impl Clone for OpenEngineServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "openengine.v1.OpenEngine"; + impl tonic::server::NamedService for OpenEngineServer { + const NAME: &'static str = SERVICE_NAME; + } +} diff --git a/packages/rust/openengine-proto/src/generated/openengine_descriptor.bin b/packages/rust/openengine-proto/src/generated/openengine_descriptor.bin new file mode 100644 index 0000000..f99bc0e Binary files /dev/null and b/packages/rust/openengine-proto/src/generated/openengine_descriptor.bin differ diff --git a/packages/rust/openengine-proto/src/lib.rs b/packages/rust/openengine-proto/src/lib.rs new file mode 100644 index 0000000..d09df73 --- /dev/null +++ b/packages/rust/openengine-proto/src/lib.rs @@ -0,0 +1,18 @@ +//! Generated Prost messages and Tonic services for OpenEngine. + +/// Monotonically increasing revision of the packaged wire contract. +pub const SCHEMA_REVISION: u32 = 1; + +/// Immutable OpenEngine release corresponding to these bindings. +pub const SCHEMA_RELEASE: &str = concat!("v", env!("CARGO_PKG_VERSION")); + +/// Serialized descriptors for the complete `openengine.v1` package. +pub const FILE_DESCRIPTOR_SET: &[u8] = include_bytes!("generated/openengine_descriptor.bin"); + +/// Modules arranged to match the protobuf package name. +pub mod openengine { + /// Version 1 of the OpenEngine wire API. + pub mod v1 { + include!("generated/openengine.v1.rs"); + } +} diff --git a/packages/rust/openengine-proto/tests/bindings.rs b/packages/rust/openengine-proto/tests/bindings.rs new file mode 100644 index 0000000..5be8322 --- /dev/null +++ b/packages/rust/openengine-proto/tests/bindings.rs @@ -0,0 +1,45 @@ +use openengine_proto::openengine::v1::{generate_request, GenerateRequest}; +use openengine_proto::{FILE_DESCRIPTOR_SET, SCHEMA_RELEASE, SCHEMA_REVISION}; +use prost::Message; +use prost_types::FileDescriptorSet; + +#[test] +fn request_round_trip_preserves_optional_zero() { + let request = GenerateRequest { + request_id: "rust-smoke".into(), + model: "test-model".into(), + input: Some(generate_request::Input::Prompt("Hello".into())), + priority: Some(0), + ..Default::default() + }; + + let decoded = GenerateRequest::decode(request.encode_to_vec().as_slice()).unwrap(); + + assert_eq!(decoded.request_id, "rust-smoke"); + assert_eq!(decoded.priority, Some(0)); + assert!(matches!( + decoded.input, + Some(generate_request::Input::Prompt(prompt)) if prompt == "Hello" + )); +} + +#[test] +fn descriptor_set_contains_openengine_service() { + let descriptors = FileDescriptorSet::decode(FILE_DESCRIPTOR_SET).unwrap(); + let service_file = descriptors + .file + .iter() + .find(|file| file.name.as_deref() == Some("openengine/v1/openengine.proto")) + .unwrap(); + + assert!(service_file + .service + .iter() + .any(|service| service.name.as_deref() == Some("OpenEngine"))); +} + +#[test] +fn package_metadata_matches_schema() { + assert_eq!(SCHEMA_REVISION, 1); + assert_eq!(SCHEMA_RELEASE, concat!("v", env!("CARGO_PKG_VERSION"))); +} diff --git a/proto/openengine/v1/README.md b/proto/openengine/v1/README.md index 9b451ca..432a00c 100644 --- a/proto/openengine/v1/README.md +++ b/proto/openengine/v1/README.md @@ -23,3 +23,7 @@ share the same package and together define the API. Generate bindings from every `.proto` file in this directory. Compiling only `openengine.proto` does not generate bindings for its imported message files. + +OpenEngine publishes pre-generated bindings from this package for Python and +Rust. Their sources and package manifests live under [`packages/`](../../../packages/), +and the generation entry points live under [`scripts/`](../../../scripts/). diff --git a/scripts/check-generated.sh b/scripts/check-generated.sh new file mode 100755 index 0000000..385e0af --- /dev/null +++ b/scripts/check-generated.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -euo pipefail + +repository=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) + +"${repository}/scripts/generate-python.sh" +"${repository}/scripts/generate-rust.sh" + +if [[ -n $(git -C "${repository}" status --porcelain --untracked-files=all -- \ + packages/python/src/openengine/v1 \ + packages/rust/openengine-proto/src/generated) ]]; then + git -C "${repository}" diff -- \ + packages/python/src/openengine/v1 \ + packages/rust/openengine-proto/src/generated + git -C "${repository}" status --short -- \ + packages/python/src/openengine/v1 \ + packages/rust/openengine-proto/src/generated + echo "Generated bindings are out of date. Run the generation scripts and commit the result." >&2 + exit 1 +fi diff --git a/scripts/check_release_version.py b/scripts/check_release_version.py new file mode 100755 index 0000000..94a506a --- /dev/null +++ b/scripts/check_release_version.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Verify that a release tag matches every published package version.""" + +from __future__ import annotations + +import re +import sys +import tomllib +from pathlib import Path + + +def read_toml(path: Path) -> dict: + with path.open("rb") as source: + return tomllib.load(source) + + +def main() -> int: + if len(sys.argv) != 2 or not re.fullmatch(r"v[0-9]+\.[0-9]+\.[0-9]+", sys.argv[1]): + print("usage: check_release_version.py vMAJOR.MINOR.PATCH", file=sys.stderr) + return 2 + + repository = Path(__file__).resolve().parent.parent + tag_version = sys.argv[1].removeprefix("v") + python_version = read_toml(repository / "packages/python/pyproject.toml")["project"]["version"] + rust_version = read_toml(repository / "Cargo.toml")["workspace"]["package"]["version"] + + versions = { + "release tag": tag_version, + "Python package": python_version, + "Rust crate": rust_version, + } + if len(set(versions.values())) != 1: + for label, version in versions.items(): + print(f"{label}: {version}", file=sys.stderr) + return 1 + + print(f"OpenEngine release versions match: {tag_version}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/cross_language_fixture.py b/scripts/cross_language_fixture.py new file mode 100755 index 0000000..2e51898 --- /dev/null +++ b/scripts/cross_language_fixture.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +"""Encode or verify the shared Python/Rust wire fixture.""" + +from __future__ import annotations + +import sys +from pathlib import Path + +from openengine.v1.generation_pb2 import GenerateRequest + + +def fixture() -> GenerateRequest: + return GenerateRequest( + request_id="cross-language", + model="test-model", + prompt="Hello", + priority=0, + ) + + +def main() -> int: + if len(sys.argv) != 3 or sys.argv[1] not in {"encode", "decode"}: + print("usage: cross_language_fixture.py (encode|decode) PATH", file=sys.stderr) + return 2 + + operation, raw_path = sys.argv[1:] + path = Path(raw_path) + if operation == "encode": + path.write_bytes(fixture().SerializeToString()) + return 0 + + decoded = GenerateRequest.FromString(path.read_bytes()) + if decoded != fixture(): + print("decoded Rust fixture does not match the Python fixture", file=sys.stderr) + return 1 + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/generate-python.sh b/scripts/generate-python.sh new file mode 100755 index 0000000..6986245 --- /dev/null +++ b/scripts/generate-python.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail + +repository=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +python=${PYTHON:-python3} +output="${repository}/packages/python/src" +export LC_ALL=C + +if ! "${python}" -c "import grpc_tools.protoc" 2>/dev/null; then + echo "grpcio-tools is required; install grpcio-tools==1.81.1" >&2 + exit 1 +fi + +protos=("${repository}"/proto/openengine/v1/*.proto) + +for generated in \ + "${output}"/openengine/v1/*_pb2.py \ + "${output}"/openengine/v1/*_pb2.pyi \ + "${output}"/openengine/v1/*_pb2_grpc.py; do + if [[ -e "${generated}" ]]; then + rm -- "${generated}" + fi +done + +"${python}" -m grpc_tools.protoc \ + -I "${repository}/proto" \ + --python_out="${output}" \ + --pyi_out="${output}" \ + "${protos[@]}" + +"${python}" -m grpc_tools.protoc \ + -I "${repository}/proto" \ + --grpc_python_out="${output}" \ + "${repository}/proto/openengine/v1/openengine.proto" diff --git a/scripts/generate-rust.sh b/scripts/generate-rust.sh new file mode 100755 index 0000000..1b4e2d7 --- /dev/null +++ b/scripts/generate-rust.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -euo pipefail + +repository=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) + +cargo run \ + --locked \ + --manifest-path "${repository}/Cargo.toml" \ + --package openengine-rust-codegen \ + -- "${repository}" diff --git a/scripts/test-cross-language.sh b/scripts/test-cross-language.sh new file mode 100755 index 0000000..5269f56 --- /dev/null +++ b/scripts/test-cross-language.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail + +repository=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +temporary_directory=$(mktemp -d) +python=${PYTHON:-python3} +trap 'rm -rf "${temporary_directory}"' EXIT + +export PYTHONPATH="${repository}/packages/python/src${PYTHONPATH:+:${PYTHONPATH}}" + +"${python}" "${repository}/scripts/cross_language_fixture.py" \ + encode "${temporary_directory}/python.bin" +cargo run --quiet \ + --manifest-path "${repository}/Cargo.toml" \ + --package openengine-proto \ + --example cross_language_fixture \ + -- decode "${temporary_directory}/python.bin" + +cargo run --quiet \ + --manifest-path "${repository}/Cargo.toml" \ + --package openengine-proto \ + --example cross_language_fixture \ + -- encode "${temporary_directory}/rust.bin" +"${python}" "${repository}/scripts/cross_language_fixture.py" \ + decode "${temporary_directory}/rust.bin" diff --git a/tools/rust-codegen/Cargo.toml b/tools/rust-codegen/Cargo.toml new file mode 100644 index 0000000..8c24a5d --- /dev/null +++ b/tools/rust-codegen/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "openengine-rust-codegen" +version = "0.0.0" +edition.workspace = true +rust-version.workspace = true +license.workspace = true +publish = false + +[dependencies] +protoc-bin-vendored = "=3.2.0" +tonic-prost-build = "=0.14.6" diff --git a/tools/rust-codegen/src/main.rs b/tools/rust-codegen/src/main.rs new file mode 100644 index 0000000..665b664 --- /dev/null +++ b/tools/rust-codegen/src/main.rs @@ -0,0 +1,39 @@ +use std::env; +use std::error::Error; +use std::fs; +use std::path::PathBuf; + +fn main() -> Result<(), Box> { + let repository = env::args_os() + .nth(1) + .map(PathBuf::from) + .unwrap_or(env::current_dir()?); + let proto_root = repository.join("proto"); + let package_root = proto_root.join("openengine/v1"); + let output = repository.join("packages/rust/openengine-proto/src/generated"); + + fs::create_dir_all(&output)?; + + let mut protos = fs::read_dir(&package_root)? + .filter_map(Result::ok) + .map(|entry| entry.path()) + .filter(|path| { + path.extension() + .is_some_and(|extension| extension == "proto") + }) + .collect::>(); + protos.sort(); + + let protoc = protoc_bin_vendored::protoc_bin_path()?; + let protobuf_include = protoc_bin_vendored::include_path()?; + env::set_var("PROTOC", protoc); + + tonic_prost_build::configure() + .build_client(true) + .build_server(true) + .file_descriptor_set_path(output.join("openengine_descriptor.bin")) + .out_dir(&output) + .compile_protos(&protos, &[proto_root, protobuf_include])?; + + Ok(()) +}