Skip to content

hoansdz/Autolang

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Autolang

A scripting language and VM for sandboxed execution of AI-generated code, written in C++17.

License: MIT Discord Docs

If you want to test: https://autolang-chatbot-demo.vercel.app/


What it is

Autolang is a small, statically-typed scripting language with a custom VM, designed for use cases where you need to let an LLM generate and run code in a constrained environment — without exposing the full surface area of a general-purpose runtime.

It is not a replacement for Python, JavaScript, or C++. The intended pattern is to wrap your existing functions as Autolang bindings and let AI-generated scripts call only those bindings.

AI writes high-level logic
    → Autolang verifies types and enforces scope
        → Registered host functions (JS / C++) execute the real work

Note: Currently supported host environments: Node.js (via npm) and C++. Python bindings are not yet available.


Motivation

AI-generated code has a distinct profile: it is short (usually under 100 lines), frequently executed, and cannot be fully trusted. It tends to produce infinite loops, null pointer accesses, wrong types, and out-of-scope API calls — not because the model is bad, but because that is the nature of generated code at scale.

Existing approaches have tradeoffs:

  • General-purpose runtimes (Python, Node.js) expose too much by default — file I/O, network access, arbitrary imports. Restricting them after the fact is complex and easy to get wrong.
  • Docker / MicroVM isolation works well for security but carries real overhead: ~200–500ms cold start and 100MB+ RAM per instance. At 10–100 concurrent agents, this becomes an economic problem.

Autolang's approach is different: instead of restricting a general-purpose runtime, it starts from a minimal VM where AI scripts can only call what you explicitly register. The underlying work is still done by your existing JS or C++ functions — Autolang just controls the boundary.

This is a language-level sandbox, not an OS-level one. It trades generality for predictability: lower startup time, lower memory footprint, and a much smaller surface area for AI code to cause harm.


Features

  • Static typing — type errors are caught at compile time, before execution
  • Opcode limiting — scripts are terminated after a configurable number of opcodes, preventing infinite loops from hanging the host
  • Null safety — nullable types require explicit handling via the ?? operator; AI scripts can be further restricted from using nullable types or lateinit entirely
  • Per-library permissions — each registered library gets its own set of allowed language features
  • Native bindings — wrap existing JS or C++ functions via @native; no need to rewrite existing code

Performance

Measured on Windows 11, Intel Core i5 12th Gen, 16GB RAM. Results will vary based on script complexity, host environment, and hardware.

Metric Result
Cold start (native) ~10ms
Cold start (Node.js/npm) ~20ms
Warm start (native) 1–2ms
RAM per instance (native) ~4.2MB
RAM per instance (npm) ~12MB
~900 lines of code ~25ms compile + run

Autolang optimizes total time (compile + runtime), not just runtime. For short AI-generated scripts that run frequently, a slow compiler negates any runtime gain. The goal is to optimize just enough — without deep optimizations that add compile cost but benefit long-running programs that Autolang is not designed for.


Syntax

Autolang uses Kotlin-inspired syntax. Most constructs will be familiar if you've used Kotlin, Swift, or TypeScript.

Variables and null safety

var a: OptionalAccess?
a?.hello(1)

println(a?.child?.hello(4) ?? "No child found")

Collections

val arr = <Int>[1, 2, 3]
val map = <String, Int>{"Apple": 10, "Banana": 20}

val filtered = arr.filter {|value| value > 5}

Classes and generics

class GAnimal {
    func sound() = "Nothing"
}

class GCat extends GAnimal {
    constructor () {
        super()
    }
    @override
    func sound() = "Meow"
}

class GenericTest<T extends GAnimal>() {
    val value: T = T()
    func sound() = value.sound()
}

Installation

Requires a compiler with C++17 support.

Node.js (npm)

npm install autolang-compiler
import { ACompiler } from 'autolang-compiler';

const compiler = await ACompiler.create();

// Register a native binding from your existing codebase
compiler.registerBuiltInLibrary("testing/print", `
    @native("testPrint")
    func testPrint(helloText: String, name: String): String
`, { autoImport: false, allowLateinitKeyword: false, allowNonNullAssertion: false }, {
    "testPrint": (helloText, name) => {
        return `${helloText} ${name}`;
    }
});

compiler.clearOutput();

compiler.compileAndRun("main.al", `
    @import("testing/print")
    println(testPrint("Hello from ", "Autolang"))
`);

console.log(compiler.getOutput());
// Output: Hello from Autolang

Desktop (Linux / macOS / Windows)

# Linux / macOS
clang++ tests/main.cpp -O2 -std=c++17 -I src -o build/autolang
./build/autolang

# Windows (MinGW)
mingw32-make

Example: AI Agent with custom database binding

A common pattern is registering a library that exposes your data to the AI, then letting it write filtering and query logic in Autolang.

1. Register the library

const compiler = await ACompiler.create({ addStdFile: false });

// Limit opcode count for AI-generated scripts
compiler.setLimitOpcodeCount(1_000_000);

compiler.registerBuiltInLibrary("company/products", `
    @import("std/json")

    class Product (
        val name: String,
        val price: Int,
        val weight: Float,
        val inStock: Bool
    )

    class Database {
        @native("get_products")
        static private func _get_products(): String

        static func get_products(): Array<Product> {
            val jsonStr = _get_products()
            val json = Json.parse(jsonStr)
            val products = json["data"]
            return jsonToArrayClass<Product>(products)
        }
    }
`, { autoImport: true }, {
    "get_products": () => JSON.stringify({
        data: [
            { name: "Dalat Carrot",   price: 25,  weight: 0.5, inStock: true  },
            { name: "Highland Potato",price: 30,  weight: 1.0, inStock: false },
            { name: "Broccoli",       price: 45,  weight: 0.4, inStock: true  },
            // ...
        ]
    })
});

// Restrict AI scripts from using lateinit or non-null assertions
compiler.setMainSourceConfig({
    allowLateinitKeyword: false,
    allowNonNullAssertion: false
});

2. The AI generates and runs Autolang scripts against your data

Prompt: "I have $30, what can I buy?"

@import("company/products")

val budget = 30
val allProducts = Database.get_products()
val affordable = allProducts.filter {|p| p.inStock && p.price <= budget }

println("Products within budget:")
affordable.forEach {|p| println("- ${p.name}: $${p.price}") }

Output:

Products within budget:
- Dalat Carrot: $25
- Pumpkin: $22
- Seedless Lime: $15

The AI only has access to what you register. It cannot reach outside company/products.


Memory model

Autolang uses reference counting combined with a hot restart approach — after each script execution, memory is reset to a clean state rather than relying on incremental garbage collection. This keeps per-run overhead predictable.


Security model

The core assumption is that AI-generated code cannot be fully trusted — not because the model is unreliable, but because running untrusted code at scale requires treating every script as potentially faulty.

Autolang's approach:

  • Scripts can only call explicitly registered functions — there is no implicit access to the filesystem, network, or host environment
  • Static analysis rejects type errors and out-of-scope API calls before execution
  • Per-library permissions let you apply stricter rules to AI-generated code (e.g. no lateinit, no nullable types) while keeping system libraries flexible
  • Opcode limits ensure runaway scripts are terminated rather than hanging the host process

The objective is not to trust that the AI will always write correct code, but to engineer a system where even if it writes bad code, it cannot bring down the host environment.

This is a language-level sandbox, not an OS-level one. It does not replace process isolation for high-security environments.


When to use Autolang

Autolang is a good fit if:

  • You are building a system where an LLM generates and executes code at runtime, and you need to control what it can access
  • You are running many concurrent AI agents and the RAM overhead of full runtime isolation (Docker, Node.js per agent) is becoming a cost problem
  • You want to expose existing JS or C++ functions to AI in a controlled way, without rewriting them
  • Your AI-generated scripts are short (under ~100 lines) and run frequently

A rough threshold: if you are running 5+ concurrent agents and memory or cold-start latency matters, the tradeoff starts making sense.

When not to use Autolang

Autolang is probably not the right fit if:

  • You only have a small number of agents and runtime isolation overhead is not a concern
  • Your AI needs to write long, complex programs — Autolang is optimized for short scripts, not large applications
  • You need OS-level security guarantees — Autolang is a language-level sandbox and does not replace process isolation
  • You need Python bindings — they are not available yet

Documentation

Full documentation: autolang.vercel.app/docs


Contributing

Bug reports and pull requests welcome, especially for npm wrappers and embedding APIs.

  • GitHub Issues: Report bugs or request features
  • Discord: Join the community
  • Maintainer: hoansdz

Sponsors

Ada group


License

MIT © 2026 Autolang Project

About

A high-performance, ultra-low latency scripting language written in C++ with no GC/JIT, optimized for AI Agents and dynamic workflows

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages