typesafe-jev
A Rust client for TypeSafe's System One API and its Jev model.
Jev does not generate text. You send a JSON state and a map of typed questions about it, and
get back one calibrated answer per question. Every question in a request is evaluated against
the same state in parallel, so a request with hundreds of questions takes about as long as one
with a single question.
This crate is the client that jevgrep (jg,
natural-language code search) uses for its default backend, extracted so that it can be used on
its own. It has no async runtime and two dependencies: serde_json for the JSON, and ureq with
rustls for the HTTPS. It is an independent client, not an official TypeSafe SDK.
Usage
[]
= "0.1"
= "1"
use ;
use ;
Client::new(api_key, config) takes the key directly. Config sets the endpoint (a gateway in
front of TypeSafe works too), the model, the timeouts, the retry budget and the connection pool:
use Duration;
use ;
examples/ask.rs is a complete program: TYPESAFE_API_KEY=... cargo run --example ask.
Questions and answers
noulasks a yes/no question. The answer is{"type": "noul", "noul": p}, withpthe probability in [0, 1] that the answer is yes.scoreasks for a judgment on an ordered scale. The question lists itscriteria, one per level, in order; the answer is{"type": "score", "score": s, "confidence": c, "probabilities": {...}, "legend": {...}}, withsa position on that scale counted from the first criterion.
The probabilities are calibrated: a noul of 0.9 is right about nine times in ten. The
questions map is sent as given, so any field the API accepts can be used.
Retries, concurrency and cost
- Connection failures and transient HTTP statuses (408, 409, 425, 429, 5xx, 529) are retried
with exponential backoff and jitter, honouring
Retry-After, up toConfig::max_retries. - Rejected credentials are returned at once as
Error::Auth; a request too large for the model's context asError::TokenLimit, which the caller should split and retry. Everything else, including retries exhausted, isError::Api. The enum is#[non_exhaustive]. - Calls block. The client is
Send + Syncand shares one connection pool: callaskfrom as many threads asConfig::pool_size. AnAdaptiveLimitercaps the concurrency and halves it whenever the API throttles, growing it back as requests succeed. TypeSafe's rate limit is a sustained token budget with no quota headers, and the limiter is what keeps several processes on one key from tripping over each other. Usagecounts requests, retries and tokens across threads.Usage::cost_usdprices the input tokens at Jev's list price (USD_PER_INPUT_MTOK); output tokens are free.Client::set_debug_reporterreceives one line per failed attempt. Nothing is logged otherwise.
Testing without the network
Client::with_transport takes any Transport, including a closure from the request body to a
Reply, so tests and local fakes need no server:
use ;
use ;
let client = with_transport;
let mut questions = new;
questions.insert;
assert_eq!;
Security notes
- The key is sent as a bearer token to whatever
Config::base_urlnames, over HTTPS by default. Plainhttp://is accepted, for local fakes; do not point a real key at one. - Error messages quote at most 400 characters of a failed response body. They never quote the
request, the key or the base URL, so the state you sent and your credentials stay out of logs.
Client'sDebugoutput leaves the key out too. - Redirects are followed, but the
Authorizationheader is not sent to the redirect's target. #![forbid(unsafe_code)]; TLS is rustls with the bundled web PKI roots.
Compatibility
- The minimum supported Rust version is 1.85, checked in CI. Raising it is a minor version bump.
serde_jsonis part of the public API (Value,Map);ureqis not. The lowest versions the manifest allows (serde_json1.0.45,ureq3.0.0) pass the test suite.- The crate follows semantic versioning. Before 1.0, a breaking change bumps the minor version; see the changelog.
License
Licensed under either of the Apache License, Version 2.0 or the MIT license, at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.