Skip to main content

Ailoy

AI agent builder with a VM at its heart.

crates.io PyPI npm node

Documentation Discord X


Ailoy is a library for building any kind of AI agents right in your own code.

CAD modeling
CAD modeling
Image editing
Image editing
Gameplay
Gameplay
Laya(JEV)
Laya(JEV)

It supports Python, JavaScript ( TypeScript), and Rust APIs, and works on Linux, Windows, and macOS.

Requirements

No system dependencies are required, but your agent's model needs a way to run: by default its provider's CLI (Claude Code, Codex or Gemini CLI), or its API with a key.

Mounting host folders into the console (virtx's virtual filesystem) needs FUSE: install FUSE-T on macOS or Dokany on Windows. See the virtx documentation for details.

On Windows, the console's micro-VM runs on the Windows Hypervisor Platform, which is off by default. Turn the optional feature on from an administrator PowerShell and restart, with virtualization enabled in the firmware:

Enable-WindowsOptionalFeature -Online -FeatureName HypervisorPlatform

Quickstart

By default, Claude, GPT and Gemini run through their CLIs, so install and log in to the one for your model: Claude Code (claude), Codex (codex) or Gemini CLI (gemini).

To call the provider's API instead, set its key and switch the org to the api backend before building the agent, e.g. ailoy.set_lang_model_provider("anthropic", "api") in Python (setLangModelProvider in Node.js, ailoy::model::set_lang_model_provider in Rust):

export ANTHROPIC_API_KEY=...   # or OPENAI_API_KEY, GEMINI_API_KEY

Amazon Bedrock, OpenRouter and vLLM are backends too; see the model providers guide.

Then build your agent with this simple API in your preferred language:

Python
pip install ailoy-py
import asyncio

from ailoy import AgentBuilder
from virtx import ConsoleClient, Recipe


async def main() -> None:
    console = await (
        ConsoleClient.builder()
        .image(Recipe("python:3.12-slim-trixie").step("pip install matplotlib"))
        .mount("./artifacts", "/artifacts")
        .network(True)
        .build()
    )

    agent = await (
        # For openai, use "openai/gpt-5.6-luna"
        AgentBuilder("anthropic/claude-haiku-5-5")
        .instruction("Write what you are asked for into /artifacts.")
        .system_tools()
        .console(console)
        .build()
    )

    async for output in agent.run("Create a bar chart comparing the populations of European countries and save it to /artifacts/population.png."):
        for part in output["message"]["contents"]:
            if part["type"] == "text":
                print(part["text"])

asyncio.run(main())

agent.run yields one complete message for each step of the tool loop, and agent.run_stream streams each message token by token as the model writes it.

Node.js
npm install @brekkylab/ailoy @brekkylab/virtx
const { AgentBuilder } = require('@brekkylab/ailoy')
const { ConsoleClient, Recipe } = require('@brekkylab/virtx')

const console_ = await ConsoleClient.builder()
  .image(new Recipe('python:3.12-slim-trixie').step('pip install matplotlib'))
  .mount('./artifacts', '/artifacts')
  .network(true)
  .build()
// For openai, use "openai/gpt-5.6-luna"
const agent = await new AgentBuilder('anthropic/claude-haiku-5-5')
  .instruction('Write what you are asked for into /artifacts.')
  .systemTools()
  .console(console_)
  .build()

try {
  for await (const { message } of agent.run('Create a bar chart comparing the populations of European countries and save it to /artifacts/population.png.')) {
    for (const part of message.contents) {
      if (part.type === 'text') console.log(part.text)
    }
  }
} finally {
  await agent.close()
}

agent.run yields one complete message for each step of the tool loop, and agent.runStream streams each message token by token as the model writes it.

Rust
[dependencies]
ailoy = "0.3"
virtx = "0.1"
use ailoy::{
    agent::AgentBuilder,
    console::ConsoleClient,
    message::{Message, Part, Role},
};
use virtx::image::Recipe;
use futures::StreamExt as _;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let console = ConsoleClient::builder()
        .image(Recipe::new("python:3.12-slim-trixie").step("pip install matplotlib"))
        .mount(std::path::absolute("./artifacts")?, "/artifacts")
        .network(true)
        .build()
        .await?;

    // For openai, use "openai/gpt-5.6-luna"
    let mut agent = AgentBuilder::new("anthropic/claude-haiku-5-5")
        .instruction("Write what you are asked for into /artifacts.")
        .system_tools()
        .console(console)
        .build()
        .await?;

    let query = Message::new(Role::User).with_contents([Part::text("Create a bar chart comparing the populations of European countries and save it to /artifacts/population.png.")]);
    let mut stream = agent.run(query);
    while let Some(output) = stream.next().await {
        let message = output?.message;
        if message.role == Role::Assistant {
            for text in message.contents.iter().filter_map(Part::as_text) {
                println!("{text}");
            }
        }
    }
    Ok(())
}

agent.run yields one complete message for each step of the tool loop, and agent.run_stream streams each message token by token as the model writes it.

...Or skip the reading: point your coding agent (Claude Code, Codex, Cursor, ...) at this README and tell it what agent you want to build. This repo is its own plugin marketplace, so the agent skill installs with no clone first:

claude plugin marketplace add brekkylab/ailoy && claude plugin install ailoy@brekkylab
codex plugin marketplace add brekkylab/ailoy && codex plugin add ailoy@brekkylab

What can an agent do?

You'll need a GPU (any GPU that supports Vulkan, or Metal on Macs) for the examples that run ML models.

Example Description
hello One turn with no tools and no console
cad Writes CadQuery, renders the model from four sides, looks at the renders and iterates
offshore_leaks Analyses the ICIJ Offshore Leaks database with SQL and Python that the agent writes itself
retail_bench Runs a supermarket simulator, one day per turn
gameplay Plays OpenTTD (Transport Tycoon Deluxe) while you watch over VNC
sam3 Segments images and videos with SAM3 on the guest GPU (ncnn + Vulkan)
tts Speaks text in a voice described in words, using Qwen3-TTS
laya Answers typed decision questions with a local model on the GPU
browser-use Waits for what you ask of it, in a window of your own browser

Each example lives in examples/<name>, with one folder per language (rust, python, node) and, where the three share files (skills, prompts, model preparation scripts), a shared folder.

Rust:

cargo run --example <name>

Python:

cd examples/<name>/python
uv run main.py

Node:

cd examples/<name>/node
npm install
npm start

How It Works

Ailoy give the agent a computer of its own.

This lets you build agents that do more than call predefined tools: they can install and use software, create their own scripts, and operate in a general-purpose computing environment—without touching the host system beyond what you explicitly expose.

To make this possible, Ailoy uses krun-based virtualization to give each agent a virtual machine of its own, with no separate VM daemon to install.

The virtualization used in Ailoy also supports the GPU, so an agent can run ML models, or even games, inside its VM.

See virtx for more details.

Building from source

git clone https://github.com/brekkylab/ailoy
cd ailoy
cargo build

For the bindings:

cd bindings/python && uv run maturin develop  # Python
cd bindings/node && npm install && npm run build  # Node.js

License

Apache-2.0. See LICENSE.md.

Metadata

Release files for ailoy-py 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for ailoy-py 0.3.1
File Actions
ailoy_py-0.3.1-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for ailoy_py-0.3.1-cp310-abi3-win_amd64.whl
ailoy_py-0.3.1-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details for ailoy_py-0.3.1-cp310-abi3-manylinux_2_28_x86_64.whl
ailoy_py-0.3.1-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details for ailoy_py-0.3.1-cp310-abi3-manylinux_2_28_aarch64.whl
ailoy_py-0.3.1-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for ailoy_py-0.3.1-cp310-abi3-macosx_11_0_arm64.whl

Total release size: 53.7 MB

Release files / ailoy_py-0.3.1-cp310-abi3-win_amd64.whl

Download URL ailoy_py-0.3.1-cp310-abi3-win_amd64.whl
Size 12.8 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
9b8152cb162c11eba233fd668da004d6521bec3e034c8c05f1039c8d92aedb7d
BLAKE2b-256 checksum
How to use checksums
a6281cdbec443972e9f474159609d4a4a375aad2166eb846f2baf392a87ef198
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / ailoy_py-0.3.1-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL ailoy_py-0.3.1-cp310-abi3-manylinux_2_28_x86_64.whl
Size 14.0 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
6b2a078bc55c759dda21916395c885299dd0756bdb5158b215aa3f092f0aa702
BLAKE2b-256 checksum
How to use checksums
19fe615073de2a4ea496e14c57c2fc6304183fbe8e721b199e8e4756123bbd6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / ailoy_py-0.3.1-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL ailoy_py-0.3.1-cp310-abi3-manylinux_2_28_aarch64.whl
Size 14.3 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
a5b16edffee7db6434b11275f38ae0dcbb6c157d571d1e8a6403a747ab5f40aa
BLAKE2b-256 checksum
How to use checksums
e79865563a53e3d9d7d3de7a14428dd2c3d2121d14c167615e6ba475e927b837
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / ailoy_py-0.3.1-cp310-abi3-macosx_11_0_arm64.whl

Download URL ailoy_py-0.3.1-cp310-abi3-macosx_11_0_arm64.whl
Size 12.7 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
01f8d159f05bd9cb641c35bb461943316dea0eec971ee457b3c6bbd251f2a515
BLAKE2b-256 checksum
How to use checksums
cbd0a0cbf01036111a186c8ffe401662fd52d1a271d2c4a884af8520dbca1648
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for ailoy-py 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3.1 This release

4 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page