From 6f57900d6f2f49ab6f184a4851eff5ec31339f22 Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 01:58:15 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=F0=9F=94=A7=20(pyproject):=20Switch=20buil?= =?UTF-8?q?d-backend=20from=20hatchling=20to=20maturin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Platform-tagged wheels with bundled Rust binary require maturin (PyO3 build tool). Hatchling's pure-Python wheel backend cannot produce per-platform wheels needed for the [runtime] extra. AAASM-1215 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ebf0310..8fec611 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +requires = ["maturin>=1.7,<2"] +build-backend = "maturin" [project] name = "agent-assembly" From 791abb482f562ed8d9ed5dfc4770fcd46bd5a9f5 Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 01:58:27 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E2=9C=A8=20(pyproject):=20Add=20[tool.matu?= =?UTF-8?q?rin]=20config=20for=20PyO3=20extension=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires maturin to the existing rust/aa-ffi-python crate. module-name matches the #[pyclass(module = "agent_assembly._core")] annotation in rust/aa-ffi-python/src/lib.rs so the compiled cdylib lands at agent_assembly/_core inside the wheel. python-source = "." tells maturin the pure-Python package root is the repo root (i.e. the agent_assembly/ tree alongside pyproject.toml). AAASM-1215 --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 8fec611..964960e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,6 +77,13 @@ default-groups = [ "pre-commit-ci", ] +[tool.maturin] +manifest-path = "rust/aa-ffi-python/Cargo.toml" +module-name = "agent_assembly._core" +python-source = "." +bindings = "pyo3" +features = ["pyo3/extension-module"] + [tool.hatch.build.targets.sdist] include = ["agent_assembly/"] packages = ["agent_assembly"] From b902132ae3e7033f9565454aebd63a155621c312 Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 01:58:40 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E2=9C=A8=20(pyproject):=20Bundle=20aasm=20?= =?UTF-8?q?binary=20at=20agent=5Fassembly/bin/aasm=20in=20wheel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit include with format="wheel" pulls the sidecar binary into the wheel artifact only (not sdist), matching where runtime.py's WHEEL_BUNDLED_BIN already searches. Listed unconditionally — maturin skips entries whose path is missing on disk, so non-runtime builds still succeed without the binary. The .exe entry is forward-looking for the Phase 2 Windows wheel target; current matrix omits it. AAASM-1215 --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 964960e..d99e5ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,13 @@ module-name = "agent_assembly._core" python-source = "." bindings = "pyo3" features = ["pyo3/extension-module"] +# aasm sidecar binary is placed at agent_assembly/bin/aasm by the release +# workflow before `maturin build`; runtime.py's find_aasm_binary() resolves +# WHEEL_BUNDLED_BIN to that same path at import time. +include = [ + { path = "agent_assembly/bin/aasm", format = "wheel" }, + { path = "agent_assembly/bin/aasm.exe", format = "wheel" }, +] [tool.hatch.build.targets.sdist] include = ["agent_assembly/"] From d1f453280d3cd3442f28c6cb83c531f6df7bdd9f Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 01:58:49 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20(pyproject):=20Drop?= =?UTF-8?q?=20obsolete=20[tool.hatch.build.targets.*]=20sections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hatchling is no longer the build backend; its sdist/wheel target config is dead config. Maturin's own python-source + include settings cover the same inclusion concerns. AAASM-1215 --- pyproject.toml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d99e5ad..8cccbe8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,12 +91,3 @@ include = [ { path = "agent_assembly/bin/aasm.exe", format = "wheel" }, ] -[tool.hatch.build.targets.sdist] -include = ["agent_assembly/"] -packages = ["agent_assembly"] -#artifacts = ["agent_assembly/py.typed"] - -[tool.hatch.build.targets.wheel] -include = ["agent_assembly/"] -packages = ["agent_assembly"] -#artifacts = ["agent_assembly/py.typed"] From c6847f0a7d5de988b49e3d8ce2f50e4d112fd173 Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 10:02:31 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=F0=9F=94=A7=20(cargo):=20Set=20PYO3=5FUSE?= =?UTF-8?q?=5FABI3=5FFORWARD=5FCOMPATIBILITY=3D1=20via=20.cargo/config.tom?= =?UTF-8?q?l?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI runs uv sync on Python 3.13. With the new maturin build backend, uv sync triggers an editable maturin build → cargo build → pyo3-ffi build script, which errors because pyo3 0.20 (current pin in aa-ffi-python) caps at CPython 3.12. Place the env var in rust/.cargo/config.toml so Cargo (and its child build scripts) see PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 for every aa-ffi-python build, without touching CI workflows or the external reusable workflow that runs uv sync. The forward-compat flag uses the stable Python ABI subset, which is already what abi3 wheels target — safe for the existing crate. AAASM-1215 --- rust/.cargo/config.toml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 rust/.cargo/config.toml diff --git a/rust/.cargo/config.toml b/rust/.cargo/config.toml new file mode 100644 index 0000000..cea9b4f --- /dev/null +++ b/rust/.cargo/config.toml @@ -0,0 +1,9 @@ +# pyo3 0.20 caps at CPython 3.12 (current crate pin). The Python SDK's +# `requires-python = ">=3.12,<4.0"` plus the CI matrix's Python 3.13 runner +# means pyo3-ffi's build script otherwise errors with: +# "the configured Python interpreter version (3.13) is newer than PyO3's +# maximum supported version (3.12)" +# Forward-compat ABI3 flag suppresses that check; the resulting binding +# uses the stable Python ABI subset that works across 3.12+. +[env] +PYO3_USE_ABI3_FORWARD_COMPATIBILITY = "1" From ae2bf4065c22907ebdd3a64b91c142c0993c7148 Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 10:18:33 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=F0=9F=94=A7=20(cargo):=20Move=20.cargo/con?= =?UTF-8?q?fig.toml=20to=20repo=20root=20for=20cwd-based=20discovery?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cargo discovers .cargo/config.toml by walking PARENT directories of the current working directory (not the manifest directory). When maturin pep517 invokes cargo, the cwd is the python-sdk repo root, not rust/. The previous placement at rust/.cargo/config.toml was never picked up — CI re-ran with the same pyo3-ffi 3.12 ceiling error. Move to .cargo/config.toml at the repo root so cargo finds it regardless of which workspace it's building. AAASM-1215 --- {rust/.cargo => .cargo}/config.toml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {rust/.cargo => .cargo}/config.toml (100%) diff --git a/rust/.cargo/config.toml b/.cargo/config.toml similarity index 100% rename from rust/.cargo/config.toml rename to .cargo/config.toml From 09bd41a587fcde44ed4ea72bce7f9e9b97130797 Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 10:24:14 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=F0=9F=94=A7=20(pyproject):=20Restore=20hat?= =?UTF-8?q?chling=20as=20the=20install-time=20build=20backend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hybrid setup: hatchling builds the universal SDK wheel that `pip install agent-assembly` and `uv sync` resolve, while maturin is retained under [tool.maturin] for the release workflow's CLI invocation (AAASM-1217). Why: switching the pep517 backend to maturin forced `uv sync` to compile the Rust extension on every CI shard, which then required the full Rust toolchain (cargo) + protobuf-compiler on each runner (aa-proto's build.rs invokes protoc) — none of which the existing test workflows provide. The native module is already optional at runtime (tests skip when _core isn't built), so keeping the SDK install pure-Python preserves that pattern. Platform wheels are still produced by maturin-action in release-python.yml, which doesn't read [build-system]. AAASM-1215 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8cccbe8..65d8dc3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -requires = ["maturin>=1.7,<2"] -build-backend = "maturin" +requires = ["hatchling"] +build-backend = "hatchling.build" [project] name = "agent-assembly" From a5efb9164e3d58a26d1e0b6127d0046f88a988fd Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 10:24:24 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=94=A7=20(pyproject):=20Restore=20[to?= =?UTF-8?q?ol.hatch.build.targets.*]=20sections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Companion to the previous commit's hatchling restore. Hatchling needs explicit packages = ["agent_assembly"] to know which directory to bundle into the sdist + universal wheel. AAASM-1215 --- pyproject.toml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 65d8dc3..4b4d54c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,3 +91,13 @@ include = [ { path = "agent_assembly/bin/aasm.exe", format = "wheel" }, ] +[tool.hatch.build.targets.sdist] +include = ["agent_assembly/"] +packages = ["agent_assembly"] +#artifacts = ["agent_assembly/py.typed"] + +[tool.hatch.build.targets.wheel] +include = ["agent_assembly/"] +packages = ["agent_assembly"] +#artifacts = ["agent_assembly/py.typed"] + From 980b7b7fa169d675f0e3e6db499077f4edbd6876 Mon Sep 17 00:00:00 2001 From: Chisanan232 Date: Sat, 23 May 2026 10:24:33 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20(cargo):=20Remove?= =?UTF-8?q?=20.cargo/config.toml=20=E2=80=94=20no=20longer=20needed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PYO3_USE_ABI3_FORWARD_COMPATIBILITY env var was only needed because uv sync triggered the pep517 maturin build chain on Python 3.13 (pyo3 0.20 ceiling). With hatchling restored as the install-time build backend, the Rust extension is no longer built during uv sync; the env var becomes dead config. maturin-action in release-python.yml will still need the forward-compat flag at build time — that's set inline in the workflow's env block (see native-core-build.yml for the established pattern), not via .cargo/config.toml. AAASM-1215 --- .cargo/config.toml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index cea9b4f..0000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,9 +0,0 @@ -# pyo3 0.20 caps at CPython 3.12 (current crate pin). The Python SDK's -# `requires-python = ">=3.12,<4.0"` plus the CI matrix's Python 3.13 runner -# means pyo3-ffi's build script otherwise errors with: -# "the configured Python interpreter version (3.13) is newer than PyO3's -# maximum supported version (3.12)" -# Forward-compat ABI3 flag suppresses that check; the resulting binding -# uses the stable Python ABI subset that works across 3.12+. -[env] -PYO3_USE_ABI3_FORWARD_COMPATIBILITY = "1"