Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TypeSafe AI System One Rust Client Library (unofficial)

By the same author of the genai crate (Jeremy Chone).

  • Very early release 0.0.x
  • Extremely basic functionality / API surface for now
  • Feel free to cherry pick what you need for now.

Part of the zcoder.run Rust libraries, and will probably be used in the zcoder harness (still in the building).

Usage

use serde_json::json;
use sysone::{Client, Question, Request};

// Set TYPESAFE_API_KEY in the environment or configure it on the builder:
// Client::builder().with_api_key("...").build()?;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::default();

    let req = Request::from_state(json!({ "code": "fn main() {}" }))
        .append_question("intent", Question::noul("What does this code do?"))
        .append_question(0, Question::choice("Classify code status")
            .append_criteria("ok", "Working code")
            .append_criteria("fix", "Needs fixes"));

    let res = client.exec(req).await?;

    println!("Model: {}", res.model);
    println!("Tokens: {} in / {} out", res.input_tokens, res.output_tokens);
    if let Some(cost) = res.cost {
        println!("Cost: ${cost:.6}");
    }

    if let Some(answer) = res.answer("intent") {
        println!("Intent answer: {answer:?}");
    }

    Ok(())
}

Request

Request follows the fluid API style, state accepts impl Into<serde_json::Value>, and questions accept impl Into<Question> keyed by impl Into<QKey>.

Constructors:

  • Request::from_state(state): state only, no questions yet (Request::new is an alias of it).
  • Request::from_state_questions(state, questions): state and questions at once.
use serde_json::json;
use sysone::{ChoiceQuestion, NoulQuestion, Question, Request, ScoreQuestion};

// Replace the full question set with key-question pairs
let req = Request::from_state("current state")
    .with_questions([
        ("intent", Question::noul("What does this code do?")),
    ]);

// Or build it up one question at a time using named or indexed keys
let req = Request::default()
    .with_state(json!({ "step": 1 }))
    .append_question("intent", Question::noul("Does it compile?"))
    .append_question(0, ChoiceQuestion::new("Pick department")
        .append_criteria("billing", "Billing questions")
        .append_criteria("support", "Technical questions"))
    .extend_questions([
        (1, ScoreQuestion::new("Rate severity").append_level("Low").append_level("High").into()),
        ("summary", Question::noul("Does it need review?")),
    ]);

Typed Questions

The Question enum and dedicated primitive structs provide typed construction and criteria builders:

  • Question::noul(...) / NoulQuestion: binary condition verification with optional .with_true(...), .with_false(...), or .with_true_false(...).
  • Question::choice(...) / ChoiceQuestion: option selection with .append_criteria(key, criterion) or .extend_criteria(...).
  • Question::score(...) / ScoreQuestion: ordinal levels with .append_level(criterion), .extend_levels(...), or criteria map.

Raw serde_json::Value questions are also accepted via From<Value> for Question.

Question Keys (QKey)

Questions can be keyed either by name or by index:

  • QKey::Name("intent".to_string()): wire key "intent".
  • QKey::Idx(0): wire key "q0".

append_question and extend_questions accept impl Into<QKey>, so &str, String, and usize work directly.

Response

Client::exec returns a typed Response:

  • res.model: model identifier used for the call.
  • res.input_tokens: input tokens consumed.
  • res.output_tokens: output tokens consumed.
  • res.cost: client-computed cost in USD (Some(f64) for supported models, None otherwise).
  • res.answers: vector of (QKey, Answer) pairs.
  • res.answer(key): lookup helper accepting impl Into<QKey> (&str, String, or usize).

Typed Answers

The Answer enum provides typed access to the three response kinds:

  • Answer::Noul(NoulAnswer): contains noul: f64.
  • Answer::Choice(ChoiceAnswer): contains choice: String, confidence: f64, and probabilities: HashMap<String, f64>.
  • Answer::Score(ScoreAnswer): contains score: f64, confidence: f64, probabilities: HashMap<String, f64>, and legend: HashMap<String, String>.

Pricing

Client-side token pricing is available via sysone::pricer:

  • Fixed rate of 0.042 USD per one million tokens (PRICE_PER_MILLION_TOKENS).
  • Applied to models starting with jev (such as jev-latest).
  • Other models return None for pricing and cost.
  • Cost is computed client-side from the input tokens via pricer::cost(model, input_tokens).

License

Licensed under either of:

at your option.

Copyright (c) 2026 BriteSnow, Inc., https://britesnow.com

About

System One TypeSafe AI Rust Client (unofficial)

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages