agent-sdk 0.2.0

Rust Agent SDK for building LLM agents
Documentation
# Contributing to Agent SDK

Thank you for your interest in contributing to Agent SDK! This document provides guidelines and instructions for contributing.

## Code of Conduct

By participating in this project, you agree to maintain a respectful and inclusive environment for everyone.

## Getting Started

1. Fork the repository
2. Clone your fork: `git clone https://github.com/YOUR_USERNAME/agent-sdk.git`
3. Create a feature branch: `git checkout -b my-feature`
4. Make your changes
5. Run the quality checks (see below)
6. Commit your changes
7. Push to your fork and submit a pull request

## Development Setup

### Prerequisites

- Rust 1.85+ (2024 edition)
- Cargo

### Building

```bash
cargo build
```

### Running Tests

```bash
cargo test
```

## Code Quality

Before submitting a pull request, ensure your code passes all quality checks:

```bash
# Type check
cargo check --all-targets

# Format code
cargo fmt

# Lint (must pass with no warnings)
cargo clippy -- -D warnings

# Run tests
cargo test
```

All of these checks run in CI and must pass for a PR to be merged.

## Coding Guidelines

### Modern Rust Module System

Use the modern Rust 2018+ module style. **Do not use `mod.rs` files.**

```
src/
├── lib.rs              # mod llm;
├── llm.rs              # pub mod types; + main code
└── llm/
    └── types.rs
```

### Error Handling

Use `anyhow` for error handling:

```rust
use anyhow::{Result, Context, bail, ensure};

pub async fn my_function() -> anyhow::Result<Output> {
    let data = fetch_data().await.context("failed to fetch")?;
    ensure!(!data.is_empty(), "data cannot be empty");
    Ok(output)
}
```

**Never use `unwrap()` or `expect()`** - always propagate errors with `?` and add context.

### Self-Documenting Code

Prefer self-documenting code over comments:

```rust
// Avoid: redundant comment
/// Find a user by their ID.
pub async fn find_by_id(...) { }

// Good: name is clear, no comment needed
pub async fn find_by_id(...) { }

// Good: comment explains non-obvious behavior
/// Returns None if the thread was archived more than 24 hours ago.
pub async fn find_active_thread(...) { }
```

### Testing

- Test behavior, not implementation details
- Never change test expectations to make tests pass - fix the code
- Skip trivial tests where Rust's type system provides sufficient guarantees

```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn feature_works() -> anyhow::Result<()> {
        let store = InMemoryStore::new();
        let result = my_function(&store).await?;
        assert_eq!(result.status, ExpectedStatus);
        Ok(())
    }
}
```

### Clippy

Never bypass clippy with `#[allow(...)]` - fix the code instead:

```rust
// Bad: bypassing clippy
#[allow(clippy::too_many_arguments)]
pub fn create(a: A, b: B, c: C, d: D, e: E, f: F) { }

// Good: use a struct
pub struct CreateParams { pub a: A, pub b: B, /* ... */ }
pub fn create(params: CreateParams) { }
```

## Pull Request Process

1. Ensure all quality checks pass
2. Update documentation if you're changing public APIs
3. Add tests for new functionality
4. Keep PRs focused - one feature or fix per PR
5. Write clear commit messages that explain the "why"
6. Reference any related issues in the PR description

## Reporting Issues

When reporting issues, please include:

- A clear description of the problem
- Steps to reproduce
- Expected behavior
- Actual behavior
- Rust version (`rustc --version`)
- Operating system

## Feature Requests

Feature requests are welcome! Please open an issue describing:

- The problem you're trying to solve
- Your proposed solution
- Any alternatives you've considered

## License

By contributing to Agent SDK, you agree that your contributions will be licensed under the Apache License, Version 2.0.