Skip to content

The proof

What ran, where

A native Android app (Kotlin) with Node.js v24.19.0 embedded as libnode.so ran the Pi coding-agent SDK in-process on an x86_64 Android emulator (API 32). No Termux, no external node executable, no WebView, no Linux userspace.

Evidence, captured from the running app

NativeBridge.runPi() returned rc=0, and the embedded runtime wrote files/result.json:

{
  "status": "ok",
  "answer": "MockPi response: received \"say hello from embedded pi\"",
  "events": ["agent_start","turn_start","message_start","message_end",
             "message_start","message_end","turn_end","agent_end","agent_settled"],
  "model": "openai/gpt-4o",
  "runtime": { "node": "v24.19.0", "platform": "android", "arch": "x64", "embedded": true }
}

Three more artifacts back it up. files/events.jsonl carries the full timestamped agent event stream. files/node.out shows the embedded runtime booting (platform=android arch=x64) and finishing the bootstrap. And the packaged APK itself ships both arm64-v8a and x86_64 in 123 MB.

The ABI note

The build cross-compiles both libnode.so and the JNI bridge for arm64-v8a and packages them. That is the primary artifact. The end-to-end run executed the x86_64 build because the emulator runs on an x86 host, and ARM system images cannot run there. Both ABIs come from the same recipe and the same source tree.

The provider caveat

No model API credentials were available, so the model backend is a mock, a canned assistant message. The SDK, the ESM loader, the event loop, and the session lifecycle all ran unmodified inside the embedded runtime.