rtb-chat 0.7.1

Unified multi-provider AI chat client for Claude, OpenAI, Gemini, and OpenAI-compatible endpoints. Part of the phpboyscout Rust toolkit.
Documentation
[package]
name = "rtb-chat"
description = "Unified multi-provider AI chat client for Claude, OpenAI, Gemini, and OpenAI-compatible endpoints. Part of the phpboyscout Rust toolkit."
version = "0.7.1"
edition = "2021"
rust-version = "1.82"
license = "MIT"
authors = ["Matt Cockayne <matt@phpboyscout.com>"]
repository = "https://gitlab.com/phpboyscout/rust/chat"
homepage = "https://chat.rust.phpboyscout.uk"
documentation = "https://docs.rs/rtb-chat"
readme = "README.md"
categories = ["api-bindings", "development-tools"]
keywords = ["ai", "chat", "llm", "claude", "openai"]

[lints.rust]
# `deny` (not forbid) so the genai-key shim in `src/client.rs` can
# locally `allow(unsafe_code)` the `std::env::set_var` it needs to hand
# the API key to genai — the single documented exception. No other
# `unsafe` anywhere.
unsafe_code = "deny"
missing_docs = "warn"

[lints.clippy]
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
cargo = { level = "warn", priority = -1 }
module_name_repetitions = "allow"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
multiple_crate_versions = "allow"

[dependencies]
# Error strings are scrubbed through `rtb_redact::string` before they
# reach diagnostics — the only rtb-* dependency this crate needs.
# (rtb-app, rtb-error, and rtb-credentials were declared in the
# monorepo but never imported; dropped at extraction per playbook §8.5.)
rtb-redact = "0.6.0"

# Multi-provider chat client — covers OpenAI / Gemini / Ollama /
# OpenAI-compatible endpoints.
genai = "0.6.5"

# Direct Anthropic Messages API path (cache, thinking, citations) +
# the base HTTP client for streaming/extracting bytes.
reqwest = { version = "0.13.4", default-features = false, features = ["rustls", "json", "stream", "gzip"] }
url = "2.5.8"

# Async + stream plumbing.
tokio = { version = "1.53.0", features = ["full"] }
async-trait = "0.1.91"
futures-util = "0.3.33"
bytes = "1.12.1"

# Serde + structured-output validation.
serde = { version = "1.0.229", features = ["derive"] }
serde_json = "1.0.150"
schemars = "1.2.1"
jsonschema = "0.48.1"

# Errors + diagnostics.
miette = { version = "7.6.0", features = ["fancy"] }
thiserror = "2.0.19"
tracing = "0.1.44"

# Secrets — `Config::api_key` is `SecretString` end-to-end.
secrecy = "0.10.3"

[dev-dependencies]
wiremock = "0.6.5"