Client for the TypeSafe System One API and its Jev models.
Runs on the JVM and on babashka.
(require '[cljev.core :as jev])
(def client (jev/client)) ; reads TYPESAFE_API_KEY
(jev/ask client "I was charged twice this month. Please refund the extra charge." {:billing (jev/noul "Is this message about billing?") :tone (jev/choice "What is the tone?" [:angry :calm :excited])}) ;; => {:model "jev-1.14.0" ;; :answers {:billing {:type :noul :noul 0.98} ;; :tone {:type :choice :choice :calm :confidence 0.7 ;; :probabilities {:angry 0.15 :calm 0.8 :excited 0.05}}} ;; :usage {:input-tokens 120 :output-tokens 12}}
Client for the TypeSafe System One API and its Jev models.
Runs on the JVM and on babashka.
(require '[cljev.core :as jev])
(def client (jev/client)) ; reads TYPESAFE_API_KEY
(jev/ask client
"I was charged twice this month. Please refund the extra charge."
{:billing (jev/noul "Is this message about billing?")
:tone (jev/choice "What is the tone?" [:angry :calm :excited])})
;; => {:model "jev-1.14.0"
;; :answers {:billing {:type :noul :noul 0.98}
;; :tone {:type :choice :choice :calm :confidence 0.7
;; :probabilities {:angry 0.15 :calm 0.8 :excited 0.05}}}
;; :usage {:input-tokens 120 :output-tokens 12}}(ask client state questions)(ask client
state
questions
{:keys [model assets upload images? long-context? extra-body timeout-ms
headers]})Ask questions about state in one request.
state is a string, a map, or a sequential collection. questions is a map
of a name you choose to a question (see noul, choice, score, box).
Returns {:model .. :answers .. :usage ..}. :answers is keyed by the
names in questions, as you gave them. Each answer has a :type and:
:noul :noul, the probability of yes :choice :choice, :confidence, :probabilities keyed by option name :score :score, :confidence, :legend and :probabilities keyed by level :box :box with :top :bottom :left :right, and :confidence
The result's metadata has :request-id and :response, the HTTP status,
headers, and JSON body as received.
Options:
:model Model for this request. Default: the client's model.
:assets Images referenced from strings: a collection of images
(see image), or a map of reference string to image or
to a raw asset map.
:upload How image bytes are sent: :multipart (the default) or
:base64, which puts them in the JSON body.
:images? Send TypeSafe-Danger-Zone-Images: true. Required for
images and box questions.
:long-context? Send TypeSafe-Danger-Zone-Long-Context: true.
:extra-body Map of extra top-level request fields, for API features
this client has no option for.
:timeout-ms Timeout for this request.
:headers Extra headers for this request.
Throws an ex-info whose :type is :cljev.core/api-error (with :status,
:detail, :body, :request-id) for a non-2xx reply, or
:cljev.core/connection-error when the server could not be reached.
See verdict and sample for acting on an answer.
Ask `questions` about `state` in one request.
`state` is a string, a map, or a sequential collection. `questions` is a map
of a name you choose to a question (see `noul`, `choice`, `score`, `box`).
Returns `{:model .. :answers .. :usage ..}`. `:answers` is keyed by the
names in `questions`, as you gave them. Each answer has a `:type` and:
:noul :noul, the probability of yes
:choice :choice, :confidence, :probabilities keyed by option name
:score :score, :confidence, :legend and :probabilities keyed by level
:box :box with :top :bottom :left :right, and :confidence
The result's metadata has `:request-id` and `:response`, the HTTP status,
headers, and JSON body as received.
Options:
:model Model for this request. Default: the client's model.
:assets Images referenced from strings: a collection of images
(see `image`), or a map of reference string to image or
to a raw asset map.
:upload How image bytes are sent: :multipart (the default) or
:base64, which puts them in the JSON body.
:images? Send `TypeSafe-Danger-Zone-Images: true`. Required for
images and box questions.
:long-context? Send `TypeSafe-Danger-Zone-Long-Context: true`.
:extra-body Map of extra top-level request fields, for API features
this client has no option for.
:timeout-ms Timeout for this request.
:headers Extra headers for this request.
Throws an ex-info whose `:type` is `:cljev.core/api-error` (with `:status`,
`:detail`, `:body`, `:request-id`) for a non-2xx reply, or
`:cljev.core/connection-error` when the server could not be reached.
See `verdict` and `sample` for acting on an answer.(ask-many client states questions)(ask-many client states questions opts)Ask the same questions about each of states, one request per state,
several at a time. Returns a vector of results in the order of states.
A state whose request fails does not stop the others: its result is
{:error e}, where e is the exception ask threw.
Takes the options of ask, plus:
:concurrency Requests in flight at once. Default 8.
Ask the same `questions` about each of `states`, one request per state,
several at a time. Returns a vector of results in the order of `states`.
A state whose request fails does not stop the others: its result is
`{:error e}`, where `e` is the exception `ask` threw.
Takes the options of `ask`, plus:
:concurrency Requests in flight at once. Default 8.(ask-one client state question)(ask-one client state question opts)Ask a single question about state and return its answer. Takes the same
options as ask. The answer's metadata has the :model, :usage, and
:request-id.
Ask a single `question` about `state` and return its answer. Takes the same options as `ask`. The answer's metadata has the `:model`, `:usage`, and `:request-id`.
(box instructions)A question that locates what instructions describe in the request's
image. Needs a model with Box support and :images? true on the request.
A question that locates what `instructions` describe in the request's image. Needs a model with Box support and `:images? true` on the request.
(choice instructions options)A question that selects one option.
options is one of:
Names may be keywords or strings; the answer uses the names as you gave them. A collection may mix bare names and pairs.
Options are sent in the order given, and the order can affect the answer: Jev can lean toward the first option. A collection keeps its order for any number of options. A Clojure map only keeps its order up to 8 entries, so pass a collection of pairs for a larger set with descriptions.
A question that selects one option.
`options` is one of:
- a collection of option names: [:angry :calm]
- a collection of [name description]: [[:angry "Hostile"] [:calm "Neutral"]]
- a map of name to description: {:angry "Hostile" :calm "Neutral"}
Names may be keywords or strings; the answer uses the names as you gave
them. A collection may mix bare names and pairs.
Options are sent in the order given, and the order can affect the answer:
Jev can lean toward the first option. A collection keeps its order for any
number of options. A Clojure map only keeps its order up to 8 entries, so
pass a collection of pairs for a larger set with descriptions.(client)(client {:keys [api-key base-url model timeout-ms retry headers http-client
request-fn sleep-fn systemone-path models-path]
:as opts})Create a client. All options are optional:
:api-key API key. Default: the TYPESAFE_API_KEY environment variable.
Surrounding whitespace is removed.
:base-url Default: TYPESAFE_BASE_URL, then https://api.typesafe.ai.
Point it at another server that implements the System One
API; see below.
:model Default model for ask. Default: TYPESAFE_DEFAULT_MODEL,
then "jev-latest". An alias such as jev-latest moves when a
release ships; pass a versioned id such as "jev-1.14.0" to
pin.
:timeout-ms Timeout for connecting and for each request. Default 10000.
:retry Map merged over default-retry. {:max-retries 0} turns
retries off.
:compression :gzip compresses request bodies of 1 KiB or more; nil or
false sends every body uncompressed. Default: :gzip for
the TypeSafe API, nil for another :base-url.
:systemone-path Path of the System One endpoint. Default /v1/systemone.
:models-path Path of the models endpoint. Default /v1/models.
:headers Extra headers sent with every request.
:http-client A babashka.http-client client to use instead of a new one.
:request-fn Replacement for babashka.http-client/request. For tests.
:sleep-fn Function of milliseconds used to wait between retries.
Another backend: a :base-url other than TypeSafe's needs no API key, and
without one no authorization header is sent. TYPESAFE_API_KEY is not used
for a :base-url given here, so the TypeSafe key is never sent to another
server; pass that server's key as :api-key if it needs one.
The client is a plain map. The API key is kept in its metadata so that printing the client does not print the key.
Create a client. All options are optional:
:api-key API key. Default: the TYPESAFE_API_KEY environment variable.
Surrounding whitespace is removed.
:base-url Default: TYPESAFE_BASE_URL, then https://api.typesafe.ai.
Point it at another server that implements the System One
API; see below.
:model Default model for `ask`. Default: TYPESAFE_DEFAULT_MODEL,
then "jev-latest". An alias such as jev-latest moves when a
release ships; pass a versioned id such as "jev-1.14.0" to
pin.
:timeout-ms Timeout for connecting and for each request. Default 10000.
:retry Map merged over `default-retry`. `{:max-retries 0}` turns
retries off.
:compression :gzip compresses request bodies of 1 KiB or more; nil or
false sends every body uncompressed. Default: :gzip for
the TypeSafe API, nil for another :base-url.
:systemone-path Path of the System One endpoint. Default /v1/systemone.
:models-path Path of the models endpoint. Default /v1/models.
:headers Extra headers sent with every request.
:http-client A babashka.http-client client to use instead of a new one.
:request-fn Replacement for `babashka.http-client/request`. For tests.
:sleep-fn Function of milliseconds used to wait between retries.
Another backend: a `:base-url` other than TypeSafe's needs no API key, and
without one no authorization header is sent. TYPESAFE_API_KEY is not used
for a `:base-url` given here, so the TypeSafe key is never sent to another
server; pass that server's key as `:api-key` if it needs one.
The client is a plain map. The API key is kept in its metadata so that
printing the client does not print the key.Request bodies of at least this many bytes are compressed.
Request bodies of at least this many bytes are compressed.
Default retry policy. Delays are in milliseconds.
:max-retries Retries after the first attempt. :backoff-initial-ms First delay; doubled on each retry. :backoff-max-ms Upper bound on the backoff delay. :backoff-jitter Fraction of each delay that may be randomly subtracted. :max-retry-after-ms Longest delay a retry-after header may ask for. A reply that asks for more is not retried.
Default retry policy. Delays are in milliseconds.
:max-retries Retries after the first attempt.
:backoff-initial-ms First delay; doubled on each retry.
:backoff-max-ms Upper bound on the backoff delay.
:backoff-jitter Fraction of each delay that may be randomly subtracted.
:max-retry-after-ms Longest delay a retry-after header may ask for. A
reply that asks for more is not retried.(image src)(image src fmt)An image to send with a request.
src is a byte array, a file, or a path. fmt is "png", "jpg", or
"jpeg"; it is taken from the file extension when omitted.
Put the image anywhere a value goes in the state or in a question's instructions or criteria:
(jev/ask client {:photo (jev/image "cat.png")} questions {:images? true})
To use it inside a string, write its :ref into the string and pass the
image in the :assets option:
(let [img (jev/image "cat.png")] (jev/ask client (str "The photo: " (:ref img)) questions {:assets [img] :images? true}))
Each image gets a unique :ref when it is created. Using one image in
several places uploads it once.
An image to send with a request.
`src` is a byte array, a file, or a path. `fmt` is "png", "jpg", or
"jpeg"; it is taken from the file extension when omitted.
Put the image anywhere a value goes in the state or in a question's
instructions or criteria:
(jev/ask client {:photo (jev/image "cat.png")} questions {:images? true})
To use it inside a string, write its `:ref` into the string and pass the
image in the `:assets` option:
(let [img (jev/image "cat.png")]
(jev/ask client (str "The photo: " (:ref img)) questions
{:assets [img] :images? true}))
Each image gets a unique `:ref` when it is created. Using one image in
several places uploads it once.(models client)List the models and aliases available to the account, as a vector of
{:name .. :description .. :release-date ..}. The vector's metadata has
:request-id and :response.
A server that lists models in the OpenAI shape, under data with an id,
is read too: each entry gets its :name from its id.
List the models and aliases available to the account, as a vector of
`{:name .. :description .. :release-date ..}`. The vector's metadata has
`:request-id` and `:response`.
A server that lists models in the OpenAI shape, under `data` with an `id`,
is read too: each entry gets its `:name` from its `id`.(noul instructions)(noul instructions criteria)A yes/no question. The answer is the probability that the answer is yes.
criteria is optional: a map with :true and/or :false describing what
counts as yes and as no.
A yes/no question. The answer is the probability that the answer is yes. `criteria` is optional: a map with `:true` and/or `:false` describing what counts as yes and as no.
(sample answer)(sample answer roll)Pick an option of a choice answer, or a level of a score answer, at random
in proportion to its probability, where :choice always gives the
likeliest one. An option with probability zero is never picked.
roll is a number from 0 to 1 and defaults to (rand); pass your own for
a draw you can reproduce.
Pick an option of a choice answer, or a level of a score answer, at random in proportion to its probability, where `:choice` always gives the likeliest one. An option with probability zero is never picked. `roll` is a number from 0 to 1 and defaults to `(rand)`; pass your own for a draw you can reproduce.
(score instructions levels)A question that rates content against ordered levels.
levels is a sequential collection of level descriptions, lowest first. A
level's position is its score, starting at zero.
A question that rates content against ordered levels. `levels` is a sequential collection of level descriptions, lowest first. A level's position is its score, starting at zero.
(verdict answer)(verdict answer threshold)Read a yes/no answer as :yes, :no, or :unsure.
answer is a noul answer or a probability of yes. threshold, from 0.5
to 1, is how sure the answer must be either way: :yes when the
probability of yes is at least threshold, :no when the probability of
no is, and :unsure in between. The default, 0.5, is never unsure.
(jev/verdict {:type :noul :noul 0.93} 0.8) ;; => :yes (jev/verdict {:type :noul :noul 0.60} 0.8) ;; => :unsure (jev/verdict {:type :noul :noul 0.10} 0.8) ;; => :no
Read a yes/no answer as `:yes`, `:no`, or `:unsure`.
`answer` is a noul answer or a probability of yes. `threshold`, from 0.5
to 1, is how sure the answer must be either way: `:yes` when the
probability of yes is at least `threshold`, `:no` when the probability of
no is, and `:unsure` in between. The default, 0.5, is never unsure.
(jev/verdict {:type :noul :noul 0.93} 0.8) ;; => :yes
(jev/verdict {:type :noul :noul 0.60} 0.8) ;; => :unsure
(jev/verdict {:type :noul :noul 0.10} 0.8) ;; => :noThe version of this library, sent in the user-agent header.
The version of this library, sent in the user-agent header.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |