~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/asyncai

0
0
main
291 lines · 10.0 KB Raw History

Contributing

Development

Rust is pinned by rust-toolchain.toml (1.97.0). The atirc client is a git dependency pinned to a revision in Cargo.toml; builds need fetch access to tangled.org, and the revision only moves when bumped deliberately (with Cargo.lock updated in the same change).

cargo build --release --bins

Binaries:

  • asyncai
  • asyncai-mcp-simple
  • socialweb-computer-kcp-readonly
  • socialweb-computer-kcp-readwrite

cargo install --path . installs all four. prompts/*.md and src/code_mode/helpers.py are embedded at build time, so prompts/ must be present in any build context.

Checks

cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test

Pool sandbox tests need the Monty worker:

cargo +1.97.0 install monty-runtime --locked   # installs `monty`
MONTY_WORKER=$(command -v monty) cargo test --test code_mode_pool

Tests mock the model, MCP servers, and the atirc bus; no live services or network are used. Never commit endpoints or tokens.

Linux amd64 build

container system start

# Drop stopped build containers from earlier runs before building.
container list --all --format json \
  | jq -r '.[] | select(.status.state=="stopped") | .id' \
  | while read -r id; do container delete "$id"; done

rm -rf $HOME/.tmp/asyncai-out
mkdir -p $HOME/.tmp/asyncai-out

container build --platform linux/amd64 -m 8G -c 4 \
  -f Dockerfile \
  -o type=local,dest=$HOME/.tmp/asyncai-out .

find $HOME/.tmp/asyncai-out -name asyncai -type f
file $HOME/.tmp/asyncai-out/*/linux_amd64/out/asyncai   # ELF 64-bit, static-pie

Build context and destination must live under $HOME: the builder cannot read /tmp (the context transfers as 2B and COPY fails). The container uses the image's pinned 1.97.x toolchain; rust-toolchain.toml is not copied into the build, so local builds can stay on 1.97.0 while the image builds with its own 1.97 patch release. -j 2 keeps monty's rustc within the 8G builder memory limit (4 jobs gets OOM-killed).

Smoke-run in an Alpine container:

container run --rm --platform linux/amd64 --memory 1G \
  -v $HOME/.tmp/asyncai-out/*/linux_amd64/out:/out \
  alpine:latest /out/asyncai --help

Windows amd64 build (cross-compile)

Cross-compiles self-contained PE32+ x86-64 binaries with mingw-w64 inside the build container. No Windows host, MSVC SDK, cargo-xwin or zig is needed.

container system start

# Drop stopped build containers from earlier runs before building.
container list --all --format json \
  | jq -r '.[] | select(.status.state=="stopped") | .id' \
  | while read -r id; do container delete "$id"; done

rm -rf $HOME/.tmp/asyncai-win-out
mkdir -p $HOME/.tmp/asyncai-win-out

# Apple Silicon: linux/arm64. Intel Macs: linux/amd64. The build container
# architecture does not change the Windows binaries.
container build --platform linux/arm64 -m 8G -c 4 \
  -f Dockerfile.windows \
  -o type=local,dest=$HOME/.tmp/asyncai-win-out .

find $HOME/.tmp/asyncai-win-out -name '*.exe' -type f
file $HOME/.tmp/asyncai-win-out/*/linux_arm64/out/asyncai.exe
# PE32+ executable (console) x86-64, for MS Windows

Dockerfile.windows installs the mingw-w64 toolchain plus cmake, perl and nasm (used by aws-lc-sys), adds the Rust x86_64-pc-windows-gnu target, and builds with a static CRT so the .exe files do not require libgcc_s_seh-1.dll or libwinpthread-1.dll. The target is added to the image's pinned 1.97.x toolchain; rust-toolchain.toml is not copied into the build so rustup cannot switch to a toolchain without that target.

A PE binary cannot be run on macOS without Windows or Wine, so this target is compile-verified only. Windows runtime notes:

  • --monitor and the kcp runner spawn sh -c, so they need Git Bash or WSL.
  • The Claude Code session harness reads HOME; on Windows set HOME (Git Bash) or pass --session-dir FORMAT=PATH, or run with --no-session.

macOS arm64 build

Native build on an Apple Silicon Mac:

cargo build --release --bins
file target/release/asyncai   # Mach-O 64-bit executable arm64

All four binaries land in target/release/.

Building on a Linux host

The container commands above are Apple-container-specific. On a Linux host use the same Dockerfiles with BuildKit (docker buildx or podman build, both support --output type=local), or build directly with the host toolchain as below. All three platforms can be produced from one Linux host except macOS.

Linux amd64 on a Linux host

# Debian/Ubuntu
sudo apt-get install -y build-essential cmake perl pkg-config
# Fedora/RHEL
sudo dnf install -y gcc gcc-c++ make cmake git perl pkgconf-pkg-config

cargo build --release --bins

git is required because .cargo/config.toml sets git-fetch-with-cli for the pinned atirc dependency.

For the same static-pie binary the container build produces, add the musl target (static against musl, no glibc dependency on the target host):

sudo apt-get install -y musl-tools
rustup target add x86_64-unknown-linux-musl
cargo build --release --bins --target x86_64-unknown-linux-musl

The four binaries land in target/x86_64-unknown-linux-musl/release/.

Windows amd64 on a Linux host (cross-compile)

# Debian/Ubuntu
sudo apt-get install -y \
  gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 \
  nasm cmake perl pkg-config
# Fedora/RHEL
sudo dnf install -y mingw64-gcc mingw64-gcc-c++ mingw64-binutils \
  nasm cmake perl pkgconf-pkg-config

rustup target add x86_64-pc-windows-gnu

export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS="-C target-feature=+crt-static"

cargo build --release --bins --target x86_64-pc-windows-gnu

nasm is only needed for x86_64 Windows (aws-lc-sys); the static CRT flag is what keeps the .exe files free of libgcc_s_seh-1.dll and libwinpthread-1.dll.

macOS arm64

A macOS artifact needs a macOS host: there is no supported way to produce one from a Linux host without an Apple SDK. Build it with cargo build --release --bins on an Apple Silicon Mac (or via an osxcross toolchain with a legally obtained SDK, which is out of scope here). Linux (glibc or musl) and Windows artifacts can both be built on one Linux host.

Container builds on a Linux host

docker buildx build --platform linux/amd64 -f Dockerfile \
  --output type=local,dest=$PWD/out/linux .

# The build container arch does not affect the Windows artifacts.
docker buildx build --platform linux/amd64 -f Dockerfile.windows \
  --output type=local,dest=$PWD/out/windows .

--output type=local requires BuildKit (default in current Docker). The $HOME/.tmp and -m/-c builder-memory notes in the Apple sections do not apply; Docker inherits the host's resources.

Cold container builds and cargo cache seeding

A cold container build can sit ~10 minutes at "Updating git repository": the container VM has no IPv6 route while musl prefers AAAA for tangled.org/crates.io. Seed the host cargo caches and build offline to skip the hang. Keep the /work/target cache mount — when it is warm only the asyncai crate recompiles; the cache also makes the copied registry layers cheap.

Create the seed from the host caches (both git repositories must be present: atirc and atproto-crates):

mkdir -p cargo-seed/git/db cargo-seed/git/checkouts cargo-seed/registry
cp -R ~/.cargo/git/db/atirc-* ~/.cargo/git/db/atproto-crates-* cargo-seed/git/db/
cp -R ~/.cargo/git/checkouts/atirc-* ~/.cargo/git/checkouts/atproto-crates-* cargo-seed/git/checkouts/
cp -R ~/.cargo/registry/index ~/.cargo/registry/cache cargo-seed/registry/

Then apply this diff to Dockerfile (and Dockerfile.windows for the same offline behavior):

 COPY src ./src
 COPY prompts ./prompts
+COPY cargo-seed/git /usr/local/cargo/git
+COPY cargo-seed/registry/index /usr/local/cargo/registry/index
+COPY cargo-seed/registry/cache /usr/local/cargo/registry/cache

-RUN --mount=type=cache,target=/usr/local/cargo/registry \
-    --mount=type=cache,target=/usr/local/cargo/git \
-    --mount=type=cache,target=/work/target \
+RUN --mount=type=cache,target=/work/target \
     TOOLCHAIN=$(echo /usr/local/rustup/toolchains/*) && \
-    PATH="$TOOLCHAIN/bin:$PATH" cargo build --release --bins -j 2 && \
+    PATH="$TOOLCHAIN/bin:$PATH" CARGO_NET_OFFLINE=true \
+    cargo build --release --bins -j 2 && \

cargo-seed/ is local scratch state; leave it untracked and do not commit it. It must stay in the build context (do not gitignore it) or the COPY steps fail.

Disk hygiene

container build caches aggressively and never prunes itself. Each distinct build adds an image (~0.4–0.5 GB), and the BuildKit builder container (~/Library/Application Support/com.apple.container/containers/buildkit, ~13 GB) keeps cargo registry/target caches between builds. Apple's CLI has no automatic garbage collection, so this grows every day a build runs.

Reclaim stopped containers (safe; the running buildkit builder is skipped):

container list --all --format json \
  | jq -r '.[] | select(.status.state=="stopped") | .id' \
  | while read -r id; do container delete "$id"; done

Deleting the buildkit container (container stop buildkit && container delete buildkit) drops its ~13 GB cache; the next build recreates the builder automatically and is cold. Rust build output is the other grower: target/ reaches multiple GB; cargo clean resets it.

Installing on a host

There is no server deploy: copy the four binaries to the machine that runs the agent and put them on PATH together.

scp target/release/asyncai \
    target/release/asyncai-mcp-simple \
    target/release/socialweb-computer-kcp-readonly \
    target/release/socialweb-computer-kcp-readwrite \
    <host>:/tmp/

ssh <host> 'sudo install -m 0755 /tmp/asyncai /tmp/asyncai-mcp-simple \
  /tmp/socialweb-computer-kcp-readonly /tmp/socialweb-computer-kcp-readwrite \
  /usr/local/bin/'

Use the matching Linux, macOS or Windows build for the target host; the Linux amd64 binaries are static-pie and need no libc or CA bundle on the host.