Skip to main content
Version: v1

Host ABI

This page is the low-level contract between the ActonOS host (Wazero) and a guest plugin compiled to wasip1 / wasm32-wasi. Most authors never call these functions — the Go SDK (sdk.Serve, RegisterTool, ctx.HTTP(), …) wraps them.

Use this page if you are compiling from Rust, TinyGo internals, or another language.

The canonical spec in the SDK repo is spec/WASM_ABI.md.


Memory protocol​

WebAssembly has a single 32-bit linear memory. Host and guest pass bytes with a non-reentrant buffer:

Host → guest (tools, channels, actions)

  1. Host calls acton_alloc(size), writes the payload, then calls acton_tool_execute (or another export).
  2. Guest returns a packed 64-bit value: (outPtr << 32) | outLen.
  3. Host reads that slice and calls acton_free(outPtr, outLen).

Guest → host (HTTP, vault, storage)

  1. Guest calls a syscall such as acton_net.http_request(req_ptr, req_len) and gets res_len.
  2. Guest allocates res_len bytes and copies with acton_sys.read_response(dest_ptr, res_len).

The pending-response buffer is not re-entrant: the guest must read it before the next syscall. That keeps the Go garbage collector stable.


Guest exports​

ExportSignatureRole
acton_alloc(size: u32) -> u32Allocate guest memory
acton_free(ptr: u32, size: u32)Free guest memory
acton_plugin_init() -> i320 = success
acton_tool_execute(namePtr, nameLen, argsPtr, argsLen: u32) -> u64Packed result JSON
acton_channel_send(ptr: u32, len: u32) -> i320 or error code
acton_channel_poll() -> u64Packed inbound JSON
acton_connector_action(ptr: u32, len: u32) -> u64Packed action JSON

Host imports​

acton_sys​

FunctionSignatureNotes
log(level, ptr, len: i32)1=Debug, 2=Info, 3=Warn, 4=Error
read_response(destPtr, destLen: i32) -> i32Copy last syscall body

acton_net​

FunctionSignatureNotes
http_request(reqPtr, reqLen: i32) -> i32Subject to net_outbound; returns body length

acton_ws​

FunctionSignatureNotes
ws_connect(urlPtr, urlLen: i32) -> i32Handle id > 0, or negative error
ws_send(handle, msgType, dataPtr: i32) -> i321=Text, 2=Binary
ws_poll(handle: i32) -> i32Byte length, 0 empty, -1 closed
ws_close(handle: i32) -> i32

acton_vault​

FunctionSignatureNotes
get_secret(keyPtr, keyLen: i32) -> i32Must match permissions.secrets

acton_storage​

FunctionSignatureNotes
kv_get(keyPtr, keyLen: i32) -> i32
kv_set(kPtr, kLen, vPtr, vLen: i32) -> i320 = success
kv_delete(keyPtr, keyLen: i32) -> i32

acton_bus​

FunctionSignatureNotes
emit_event(tPtr, tLen, pPtr, pLen: i32) -> i32Must match permissions.bus_events