Using AI Keywords in WASM¶
Status: Reference guide for WAT/WASM developers
Updated: 2026-05-08
Overview¶
AI keywords (PROMPT, GENERATE, EXTRACT, CLASSIFY, THINK, STREAM, PLAN, EMBED, TRANSCRIBE) are fully implemented in the Python backend but require host import implementations in WASM/WAT environments.
This guide explains how to integrate AI functionality when targeting WebAssembly.
The Challenge¶
Python (Works Out-of-Box)¶
The Python backend uses a MockProvider (for testing) or real AI services at runtime.
WASM (Requires Host Imports)¶
WASM can't directly call external services. Instead, it must: 1. Define host imports for AI functions 2. Pass request/response through memory 3. Implement host callbacks in JavaScript/browser
Solution: Host Imports¶
What WASM Generates¶
When compiling multilingual code with AI keywords to WASM, the WAT includes calls like:
(import "env" "_prompt" (func $prompt (param i32 i32) (result i32)))
(import "env" "_generate" (func $generate (param i32 i32) (result i32)))
(import "env" "_extract" (func $extract (param i32 i32) (result i32)))
(import "env" "_classify" (func $classify (param i32 i32) (result i32)))
(import "env" "_think" (func $think (param i32 i32) (result i32)))
(import "env" "_stream" (func $stream (param i32 i32) (result i32)))
(import "env" "_plan" (func $plan (param i32 i32) (result i32)))
(import "env" "_embed" (func $embed (param i32 i32) (result i32)))
(import "env" "_transcribe" (func $transcribe (param i32 i32) (result i32)))
Each function: - Takes 2 parameters: input pointer (i32) and input length (i32) - Returns output pointer (i32) pointing to result in linear memory
What You Must Provide¶
Implement these host functions in JavaScript:
const hostFunctions = {
env: {
_prompt: (inputPtr, inputLen) => {
const prompt = readStringFromMemory(inputPtr, inputLen);
const response = "Mock response: " + prompt;
return writeStringToMemory(response);
},
_generate: (inputPtr, inputLen) => {
const spec = readStringFromMemory(inputPtr, inputLen);
const output = "Generated: " + spec;
return writeStringToMemory(output);
},
_extract: (inputPtr, inputLen) => {
const text = readStringFromMemory(inputPtr, inputLen);
// Parse and return extracted items
return writeStringToMemory(JSON.stringify([]));
},
_classify: (inputPtr, inputLen) => {
const text = readStringFromMemory(inputPtr, inputLen);
return writeStringToMemory("POSITIVE");
},
// ... implement others similarly
}
};
Memory Layout Conventions¶
WASM uses linear memory to pass strings between the host and module.
Reading from Memory¶
function readStringFromMemory(ptr, len) {
const buffer = new Uint8Array(wasmInstance.exports.memory.buffer, ptr, len);
return new TextDecoder().decode(buffer);
}
Writing to Memory¶
function writeStringToMemory(str) {
const encoder = new TextEncoder();
const encoded = encoder.encode(str);
const ptr = wasmInstance.exports.allocate(encoded.length);
const buffer = new Uint8Array(wasmInstance.exports.memory.buffer, ptr, encoded.length);
buffer.set(encoded);
return ptr;
}
Note: Your WASM module must export an allocate() function to reserve memory for responses.
Example: Browser Integration¶
1. Compile Multilingual Code to WASM¶
python -m multilingualprogramming examples/my_ai_program.multi --target=wasm --output=my_ai_program.wasm
2. Load and Instantiate¶
const wasmModule = await fetch('my_ai_program.wasm')
.then(r => r.arrayBuffer())
.then(b => WebAssembly.instantiate(b, { env: hostFunctions }));
const { main, memory, allocate } = wasmModule.instance.exports;
3. Connect to Real AI Service¶
hostFunctions.env._prompt = async (inputPtr, inputLen) => {
const prompt = readStringFromMemory(inputPtr, inputLen);
// Call your AI service (Ollama, Claude, etc.)
const response = await fetch('/api/prompt', {
method: 'POST',
body: JSON.stringify({ prompt })
}).then(r => r.json());
return writeStringToMemory(response.text);
};
Complete Working Example¶
Multilingual Code (ai_demo.multi)¶
let question = "What is machine learning?"
let answer = prompt @default: question
print("Q:", question)
print("A:", answer)
Compile to WASM¶
JavaScript Host (ai_demo.html)¶
<!DOCTYPE html>
<html>
<head><title>WASM AI Demo</title></head>
<body>
<div id="output"></div>
<script>
// Memory utilities
function readStringFromMemory(ptr, len) {
const buffer = new Uint8Array(memory.buffer, ptr, len);
return new TextDecoder().decode(buffer);
}
function writeStringToMemory(str) {
const encoded = new TextEncoder().encode(str);
const ptr = allocate(encoded.length);
const buffer = new Uint8Array(memory.buffer, ptr, encoded.length);
buffer.set(encoded);
return ptr;
}
// Host functions
const hostFunctions = {
env: {
_prompt: (inputPtr, inputLen) => {
const prompt = readStringFromMemory(inputPtr, inputLen);
const response = `Processed: "${prompt}"`;
return writeStringToMemory(response);
},
_generate: (inputPtr, inputLen) => {
return writeStringToMemory("Generated output");
},
_extract: (inputPtr, inputLen) => {
return writeStringToMemory("[]");
},
_classify: (inputPtr, inputLen) => {
return writeStringToMemory("NEUTRAL");
},
// ... other AI functions
}
};
// Load and run
let memory, allocate, main;
WebAssembly.instantiateStreaming(
fetch('ai_demo.wasm'),
hostFunctions
).then(({ instance }) => {
memory = instance.exports.memory;
allocate = instance.exports.allocate;
main = instance.exports.main;
// Execute main
main();
});
</script>
</body>
</html>
API Reference¶
| Keyword | Purpose | Input Format | Output Format |
|---|---|---|---|
prompt |
Ask a question | Plain text | Plain text |
generate |
Create content | Specification | Generated text |
extract |
Parse data | Unstructured text | JSON array |
classify |
Categorize | Text | Category label |
think |
Reason through | Problem | Reasoning steps |
stream |
Stream response | Query | Iterator/stream |
plan |
Create steps | Goal | List of steps |
embed |
Get vector | Text | Float array |
transcribe |
Audio→text | Audio data | Transcribed text |
Migration Path¶
Phase 1 (Current)¶
- ✅ Mock implementations (for testing)
- ✅ Dummy host imports
Phase 2 (v0.9.0)¶
- Plan: Real AI service integration
- Plan: Caching layer for embeddings
- Plan: Streaming support
Phase 3 (v1.0.0)¶
- Plan: Native WASI AI module
- Plan: Hardware acceleration for embeddings
- Plan: Multi-provider support (OpenAI, Anthropic, Ollama)
Troubleshooting¶
Error: Undefined host import _prompt¶
Cause: Host function not provided
Fix: Add _prompt to your hostFunctions.env object
Error: Invalid pointer in readStringFromMemory¶
Cause: WASM module didn't allocate memory properly
Fix: Ensure WASM module exports allocate() function
Responses are truncated or garbled¶
Cause: Memory write overflow
Fix: Increase buffer size or use dynamic allocation
Best Practices¶
- Always check buffer bounds before reading/writing
- Implement timeout handling for external AI calls
- Cache embeddings to avoid redundant computation
- Use separate host functions for different AI services
- Test with mock implementations first, then swap in real services
See Also¶
Contributing¶
To improve this guide or add new AI integrations:
- Create a pull request with your improvements
- Include working example code
- Document any new host import signatures
- Add test cases for new functionality
Generated: 2026-05-08
Maintainer: Multilingual Programming Team
License: GPL-3.0-or-later