lambda-microvm-hook-server 0.1.0

Hook server for supervising commands in AWS Lambda MicroVMs
Documentation
# Run Aether in an AWS Lambda `MicroVM`

This crate provides the lifecycle hook server needed to run Aether as a one-shot coding agent in a Lambda `MicroVM`.

## Build a `MicroVM` image

### 1. Create a `Dockerfile` containing Aether, the hook server, Git, and the GitHub CLI:

```dockerfile
FROM rust:1.97-bookworm AS build
RUN cargo install --locked aether-agent-cli
RUN cargo install --locked lambda-microvm-hook-server

FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates git gh \
    && rm -rf /var/lib/apt/lists/*
COPY --from=build /usr/local/cargo/bin/aether /usr/local/bin/
COPY --from=build /usr/local/cargo/bin/lambda-microvm-hook-server /usr/local/bin/
CMD ["lambda-microvm-hook-server"]
```

### 2. Upload it to S3:

```sh
zip aether-microvm.zip Dockerfile
aws s3 cp aether-microvm.zip s3://YOUR_BUCKET/aether-microvm.zip
```

### 3. Create the microVM image 

Replace the bucket, Region, account ID, and role name:

```sh
aws lambda-microvms create-microvm-image \
  --name aether \
  --code-artifact uri=s3://YOUR_BUCKET/aether-microvm.zip \
  --base-image-arn arn:aws:lambda:YOUR_REGION:aws:microvm-image:al2023-1 \
  --build-role-arn arn:aws:iam::YOUR_ACCOUNT_ID:role/YOUR_BUILD_ROLE \
  --egress-network-connectors arn:aws:lambda:YOUR_REGION:aws:network-connector:aws-network-connector:INTERNET_EGRESS \
  --hooks '{
    "port": 9000,
    "microvmImageHooks": {
      "ready": "/aws/lambda-microvms/runtime/v1/ready",
      "readyTimeoutInSeconds": 300
    },
    "microvmHooks": {
      "run": "/aws/lambda-microvms/runtime/v1/run",
      "runTimeoutInSeconds": 60,
      "terminate": "/aws/lambda-microvms/runtime/v1/terminate",
      "terminateTimeoutInSeconds": 30
    }
  }'
```

### 4. Wait for AWS to build your microVM image

```sh
aws lambda-microvms get-microvm-image --image-identifier aether
```

Wait until `state` is `CREATED`:

## Run your agent

Create a short-lived fine-grained GitHub token with **Contents: read/write** and **Pull requests: read/write**, then export it with your model provider's key:

```sh
export GH_TOKEN=...
export ZAI_API_KEY=...
```

The setup script is supplied dynamically for each run. This example clones the requested repository and passes the user's prompt directly to Aether:

```sh
cat > setup.sh <<'EOF'
set -eu

repository=$1
prompt=$2
workspace=/workspace/repository

gh auth setup-git
gh repo clone "$repository" "$workspace"
cd "$workspace"
exec aether headless --output text "$prompt"
EOF
```

Build the run payload. `OWNER/REPOSITORY` may be public or private as long as the token can access it.

```sh
jq -n \
  --rawfile setup setup.sh \
  --arg repository "OWNER/REPOSITORY" \
  --arg prompt "Fix the failing login test, add a regression test, and open a pull request" \
  --arg github_token "$GH_TOKEN" \
  --arg zai_key "$ZAI_API_KEY" \
  '{
    command: "/bin/sh",
    args: ["-c", $setup, "setup.sh", $repository, $prompt],
    environment: {
      GH_TOKEN: $github_token,
      ZAI_API_KEY: $zai_key
    }
  }' > payload.json
```

Run the agent:

```sh
aws lambda-microvms run-microvm \
  --image-identifier aether \
  --egress-network-connectors arn:aws:lambda:YOUR_REGION:aws:network-connector:aws-network-connector:INTERNET_EGRESS \
  --run-hook-payload file://payload.json \
  --maximum-duration-in-seconds 3600
```

Aether clones the repository, completes the task, and opens the PR. Watch the image's `CloudWatch` logs or run `gh pr list --repo OWNER/REPOSITORY` to see when it appears.

When Aether finishes, the hook server exits and Lambda terminates the `MicroVM`. The maximum duration is only a guardrail for a stuck agent. The run payload contains credentials, so use narrowly scoped, short-lived tokens.