iron-core 0.1.36

Core AgentIron loop, session state, and tool registry
Documentation
# iron-core

`iron-core` is the core embedding crate for AgentIron.

It provides:

- the stream-first `IronAgent` / `AgentConnection` / `AgentSession` facade
- durable messages, timeline entries, and tool-call records
- tool registration with JSON Schema argument validation
- approval-gated tool execution
- ACP-native transports for in-process, stdio, and TCP integrations
- context compaction, active-context accounting, and handoff export/import
- layered prompt composition with repository instruction loading and runtime context injection
- optional embedded Python execution via the `embedded-python` feature
- WASM integration plugins via Extism with install lifecycle, manifest extraction, session-scoped enablement, auth-gated tool availability, and a 30-second execution timeout

The facade/runtime API is the supported integration surface.

## Requirements

- Rust 1.95+
- Tokio for async embedding code

## Install

Use the git dependency for now:

```toml
[dependencies]
iron-core = { git = "https://github.com/AgentIron/iron-core", branch = "main" }
iron-providers = "0.2.2"
serde_json = "1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
```

`iron-core` is not ready for crates.io publication yet because the optional `embedded-python` feature depends on `monty` from git until a usable crates.io release exists.

If you need the built-in `python_exec` tool, enable the feature explicitly:

```toml
[dependencies]
iron-core = { git = "https://github.com/AgentIron/iron-core", branch = "main", features = ["embedded-python"] }
iron-providers = "0.2.2"
serde_json = "1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
```

## Quick Start

```rust,ignore
use iron_core::{Config, FunctionTool, IronAgent, PromptEvent, ToolDefinition};
use iron_providers::{ApiFamily, ProviderConnection, ProviderProfile, RuntimeConfig};
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = Config::new().with_model("gpt-4o");
    let provider = ProviderConnection::from_profile(
        ProviderProfile::new("openai", ApiFamily::Responses, "https://api.openai.com/v1"),
        RuntimeConfig::new(std::env::var("OPENAI_API_KEY")?),
    )?;
    let agent = IronAgent::new(config, provider);

    agent.register_tool(FunctionTool::new(
        ToolDefinition::new(
            "echo",
            "Return the provided text",
            json!({
                "type": "object",
                "properties": {
                    "text": { "type": "string" }
                },
                "required": ["text"]
            }),
        ),
        |args| Ok(json!({ "echo": args["text"].clone() })),
    ));

    let connection = agent.connect();
    let session = connection.create_session()?;
    let (handle, mut events) = session.prompt_stream("Call echo with hello.");

    while let Some(event) = events.next().await {
        match event {
            PromptEvent::Output { text } => print!("{text}"),
            PromptEvent::ApprovalRequest { call_id, .. } => {
                handle.approve(&call_id).expect("approval should be pending");
            }
            PromptEvent::Complete { outcome } => {
                println!("\nprompt finished: {outcome:?}");
                break;
            }
            _ => {}
        }
    }

    Ok(())
}
```

The canonical interaction model is stream-first:

- call `session.prompt_stream(...)`
- consume `PromptEvent`s as they arrive
- use `PromptHandle` to approve, deny, or cancel an active prompt

## Built-In Tools

`iron-core` can register built-in `read`, `write`, `edit`, `glob`, `grep`, and `webfetch` tools, plus `bash` or `powershell` when a shell is available.

Use `BuiltinToolConfig` to scope filesystem access, disable specific tools, and tune limits such as command timeouts and output caps.

## MCP Servers

`iron-core` supports session-scoped MCP (Model Context Protocol) servers as a tool source alongside built-in and custom tools. The full implementation covers:

- Runtime-local MCP server inventory with per-server configuration
- Session-scoped enablement governed by a single runtime-default policy
- Canonical session-effective tool catalog with precise unavailable-tool diagnostics
- Approval strategy enforcement for MCP tool calls
- Transport clients for stdio, HTTP, and HTTP+SSE
- Connection lifecycle management with single-flight connect guarding
- Handoff exclusion — MCP state is runtime-local and not portable

## Integration Plugins

`iron-core` includes a WASM-based integration-plugin surface powered by [Extism](https://extism.org). Plugins are a third tool source alongside built-in tools and MCP servers.

The plugin system is fully implemented:

- **Install lifecycle** — fetch (local or HTTPS+checksum), cache, manifest extraction from WASM binaries, identity validation, and Extism-backed WASM host loading
- **WASM execution** — tools are invoked via `tool_{name}` exports with a JSON request/response envelope and a 30-second timeout
- **Session-scoped enablement** — runtime-level defaults materialised at session creation, with per-session overrides
- **Canonical tool availability** — single-source-of-truth `compute_tool_availability()` gates tools on health, auth requirements, and scope satisfaction
- **Auth model** — runtime-governed auth state, credential bindings, and per-tool scope checks
- **Tool diagnostics** — structured `UnavailableReason` variants for actionable error messages
- **Network policy** — allowlist, blocklist, and wildcard policies declared in plugin manifests

## Development

Install the security tooling if you want to run the same audit check CI reports:

```bash
cargo install cargo-audit
```

Configure the repository pre-commit hook after cloning:

```bash
git config core.hooksPath .githooks
```

The pre-commit hook runs `cargo fmt --manifest-path Cargo.toml -- --check` when staged Rust files are present. Before opening or updating a pull request, run the same checks CI validates:

```bash
cargo build --manifest-path Cargo.toml --all-targets
cargo fmt --manifest-path Cargo.toml -- --check
cargo clippy --manifest-path Cargo.toml --all-targets --all-features -- -D warnings
cargo test --manifest-path Cargo.toml
cargo audit --file Cargo.lock
```

The local `invoke` tasks in `tasks.py` are a convenience layer over these checks:

```bash
inv build
inv test
inv security
```

The `Pull Request` workflow runs build, format, lint, and test checks on every PR to `main`. It also runs `cargo audit` as a non-blocking audit and posts the output as a PR comment.

Merges to `main` trigger an automatic patch release that bumps `Cargo.toml`, creates a `vX.Y.Z` tag, and creates a GitHub release. Publishing to crates.io is skipped until `monty` is available from crates.io because crates.io rejects manifests containing git dependencies.

## Documentation

- [Architecture Overview]docs/architecture-overview.md
- [Getting Started]docs/getting-started-iron-core.md
- [Integration Plugins]docs/integration-plugins.md
- [Prompt Composition]docs/prompt-composition.md
- [Architecture Cleanup Checklist]docs/architecture-cleanup-checklist.md

Build the API docs locally with:

```bash
cargo doc -p iron-core --no-deps
```

## License

Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE).