Components
Component とは?
Section titled “Component とは?”Component は、Greentic WIT interface を実装するポータブルな WebAssembly (WASM) building block です。component には次の特徴があります:
- Sandboxed - 分離された WASM environment で実行される
- Portable - Wasmtime がある任意の platform で動作する
- Composable - 組み合わせて複雑な workflow を構築できる
- Language-agnostic - Rust、Go、または任意の WASM-compatible language で書ける
Component の種類
Section titled “Component の種類”| Type | 用途 | 例 |
|---|---|---|
| Node | flow の処理ステップ | LLM caller、template renderer |
| Provider | 外部サービスとの bridge | Telegram、Slack、SendGrid |
| Tool | MCP tool implementation | database query、API call |
| Operator | メッセージ変換 | button handling、card rendering |
Component の作成
Section titled “Component の作成”Project Setup
Section titled “Project Setup”component authoring CLI を使います:
# Create new component projectgreentic-component new my-processor
cd my-processor生成される構成:
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”component の 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;}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);# Build for WASM targetcargo build --target wasm32-wasip2 --release
高度な Component パターン
Section titled “高度な Component パターン”Async operations
Section titled “Async operations”component は、WASI interface を使って async operation を実行できます:
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 管理
Section titled “State 管理”component 内で session state にアクセスできます:
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, } }}エラーハンドリング
Section titled “エラーハンドリング”エラーハンドリングには Result 型を使います:
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, }) }}組み込み Components
Section titled “組み込み Components”Greentic はいくつかの組み込み component を提供します:
component-llm-openai
Section titled “component-llm-openai”OpenAI-compatible LLM を呼び出します:
- id: analyze type: llm config: model: "gpt-4" system_prompt: "You are a helpful assistant." prompt: "{{message}}"component-templates
Section titled “component-templates”Handlebars template を render します:
- id: format type: template config: template: "Hello, {{name}}! Your order #{{order_id}} is ready."component-script-rhai
Section titled “component-script-rhai”Rhai script を実行します:
- 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”Adaptive Cards を render および validate します:
- id: show_card type: adaptive-card config: card: "cards/welcome.json" data: user_name: "{{user_name}}"Component のテスト
Section titled “Component のテスト”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 のベストプラクティス
Section titled “Component のベストプラクティス”- Keep components focused - 単一責務にする
- Handle all errors - production で panic させない
- Minimize dependencies - WASM binary を小さく保つ
- Use strong types - 型安全のために WIT を活用する
- Document interfaces - WIT definition を明確にする
- Test thoroughly - unit test と integration test を行う
- Optimize size - LTO と size optimization を使う
Component のデバッグ
Section titled “Component のデバッグ”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”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 }}次のステップ
Section titled “次のステップ”- Providers - provider component を構築する
- MCP Tools - MCP tool component を作成する
- WIT Interfaces Reference - 完全な WIT specification