omegon-extension 0.25.2

Omegon extension SDK — safe, versioned interface for third-party extensions
Documentation
# omegon-extension

Safe, versioned SDK for building [Omegon](https://github.com/styrene-lab/omegon) extensions.

Extensions run as isolated processes communicating via JSON-RPC over stdin/stdout. An extension crash never crashes the host agent.

## Usage

```toml
[dependencies]
omegon-extension = "0.25"
```

`omegon-extension` uses normal crate SemVer for Rust releases and exposes
`SDK_CONTRACT_VERSION` for cross-language wire compatibility. SDK crate versions
are independent from Omegon host patch versions; the current crate line can still
expose SDK contract version `0.24` for host compatibility.
Python and TypeScript SDKs validate against the canonical contract artifact in
`schema/sdk-contract.json`, which is also embedded as `SDK_CONTRACT_JSON`.

```rust
use omegon_extension::{Extension, serve};
use serde_json::{json, Value};

#[derive(Default)]
struct MyExtension;

#[async_trait::async_trait]
impl Extension for MyExtension {
    fn name(&self) -> &str { "my-extension" }
    fn version(&self) -> &str { env!("CARGO_PKG_VERSION") }

    async fn handle_rpc(&self, method: &str, params: Value) -> omegon_extension::Result<Value> {
        match method {
            "get_tools" => Ok(json!([
                {
                    "name": "hello",
                    "description": "Return a greeting",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "name": {"type": "string"}
                        }
                    }
                }
            ])),
            "execute_tool" => {
                let name = params["name"].as_str().unwrap_or("");
                let args = params.get("args").cloned().unwrap_or_default();
                match name {
                    "hello" => Ok(json!({
                        "content": [{
                            "type": "text",
                            "text": format!(
                                "Hello, {}!",
                                args["name"].as_str().unwrap_or("World")
                            )
                        }]
                    })),
                    _ => Err(omegon_extension::Error::method_not_found(name)),
                }
            }
            _ => Err(omegon_extension::Error::method_not_found(method)),
        }
    }
}

#[tokio::main]
async fn main() {
    serve(MyExtension::default()).await.unwrap();
}
```

## HostActions

HostActions are the SDK contract for host-managed side effects. Extensions describe
intent; Omegon validates every action, applies manifest/runtime/operator policy, and
only then renders or executes it. Returning a HostAction does not make the effect run
by itself.

Use declarative actions in ordinary tool results when the host should present or queue
a side effect with the tool response:

```rust
use omegon_extension::{HostAction, ToolResult};
use omegon_extension::actions::terminal::{TERMINAL_CREATE_V1, TerminalCreateParams};

let params = TerminalCreateParams::new("bookokrat")
    .with_args(["/books/example.epub"]);
let action = HostAction::new("open-reader", TERMINAL_CREATE_V1, params)?;
let result = ToolResult::text("Opening reader").with_action(action);
let value = serde_json::to_value(result)?;
```

The serialized tool result contains ordinary content plus an `actions` array:

```json
{
  "content": [{"type": "text", "text": "Opening reader"}],
  "actions": [{
    "id": "open-reader",
    "type": "terminal.create@1",
    "params": {
      "command": "bookokrat",
      "args": ["/books/example.epub"]
    }
  }]
}
```

Extensions that need the advanced imperative path can use `HostProxy` from `serve_v2()`.
`execute_action()` sends JSON-RPC method `actions/execute` with params
`{"action": <HostAction>}` and returns a full `HostActionOutcome`:

```rust
use omegon_extension::actions::terminal::TerminalCreateResult;

let outcome = host.execute_action(action).await?;
if let Some(result) = outcome.result {
    let terminal: TerminalCreateResult = serde_json::from_value(result)?;
    eprintln!("opened {} via {}", terminal.terminal_id, terminal.backend);
}
```

The expected host response shape is:

```json
{
  "action_id": "open-reader",
  "status": "completed",
  "result": {
    "terminal_id": "term_123",
    "backend": "zellij",
    "actual_placement": "background_session"
  }
}
```

To advertise support during `initialize`, set the capability flags relevant to the
extension:

```json
{
  "capabilities": {
    "tools": true,
    "host_actions": true,
    "host_action_execution": true
  }
}
```

`terminal.create@1` is SDK/protocol foundation only. The host-side executor, policy
engine, and real terminal process creation live in Omegon core, not in this crate.

## License

Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT License](LICENSE-MIT) at your option.