Components
What is a Component?
Section titled “What is a Component?”A Component is a portable WebAssembly (WASM) building block that implements the Greentic WIT interface. Components are:
- Sandboxed - Execute in isolated WASM environment
- Portable - Run on any platform with Wasmtime
- Composable - Combine to build complex workflows
- Language-agnostic - Write in Rust, Go, or any WASM-compatible language
Component Types
Section titled “Component Types”| Type | Purpose | Example |
|---|---|---|
| Node | Flow processing step | LLM caller, template renderer |
| Provider | External service bridge | Telegram, Slack, SendGrid |
| Tool | MCP tool implementation | Database query, API call |
| Operator | Message transformation | Button handling, card rendering |
Creating a Component
Section titled “Creating a Component”Project Setup
Section titled “Project Setup”Use the component authoring CLI:
# Create new component projectgreentic-component new my-processor
cd my-processorThis generates:
my-processor/├── Cargo.toml├── src/│ └── lib.rs├── wit/│ └── component.wit└── build.shCargo.toml
Section titled “Cargo.toml”[package]name = "my-processor"version = "0.1.0"edition = "2024"
[lib]crate-type = ["cdylib"]
[dependencies]wit-bindgen = "0.53"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"
[profile.release]opt-level = "s"lto = trueWIT Interface
Section titled “WIT Interface”Define your component’s interface:
package greentic:my-processor;
interface types { record input { message: string, context: option<string>, }
record output { result: string, success: bool, }}
world processor { import types;
export process: func(input: types.input) -> types.output;}Implementation
Section titled “Implementation”use wit_bindgen::generate;
generate!({ world: "processor", path: "wit",});
struct MyProcessor;
impl Guest for MyProcessor { fn process(input: Input) -> Output { // Your processing logic here let result = format!("Processed: {}", input.message);
Output { result, success: true, } }}
export!(MyProcessor);Building
Section titled “Building”# Build for WASM targetcargo build --target wasm32-wasip2 --release
Advanced Component Patterns
Section titled “Advanced Component Patterns”Async Operations
Section titled “Async Operations”Components can perform async operations using WASI interfaces:
use wit_bindgen::generate;
generate!({ world: "async-processor", path: "wit", async: true,});
impl Guest for AsyncProcessor { async fn process(input: Input) -> Output { // Async HTTP call let response = http_fetch(&input.url).await;
Output { result: response.body, success: response.status == 200, } }}State Management
Section titled “State Management”Access session state within components:
impl Guest for StatefulProcessor { fn process(input: Input, state: &mut State) -> Output { // Read from state let counter = state.get("counter").unwrap_or(0);
// Update state state.set("counter", counter + 1);
Output { result: format!("Processed {} times", counter + 1), success: true, } }}Error Handling
Section titled “Error Handling”Use the Result type for error handling:
impl Guest for SafeProcessor { fn process(input: Input) -> Result<Output, Error> { if input.message.is_empty() { return Err(Error::InvalidInput("Message cannot be empty".into())); }
Ok(Output { result: process_message(&input.message)?, success: true, }) }}Built-in Components
Section titled “Built-in Components”Greentic provides several built-in components:
component-llm-openai
Section titled “component-llm-openai”Call OpenAI-compatible LLMs:
- id: analyze type: llm config: model: "gpt-4" system_prompt: "You are a helpful assistant." prompt: "{{message}}"component-templates
Section titled “component-templates”Render Handlebars templates:
- id: format type: template config: template: "Hello, {{name}}! Your order #{{order_id}} is ready."component-script-rhai
Section titled “component-script-rhai”Execute Rhai scripts:
- id: calculate type: script config: script: | let total = 0; for item in items { total += item.price * item.quantity; } totalcomponent-adaptive-card
Section titled “component-adaptive-card”Render and validate Adaptive Cards:
- id: show_card type: adaptive-card config: card: "cards/welcome.json" data: user_name: "{{user_name}}"Testing Components
Section titled “Testing Components”Unit Tests
Section titled “Unit Tests”#[cfg(test)]mod tests { use super::*;
#[test] fn test_process() { let input = Input { message: "Hello".into(), context: None, };
let output = MyProcessor::process(input);
assert!(output.success); assert!(output.result.contains("Processed")); }}Integration Tests
Section titled “Integration Tests”# Run with test harnessgreentic-component test ./my-processor
# Test with sample inputecho '{"message": "test"}' | greentic-component run ./my-processor.wasmComponent Best Practices
Section titled “Component Best Practices”- Keep components focused - Single responsibility
- Handle all errors - Never panic in production
- Minimize dependencies - Smaller WASM binaries
- Use strong types - Leverage WIT for type safety
- Document interfaces - Clear WIT definitions
- Test thoroughly - Unit and integration tests
- Optimize size - Use LTO and size optimization
Debugging Components
Section titled “Debugging Components”WASM Inspection
Section titled “WASM Inspection”# Inspect component exportswasm-tools component wit ./my-processor.wasm
# Validate componentwasm-tools validate ./my-processor.wasmLogging
Section titled “Logging”Use the WASI logging interface:
use greentic_interfaces::log;
impl Guest for DebugProcessor { fn process(input: Input) -> Output { log::debug(&format!("Processing: {:?}", input));
// ... processing ...
log::info("Processing complete"); output }}Next Steps
Section titled “Next Steps”- Providers - Build provider components
- MCP Tools - Create MCP tool components
- WIT Interfaces Reference - Complete WIT specification