Vendor

com.softinio.verdict4s.Vendor
See theVendor companion object
trait Vendor

How to speak to one vendor's decision API.

Jev and OpenAI Decisions answer the same three kinds of question with the same kinds of answer, and differ only in how they spell them on the wire. The questions, Ask and the typed answers are therefore shared, and a Vendor is everything that is not: where to send a request, how to encode it, how to read the reply, and which requests the vendor accepts.

A value rather than a typeclass, so that the vendor can be chosen at runtime, from configuration, without a type parameter on every signature.

It is also the way to drive a vendor with no effect system at all. Render a request, send it with whatever HTTP client you already have, and parse the reply back into typed answers:

val vendor = Vendor.OpenAI
val body = vendor.renderAsk(ask, state) // Either[Verdict4sError, String]
val text = myHttpClient.post(
 vendor.evaluateUrl,
 vendor.headers(key),
 body
) // your code
val answers = vendor.parseAsk(ask, text)

Attributes

Companion
object
Graph
Supertypes
class Object
trait Matchable
class Any
Known subtypes
object JevVendor
class OpenAIVendor

Members list

Value members

Abstract methods

Read a successful response body.

Read a successful response body.

Attributes

The service's address. A String because core must not depend on http4s; the client turns it into a Uri.

The service's address. A String because core must not depend on http4s; the client turns it into a Uri.

Attributes

The model used when neither the request nor the client names one.

The model used when neither the request nor the client names one.

Attributes

def encode(request: EvaluationRequest): Json

The request body. Does not validate; see validate.

The request body. Does not validate; see validate.

Attributes

Path segments of the evaluation endpoint, relative to the base URL.

Path segments of the evaluation endpoint, relative to the base URL.

Attributes

def name: String

A human-readable name, for logs and error messages.

A human-readable name, for logs and error messages.

Attributes

Response header carrying the per-request correlation id.

Response header carrying the per-request correlation id.

Attributes

Concrete methods

final def authorization(apiKey: ApiKey): String

The Authorization header value for a key.

The Authorization header value for a key.

Attributes

final def evaluateUrl: String

Where to POST an evaluation, using the default base URL.

Where to POST an evaluation, using the default base URL.

Attributes

final def headers(apiKey: ApiKey): List[(String, String)]

The headers every request needs, as plain pairs.

The headers every request needs, as plain pairs.

Attributes

Parse a successful response body.

Parse a successful response body.

Attributes

final def parseAsk[Q <: Tuple](ask: Ask[Q], body: String): Either[Verdict4sError, Answers[Q]]

Parse a response and project it through the questions that produced it.

Parse a response and project it through the questions that produced it.

Attributes

final def parseError(status: Int, body: String, headers: Map[String, String] = ...): Api

Turn an unsuccessful response into a typed error.

Turn an unsuccessful response into a typed error.

Value parameters

body

the raw body, which need not be JSON

headers

the response headers, for the request id and the retry delay

status

the HTTP status code

Attributes

Validate and encode in one step.

Validate and encode in one step.

Attributes

final def render(request: EvaluationRequest): String

Render a request as the JSON to send. Does not validate; see renderAsk or prepare.

Render a request as the JSON to send. Does not validate; see renderAsk or prepare.

Attributes

final def renderAsk[Q <: Tuple, S : Encoder](ask: Ask[Q], state: S, model: Model = ...): Either[Verdict4sError, String]

Build, validate and render in one step, reporting every problem at once.

Build, validate and render in one step, reporting every problem at once.

Vendor.Jev.renderAsk(Ask(q1, q2), state)

Attributes

final def renderPretty(request: EvaluationRequest): String

Render a request indented, for logs and documentation.

Render a request indented, for logs and documentation.

Attributes

A response header giving the retry delay in milliseconds, consulted before the standard Retry-After.

A response header giving the retry delay in milliseconds, consulted before the standard Retry-After.

Attributes

def retryable(error: Api): Boolean

Whether an error the retry policy would retry is worth retrying.

Whether an error the retry policy would retry is worth retrying.

The policy decides by status alone; this lets a vendor veto a retry that its error body says cannot succeed, such as OpenAI's insufficient_quota 429, which no amount of waiting fixes.

Attributes

Reject requests this vendor cannot serve, such as a feature only the other vendor has, before they cost a round trip. Every problem is reported at once.

Reject requests this vendor cannot serve, such as a feature only the other vendor has, before they cost a round trip. Every problem is reported at once.

Attributes