# fai-module-sdk Stable, ergonomic Rust surface for writing F∆I Platform modules. A module written against this crate looks like: ```rust use fai_module_sdk::prelude::*; #[fai_module] fn invoke(_ctx: Context, inputs: Inputs) -> Result { let text = inputs.require_text("input")?; Ok(Outputs::new().with_text("output", format!("echo: {text}"))) } ``` That single function — plus a `Cargo.toml` listing `fai-module-sdk` as a dependency — is the entire module. The `#[fai_module]` macro generates the `wit_bindgen` invocation, the `Guest` implementation, the type conversions, and the `wit_bindgen::export!` glue behind the scenes. ## What the SDK gives you | You get | Instead of | |---------|-----------| | `Inputs::require_text("name")` | manual `match payload { Payload::Text(s) => ..., _ => ... }` | | `Outputs::new().with_json(...)?` | building `Vec<(String, Payload)>` by hand | | `ModuleError::invalid_input("...")` | constructing WIT `invocation-error` variants | | `#[fai_module]` | `wit_bindgen::generate!` + `Guest` impl + `export!` + `#![allow(unsafe_op_in_unsafe_fn)]` | ## Stability The SDK insulates module code from the underlying WIT contract (`chain:platform`, frozen at v1.0 in the platform repo). The WIT may evolve in additive minor versions or, eventually, a coordinated v2.0; the SDK absorbs that change so existing module code keeps compiling. The SDK ships its own copy of `wit/world.wit` so that the proc-macro can embed the contract via `include_str!` at compile time. A snapshot test (`crates/fai-module-sdk/tests/wit_freeze.rs`) asserts the SHA-256 matches the platform's frozen hash — if the two ever drift, CI fails. ## Versioning | Track | Stability | |-------|-----------| | WIT contract (`chain:platform`) | Frozen at v1.0 in the platform repo | | `fai-module-sdk` Rust API | Semver; v0.x while ergonomics evolve | | Per-module versions | Each module repo's own concern | ## License Apache-2.0. See `LICENSE`. Author: Dr. Stefan Flemming, Flemming.AI Repository: https://git.flemming.ai/fai/module-sdk-rust