agentix 0.18.2

Multi-provider LLM client for Rust — streaming, non-streaming, tool calls, MCP, DeepSeek, OpenAI, Anthropic, Gemini
Documentation
# v0.4.0 — Release notes

Version: 0.4.0 (breaking)
Date: 2026-03-23

## Summary

This release marks the evolution of the crate into a multi-provider LLM agent framework. We have unified the API across DeepSeek, OpenAI, Anthropic, and Gemini, and introduced significant improvements to the tool-calling system.

The core goal of this release is to provide a robust, type-safe, and idiomatic Rust experience for building LLM agents.

---

## Key Features & Improvements

### 1. Robust Tool Macro (`#[tool]`)
- **dtolnay trick implementation**: The `#[tool]` macro now intelligently handles both plain return types (`T`) and `Result<T, E>`.
- **Automatic Error Propagation**: When a tool returns `Result::Err(e)`, it is automatically converted to `{"error": e.to_string()}` and sent back to the LLM. This encourages models to self-correct based on readable error messages.
- **Type Safety**: Input parameters are statically checked for `JsonSchema` and `Deserialize` implementation.
- **Recursive Schema Generation**: Improved JSON Schema generation for complex types like `Vec<T>`, `Option<T>`, and nested structs.

### 2. Multi-Provider Support
- Unified `LlmClient` and `Agent` abstractions for:
  - **DeepSeek** (chat and reasoner)
  - **OpenAI** (GPT-4o, etc.)
  - **Anthropic** (Claude 3.5 Sonnet/Opus)
  - **Gemini** (2.0 Flash/Pro)

### 3. Shared Context & Memory
- Introduced `SharedContext` for thread-safe state management across agents.
- Pluggable `Memory` traits (InMemory, SlidingWindow) for managing conversation history.

### 4. Re-exported Dependencies
- `agentix` now re-exports `serde`, `serde_json`, `async_trait`, and `schemars`. Users no longer need to manually add these to their `Cargo.toml` to use the `#[tool]` macro.

---

## Breaking Changes

- **Macro Expansion Path**: The `#[tool]` macro now generates code referencing `agentix::...`. You must ensure `agentix` is available in your scope.
- **Result Serialization**: Returning `Result<T, E>` from a tool no longer serializes as `{"Ok": ...}` or `{"Err": ...}`. It now transparently returns the success value or an `{"error": "..."}` object.
- **Error Constraint**: Any error type `E` returned in a `Result<T, E>` from a tool must now implement `std::fmt::Display`.

---

## Quick Migration

### Old Tool (v0.3.x)
```rust
#[tool]
impl Tool for MyTool {
    async fn run(&self, input: String) -> serde_json::Value {
        serde_json::json!({ "output": input })
    }
}
```

### New Tool (v0.4.0)
```rust
#[tool]
impl Tool for MyTool {
    async fn run(&self, input: String) -> String {
        input // Plain types just work
    }
}
// OR with error handling
#[tool]
impl Tool for MyTool {
    async fn run(&self, input: String) -> Result<String, MyError> {
        Ok(input)
    }
}
```

---

## How to Test

```bash
cargo test --workspace
```

---

## Roadmap

- MCP (Model Context Protocol) server support enhancement.
- Advanced graph-based multi-agent orchestration.
- Semantic summarizers for long-term memory.