jev-sdk 0.1.0

Unofficial Rust client for the TypeSafe AI System One API (Jev): typed decisions with calibrated probabilities
Documentation
//! # jev-sdk
//!
//! A Rust client for the [TypeSafe AI](https://typesafe.ai) System One API.
//!
//! [Jev](https://typesafe.ai/blog/introducing-system-one-models-and-jev) is a
//! System One model: instead of generating text, it evaluates typed
//! *questions* against a *state* and returns structured decisions with
//! calibrated probabilities and confidence — fast enough to sit inside
//! ordinary code paths.
//!
//! ## Quick start
//!
//! ```no_run
//! use jev_sdk::{Choice, Noul, Question, Score, TypeSafeClient};
//!
//! # async fn example() -> Result<(), jev_sdk::Error> {
//! // Reads TYPESAFE_API_KEY from the environment.
//! let client = TypeSafeClient::from_env()?;
//!
//! let ticket = "Hi, I've been trying to connect my Stripe account for 3 days \
//!               and it keeps failing. I'm losing sales. Please help ASAP.";
//!
//! let response = client
//!     .system_one(
//!         ticket,
//!         [
//!             (
//!                 "department",
//!                 Question::from(Choice::new(
//!                     "Which team should handle this",
//!                     [
//!                         ("billing", Some("Payment or subscription issues")),
//!                         ("technical", Some("Bugs or integration problems")),
//!                         ("sales", Some("Pricing or account questions")),
//!                     ],
//!                 )),
//!             ),
//!             (
//!                 "frustration",
//!                 Question::from(Score::new(
//!                     "How frustrated the customer appears",
//!                     ["Calm, just stating facts", "Frustrated but civil", "Very angry"],
//!                 )),
//!             ),
//!             (
//!                 "is_urgent",
//!                 Question::from(Noul::new("The message conveys urgency or time-sensitivity")),
//!             ),
//!         ],
//!     )
//!     .await?;
//!
//! let department = response.choice("department").unwrap();
//! println!("route to {} (confidence {:.2})", department.choice, department.confidence);
//! println!("frustration: {:.2}", response.score("frustration").unwrap().score);
//! println!("urgent: {:.3}", response.noul("is_urgent").unwrap().noul);
//! # Ok(())
//! # }
//! ```
//!
//! ## Configuration
//!
//! | Setting | Environment variable | Default |
//! |---------|----------------------|---------|
//! | API key | `TYPESAFE_API_KEY` | — (required) |
//! | Model | `TYPESAFE_DEFAULT_MODEL` | `jev-latest` |
//! | Base URL | `TYPESAFE_BASE_URL` | `https://api.typesafe.ai` |
//!
//! Use [`TypeSafeClient::builder`] for timeouts, retry policy, extra headers,
//! or a custom `reqwest` client. See [`RetryPolicy`] for retry behavior
//! (transient `429`/`529` responses are retried with exponential backoff by
//! default).

mod client;
mod error;
mod models;
mod question;
mod response;
mod retry;

pub use client::{
    ClientBuilder, TypeSafeClient, DEFAULT_BASE_URL, DEFAULT_MODEL, DEFAULT_TIMEOUT, ENV_API_KEY,
    ENV_BASE_URL, ENV_DEFAULT_MODEL,
};
pub use error::{ApiError, Error};
pub use models::{ListModelsResponse, ModelCard};
pub use question::{Choice, IntoContent, IntoDescription, Noul, NoulCriteria, Question, Score};
pub use response::{Answer, ChoiceAnswer, NoulAnswer, ScoreAnswer, SystemOneResponse, Usage};
pub use retry::RetryPolicy;