Enhancing ActivePieces Framework for Multi-Language Execution Via WebAssembly

Enhancing ActivePieces Framework for Multi-Language Execution Via WebAssembly

Background:
Pieces Framework designed to facilitate integration between APIs through triggers, actions, and connections. However, its current architecture predominantly supports JavaScript/TypeScript, limiting the developer ecosystem to those proficient in these languages.

WebAssembly (Wasm) offers a secure, lightweight, and highly portable runtime that allows code written in various languages to run efficiently on any platform. By integrating WebAssembly into the ActivePieces Pieces Framework, we can unlock the ability to support multiple programming languages, attracting a more diverse developer base and broadening the platform’s utility.

Proposal Objectives

  1. Enable Polyglot Development:

    • Support the development of Pieces using any language that compiles to WebAssembly (e.g., Rust, Go, Python, C/C++).
    • Attract a diverse pool of developers, allowing them to work in their preferred languages while contributing to the ActivePieces ecosystem.
  2. Improve Performance:

    • Leverage WebAssembly’s near-native execution speeds to enhance runtime efficiency of Pieces.
    • Optimize resource utilization for computationally intensive tasks, making automation workflows faster and more scalable.
  3. Expand Ecosystem:

    • Increase adoption by attracting developers from varied programming backgrounds.
    • Facilitate the growth of reusable, language-agnostic modules that enrich the ActivePieces marketplace.
  4. Future-Proofing:

    • Position ActivePieces as a forward-thinking platform aligned with industry trends in software development.
    • Adopt cutting-edge technologies like WebAssembly and Firecracker to maintain relevance in the rapidly evolving automation and cloud spaces.
  5. Enable Efficient Infrastructure for AI Agents:

    • Provide a robust and high-performance infrastructure for hosting AI agents within the ActivePieces ecosystem.
    • Facilitate secure, sandboxed execution of AI-driven Pieces, enabling scalable workflows that leverage artificial intelligence.
  6. Cloud-Ready, Secure Multitenancy:

    • Empower the cloud version of ActivePieces to run custom customer-developed Pieces within a secure, multitenant sandboxed environment.
    • Isolate customer workflows to ensure data security and prevent cross-tenant interference.
  7. Usage-Based Billing:

    • Enable serverless function-style billing for customer-deployed Pieces in the cloud.
    • Charge customers based on actual resource consumption (e.g., execution time, memory usage), similar to how cloud providers bill for serverless functions.
    • Provide a flexible and cost-efficient model for customers, aligning costs directly with their usage.

These objectives ensure that the proposal aligns with both technical enhancements and business value, addressing ActivePieces’ future needs for scalability, security, and customer satisfaction.

Proposed Solution

1. Integrate a WebAssembly Runtime into the Pieces Framework

  • Choose a Wasm runtime compatible with server-side execution, such as:
    • WasmEdge: Lightweight and optimized for server-side apps.
    • Wasmer: Supports multi-language interfaces.
    • WASI: Provides system interfaces for WebAssembly modules.
  • Embed the runtime within the ActivePieces executor service to handle Wasm modules.

2. Create a Language-Agnostic Interface for WebAssembly Pieces

  • Define a standardized API contract for WebAssembly modules to interact with the ActivePieces environment.
  • Example: Modules export specific functions (e.g., trigger(), action()), which are invoked by the ActivePieces runtime.
  • Provide SDKs for popular languages to streamline development.

3. Build Tooling for Developers

  • Develop a CLI tool for compiling, testing, and packaging Pieces in any Wasm-supported language.
  • Offer templates and starter kits for languages like Rust, Go, and Python to simplify onboarding.

4. Implement Compatibility with Existing Pieces

  • Ensure backward compatibility with existing JavaScript/TypeScript Pieces.
  • Develop a seamless migration path for developers who want to port JavaScript Pieces to Wasm.

5. Optimize Deployment and Resource Management

  • Use caching mechanisms to precompile Wasm modules for faster execution.
  • Implement resource-limiting features to sandbox modules and ensure security.

Key Benefits

  1. Broader Developer Reach: Attract developers proficient in Rust, Go, Python, and more.
  2. Performance Gains: Optimize Pieces for high-performance scenarios with Wasm’s efficient runtime.
  3. Enhanced Security: Isolate execution of Pieces to mitigate risks.
  4. Ecosystem Growth: Foster a vibrant community contributing multilingual Pieces.

Proposed Implementation Phases

Phase Description Deliverables
Phase 1: Research Evaluate Wasm runtimes and define API contracts. - Technical documentation on runtime selection
- API contract specifications
Phase 2: Prototype Build a prototype runtime integration for WebAssembly Pieces. - Working prototype of Wasm-based Pieces execution
Phase 3: Tooling Develop SDKs, CLI tools, and language-specific templates. - CLI tool
- Rust/Go/Python SDKs and templates
Phase 4: Testing Perform extensive testing to ensure stability, security, and backward compatibility. - Test cases
- Performance benchmarks
Phase 5: Release Deploy the enhanced framework with comprehensive developer documentation and tutorials. - Production-ready framework
- Updated documentation and tutorials

Key Benefits

  1. Broader Developer Reach: Attract developers proficient in Rust, Go, Python, and more.
  2. Performance Gains: Optimize Pieces for high-performance scenarios with Wasm’s efficient runtime.
  3. Enhanced Security: Isolate execution of Pieces to mitigate risks.
  4. Ecosystem Growth: Foster a vibrant community contributing multilingual Pieces.

1. Runtime Integration

The foundation of this enhancement lies in embedding a WebAssembly runtime into the Pieces Framework. We’ll explore the technical aspects for runtime compatibility and execution.

Runtime Evaluation

  • WasmEdge:
    • Designed for server-side WebAssembly.
    • Optimized for performance-critical applications, making it ideal for ActivePieces’ automation scenarios.
    • Features:
      • Built-in support for WASI.
      • Extensions for handling HTTP and other protocols, which are crucial for API-based automation.
  • Wasmer:
    • Lightweight runtime with multi-language support.
    • Supports Emscripten, WASI, and custom imports for interacting with the host environment.
    • Modular, allowing integration with plugins for specific needs.
  • WASI:
    • WebAssembly System Interface standard for interacting with file systems, sockets, and environment variables.
    • Suitable for creating sandboxed execution environments.

1. Potential Execution Pipeline

  1. Precompilation:
  • Pieces written in any Wasm-supported language are compiled to .wasm files.
  • Use ahead-of-time (AOT) compilation when possible to optimize runtime performance.
  1. Runtime Loader:
  • Integrate a loader in the ActivePieces executor to initialize and manage Wasm modules.
  • Modules are validated, sandboxed, and cached for reuse.
  1. Host API Bindings:
  • Provide bindings for common operations (e.g., making HTTP requests, reading environment variables) using WASI or custom imports.

2. Language-Agnostic API for Wasm Pieces

To ensure interoperability between languages, define a universal API contract that Wasm modules must implement.

Exported Functions

Each Wasm module must export specific functions adhering to a standard interface:

  • trigger(params: Input): Output
  • action(params: Input): Output
  • init(config: Config): void
Example (in Rust)

rust

#[no_mangle]
pub extern "C" fn trigger(input_ptr: *const u8, input_len: usize) -> *mut u8 {
    let input = deserialize_input(input_ptr, input_len);
    let output = process_trigger(input);
    serialize_output(output)
}

#[no_mangle]
pub extern "C" fn init(config_ptr: *const u8, config_len: usize) {
    let config = deserialize_config(config_ptr, config_len);
    initialize_runtime(config);
}

Input and Output Formats

  • Use standardized formats like JSON or MessagePack for serialization.
  • Provide libraries for common serialization/deserialization tasks in supported languages.

3. Developer Workflow and Tooling

A seamless developer experience is critical for adoption. Build tools to simplify the creation, testing, and deployment of Wasm-based Pieces.

CLI Tool

  • Commands:
    • ap-wasm init: Create a new Piece in the language of choice.
    • ap-wasm build: Compile the Piece to a .wasm file.
    • ap-wasm test: Run the Piece locally for validation.
    • ap-wasm deploy: Package and upload the Piece to the ActivePieces platform.
  • Output standardized .wasm files with metadata (e.g., required imports, environment variables).

SDKs

Language-specific SDKs abstract the complexities of Wasm module creation and provide helpers for:

  • Serialization/deserialization of inputs and outputs.
  • Accessing host-provided APIs (e.g., HTTP requests).
  • Managing state and configuration.
Example Languages
  • Rust: Leverage wasm-bindgen and serde for bindings.
  • Go: Use tinygo for compilation and helper libraries for WASI.
  • C#: Use the dotnet-wasi-sdk to create .wasm modules with WASI bindings.

4. Security Enhancements

WebAssembly is designed with security in mind, but additional measures ensure robust sandboxing for executing third-party Pieces.

Sandboxing

  • Restrict file system access using WASI capabilities.
  • Limit resource usage (e.g., CPU, memory) through runtime configurations.
  • Disallow arbitrary network access unless explicitly permitted via API imports.

Validation

  • Validate Wasm binaries during upload to ensure:
    • No unauthorized imports.
    • Compliance with the API contract.
    • Safe execution limits.

5. Developer Ecosystem Growth

Wasm Registry

Create a public registry for Wasm-based Pieces:

  • Developers can share reusable modules.
  • Modules are tagged by language, API, and functionality.

Community Contributions

Encourage community development by:

  • Hosting hackathons focused on non-JS/TS languages.
  • Offering incentives for high-quality contributions.

FireCracker: a safe multitenant host for executing pieces as a microVMs

Firecracker, an open-source virtualization technology developed by Amazon Web Services (AWS), is designed to create and manage lightweight virtual machines called microVMs. These microVMs offer strong security and isolation, making Firecracker a potential host for executing WebAssembly (Wasm) modules. By running Wasm-based pieces within microVMs, Firecracker can provide a secure and efficient environment, combining the portability of Wasm with the robust isolation of microVMs.

Endgame: Unlocking Shared Economy and Network Effects in the ActivePieces Ecosystem

By empowering developers to use their preferred programming languages and providing a platform for monetization, ActivePieces can harness the network effect to build a robust ecosystem. This strategy not only attracts developers from diverse backgrounds but also creates a virtuous cycle where a growing library of Pieces attracts more customers, driving further contributions and fostering innovation in automation. The shared economy model ensures developers are incentivized to contribute, making ActivePieces a thriving, collaborative, and scalable platform.

This is a very interesting idea, though I wonder how many new developers it would actually attract. JavaScript is an… imperfect… language, but so ubiquitous and accessible that I’d expect that most people capable of writing an integration in other languages could manage it in JS.

I’m very curious how big the performance improvement would actually be. We were actually talking about this topic earlier today in the Discord. I’d love to know if WASM’s sandboxing mechanism is significantly more efficient than the ones currently in use.

What kind of flows do you have that would benefit from this extra performance?
The pieces I generally use are bottlenecked by network request(s) far more than the speed of their code.

Tangentially related: Supabase uses WASM to run untrusted user-provided extensions on their servers.

1 Like

Thanks for the response,
regarding performance, MicroVMs are not the perfect example in terms of performance in comparison to node.js Isolated-vm, but WasmEdge could be a better sandboxing option.
Here’s a side-by-side comparison between WasmEdge and Node.js isolated-vm:

Feature WasmEdge Node.js isolated-vm
Runtime Type WebAssembly runtime optimized for server-side execution JavaScript runtime sandbox based on V8 isolates
Language Support Polyglot: Supports any language that compiles to WebAssembly (e.g., Rust, Go, Python) JavaScript and WebAssembly within the Node.js ecosystem
Startup Speed Extremely fast due to lightweight design and AOT compilation Very fast within the same process, but tied to V8’s initialization overhead
Execution Speed Near-native performance with low overhead High performance for JavaScript but slightly more overhead for non-JS tasks
Isolation Level Lightweight, sandboxed runtime with WASI and host bindings Process-level isolation using V8 contexts
Resource Management Configurable memory and CPU limits; low memory overhead Limited control, shares resources with the host process
Security Strong sandboxing; designed for secure multitenant environments Moderate security; relies on V8’s isolate-based sandboxing
Supported Workflows Server-side apps, API processing, edge computing, serverless Lightweight JS-centric automations and secure code execution
Cold Start Latency Millisecond-level (AOT-compiled Wasm modules are preloaded) Sub-millisecond, but less efficient for large-scale workloads
Extensibility Built-in support for HTTP, gRPC, and custom host extensions Limited to Node.js APIs and JavaScript
Use Cases Polyglot serverless functions, edge computing, lightweight AI Quick JavaScript or WebAssembly task execution in Node.js
Resource Footprint Very small (optimized for low-memory environments) Medium; depends on Node.js runtime environment
Scalability Designed for high-concurrency, low-overhead multitenancy Limited scalability due to Node.js’s event loop constraints

For the nest uses cases of Wasm with ActivePieces:

  • A custom logic that be built using any language and get executed within the piece.
  • could be a long-running logic such as worker task in Orkas platform: Worker Task (Simple) | Orkes Conductor Documentation
  • could be a new way to extend the logic of ActivePieces workers, instead of the current limitations.
  • Or even a logic/code host for future agentic ActivePieces features.-

The more the platform supports human workflows and interactions, i believe we could use such a feature.

And yes, hosting and executing customers’ untrusted code is the best use case for wasm support.