Skip to main content

Client

Struct Client 

Source
pub struct Client { /* private fields */ }
Expand description

Asynchronous TypeSafe System One client.

Cheap to clone (Arc internally) and safe to share across tasks (Send + Sync).

§Examples

use typesafe_rs::{questions, Client, ClientConfig, Question};

let client = ClientConfig::new().api_key("sk-...").build()?;
let response = client
    .system_one(
        "Help! My payouts have been failing for 3 days.",
        questions! { "urgent" => Question::noul("Does this convey urgency?") },
    )
    .await?;
assert!(response.noul("urgent").is_some());

Implementations§

Source§

impl Client

Source

pub fn new(config: ClientConfig) -> Result<Self, Error>

Build a client. Unset fields fall back to the process environment, then defaults.

§Errors

Returns Error::MissingApiKey when no key is configured, or Error::InvalidRequest for invalid timeout / retry / URL values.

Examples found in repository?
examples/quickstart.rs (lines 20-25)
14async fn main() -> Result<(), Box<dyn std::error::Error>> {
15    let mock = MockServer::start().await;
16    mock.on_system_one().respond(json!({
17        "urgent": noul(0.97),
18    }));
19
20    let client = Client::new(ClientConfig {
21        api_key: Some("test".into()),
22        base_url: Some(mock.url()),
23        default_model: Some("jev-latest".into()),
24        ..ClientConfig::default()
25    })?;
26
27    let response = client
28        .system_one(
29            "Help! My payouts have been failing for 3 days.",
30            questions! {
31                "urgent" => Question::noul("Does this convey urgency?")
32                    .when_true("Explicitly time-sensitive")
33                    .when_false("No time pressure"),
34            },
35        )
36        .await?;
37
38    println!("urgent noul = {:?}", response.noul("urgent"));
39    println!("request id  = {:?}", response.meta.request_id);
40    Ok(())
41}
Source

pub fn from_env() -> Result<Self, Error>

Self::new using TYPESAFE_* from the process environment.

Source

pub fn new_with_env( config: ClientConfig, lookup: impl FnMut(&str) -> Option<String>, ) -> Result<Self, Error>

Like Self::new, but environment fallbacks come from lookup.

Intended for tests and embeddings that should not read process env.

Source

pub fn default_model(&self) -> &str

Default model used when a request omits model.

Source

pub fn base_url(&self) -> &Url

Resolved API root, without a trailing slash.

Source

pub async fn system_one( &self, state: impl Serialize, questions: Questions, ) -> Result<SystemOneResponse, Error>

Evaluate state against questions using client defaults.

state may be a string, object, or array. Question keys are returned on SystemOneResponse::answers.

§Errors

Returns Error::InvalidRequest before any network call when the question map is empty or a Choice/Score is under-specified. Network and API failures use the rest of Error.

Examples found in repository?
examples/quickstart.rs (lines 28-35)
14async fn main() -> Result<(), Box<dyn std::error::Error>> {
15    let mock = MockServer::start().await;
16    mock.on_system_one().respond(json!({
17        "urgent": noul(0.97),
18    }));
19
20    let client = Client::new(ClientConfig {
21        api_key: Some("test".into()),
22        base_url: Some(mock.url()),
23        default_model: Some("jev-latest".into()),
24        ..ClientConfig::default()
25    })?;
26
27    let response = client
28        .system_one(
29            "Help! My payouts have been failing for 3 days.",
30            questions! {
31                "urgent" => Question::noul("Does this convey urgency?")
32                    .when_true("Explicitly time-sensitive")
33                    .when_false("No time pressure"),
34            },
35        )
36        .await?;
37
38    println!("urgent noul = {:?}", response.noul("urgent"));
39    println!("request id  = {:?}", response.meta.request_id);
40    Ok(())
41}
More examples
Hide additional examples
examples/triage.rs (lines 26-41)
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13    let mock = MockServer::start().await;
14    mock.on_system_one().respond(json!({
15        "urgent": noul(0.97),
16        "team": choice("technical", 0.82),
17        "frustration": score(1.6, 0.78),
18    }));
19
20    let client = ClientConfig::new()
21        .api_key("test")
22        .base_url(mock.url())
23        .build()?;
24
25    let response = client
26        .system_one(
27            "Help! My payouts have been failing for 3 days.",
28            questions! {
29                "urgent" => Question::noul("Does this convey urgency?")
30                    .when_true("Explicitly time-sensitive")
31                    .when_false("No time pressure"),
32                "team" => Question::choice("Which team should handle this?")
33                    .option("billing", "Payments, invoicing, refunds")
34                    .option("technical", "Bugs, outages, integrations")
35                    .option("sales", "Pricing, upgrades, new accounts"),
36                "frustration" => Question::score("How frustrated is the customer?")
37                    .level("Calm")
38                    .level("Frustrated")
39                    .level("Very angry"),
40            },
41        )
42        .await?;
43
44    println!("urgent      = {:?}", response.noul("urgent"));
45    println!(
46        "team        = {:?}",
47        response.choice("team").map(|c| c.choice)
48    );
49    println!(
50        "frustration = {:?}",
51        response.score("frustration").map(|s| s.score)
52    );
53    Ok(())
54}
Source

pub async fn system_one_with( &self, req: &SystemOneRequest, opts: CallOptions, ) -> Result<SystemOneResponse, Error>

Evaluate a fully specified request with per-call options.

Source

pub fn models(&self) -> Models<'_>

Access the Models resource.

Examples found in repository?
examples/models.rs (line 28)
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13    let mock = MockServer::start().await;
14    mock.on_models().respond(json!({
15        "models": [{
16            "name": "jev-latest",
17            "description": "TypeSafe flagship",
18            "release_date": "2026-01-01"
19        }]
20    }));
21
22    let client = ClientConfig::new()
23        .api_key("test")
24        .base_url(mock.url())
25        .build()?;
26
27    client.warm_up().await?;
28    for model in client.models().list().await? {
29        println!("{} — {}", model.name, model.description);
30    }
31    Ok(())
32}
Source

pub async fn warm_up(&self) -> Result<(), Error>

Establish a pooled connection by calling GET /v1/models.

Examples found in repository?
examples/models.rs (line 27)
12async fn main() -> Result<(), Box<dyn std::error::Error>> {
13    let mock = MockServer::start().await;
14    mock.on_models().respond(json!({
15        "models": [{
16            "name": "jev-latest",
17            "description": "TypeSafe flagship",
18            "release_date": "2026-01-01"
19        }]
20    }));
21
22    let client = ClientConfig::new()
23        .api_key("test")
24        .base_url(mock.url())
25        .build()?;
26
27    client.warm_up().await?;
28    for model in client.models().list().await? {
29        println!("{} — {}", model.name, model.description);
30    }
31    Ok(())
32}

Trait Implementations§

Source§

impl Backend for Client

Source§

fn name(&self) -> &str

Stable backend name, e.g. "typesafe".
Source§

fn system_one( &self, req: &SystemOneRequest, opts: &CallOptions, ) -> impl Future<Output = Result<SystemOneResponse, Error>> + Send

Evaluate req with per-call options.
Source§

impl Clone for Client

Source§

fn clone(&self) -> Client

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more