Experimental Chicory Android Compiler
Installing
The experimental Chicory Android compiler is currently available through the GitHub Package Registry.
Gradle
In your settings.gradle.kts:
repositories {
maven {
url = uri("https://maven.pkg.github.com/dylibso/chicory-compiler-android")
credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME")
password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN")
}
}
}where USERNAME is your GitHub username, and TOKEN is a Classic Token. You can configure them in your gradle.properties or set the USERNAME and TOKEN environment variables.
Then add the dependency to your build.gradle.kts:
dependencies {
implementation("com.dylibso.chicory:android-aot:0.0.1")
}
Maven
Configure Maven.
Create a settings.xml file alongside your pom.xml or just add to your ~/.m2/settings.xml:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <activeProfiles> <activeProfile>github</activeProfile> </activeProfiles> <profiles> <profile> <id>github</id> <repositories> <repository> <id>central</id> <url>https://repo.maven.apache.org/maven2</url> </repository> <repository> <id>github</id> <url>https://maven.pkg.github.com/dylibso/chicory-compiler-android</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> </profiles> <servers> <server> <id>github</id> <username>USERNAME</username> <password>TOKEN</password> </server> </servers> </settings>
where USERNAME is your GitHub username, and TOKEN is a Classic Token.
Now you can depend on the package in your pom.xml:
<dependencies>
<dependency>
<groupId>com.dylibso.chicory</groupId>
<artifactId>android-aot</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
If you are using a local settings.xml, just run mvn -s settings.xml <command>.
Using the Android Chicory Compiler
Once you have the com.dylibso.chicory:android-aot dependency in your classpath, you only need to plug the MachineFactory.
import com.dylibso.chicory.compiler.MachineFactoryCompiler; import com.dylibso.chicory.wasm.Parser; import com.dylibso.chicory.wasm.WasmModule; import com.dylibso.chicory.experimental.android.aot.AotAndroidMachine; var module = Parser.parse(new File("your.wasm")); var instance = Instance.builder(module). withMachineFactory(AotAndroidMachine::new). build();
Because of the memory and stack limitations on the main Android thread, we strongly advise to initialize and invoke the instance on its own thread, with a generous amount of stack memory:
Runnable r = () -> instance.call(...);
Thread t = new Thread( new ThreadGroup("chicory"), r, "chicory-thread", 8 * 1024 * 1024) )
Using the Android Chicory Compiler with Extism
The Extism Chicory SDK supports the Android compiler extension since version 0.2.0. In this case, you will write:
var path = Path.of("https://github.com/extism/plugins/releases/download/v1.1.1/count_vowels.wasm"); var wasm = ManifestWasm.fromFilePath(path).build(); var manifest = Manifest.ofWasms(wasm) .withOptions(new Manifest.Options() .withMachineFactory(AotAndroidMachine::new)).build(); var plugin = Plugin.ofManifest(manifest).build();
Because of the memory and stack limitations on the main Android thread, we strongly advise to initialize and invoke the plugin on its own thread, with a generous amount of stack memory:
Runnable r = () -> plugin.call(...);
Thread t = new Thread( new ThreadGroup("chicory"), r, "chicory-thread", 8 * 1024 * 1024) )
Using the Android Chicory Compiler with mcpx4j
The mcpx4j library to run mcp.run tools on-device, is built on Extism and it also supports the Android AOT compiler.
In this case, you will write something like:
val mcpx = // Configure the MCP.RUN Session Mcpx.forApiKey(BuildConfig.mcpRunKey) .withServletOptions( McpxServletOptions.builder() .withMachineFactory{ AotAndroidMachine(it) } // Setup an HTTP client compatible with Android // on the Chicory runtime .withChicoryHttpConfig(AndroidHttpConfig.get()) // Configure an alternative, Android-specific logger .withChicoryLogger(AndroidLogger("mcpx4j-runtime")) .build()) // Configure also the MCPX4J HTTP client to use // the Android-compatible implementation .withHttpClientAdapter(HttpUrlConnectionClientAdapter()) .withProfile(BuildConfig.profile) .build()
Because of the memory and stack limitations on the main Android thread, we strongly advise to initialize and invoke the plugin on its own thread, with a generous amount of stack memory; for instance:
val service = Executors.newSingleThreadExecutor { Thread(ThreadGroup("chicory"), it, "chicory-thread", 8 * 1024 * 1024) } val call: Callable<String> = Callable { tool.call(input) } val res: String = service.submit(call).get()