///|
/// A request to the `/moderations` endpoint.
pub(all) struct ModerationRequest {
input : EmbeddingInput
mut model : String?
}
///|
/// Create a moderation request for a single text.
pub fn ModerationRequest::of_text(text : String) -> ModerationRequest {
{ input: Single(text), model: None }
}
///|
/// Create a moderation request for a batch of texts.
pub fn ModerationRequest::of_batch(texts : Array[String]) -> ModerationRequest {
{ input: Batch(texts), model: None }
}
///|
/// Set the moderation model explicitly.
pub fn ModerationRequest::model(
self : ModerationRequest,
m : String,
) -> ModerationRequest {
self.model = Some(m)
self
}
///|
pub impl ToJson for ModerationRequest with fn to_json(self : ModerationRequest) -> Json {
let obj : Map[String, Json] = { "input": self.input.to_json() }
if self.model is Some(m) {
obj["model"] = Json::string(m)
}
Json::object(obj)
}
///|
/// A single moderation result: whether the input was flagged, and which
/// categories were triggered.
pub(all) struct ModerationResult {
flagged : Bool
categories : Map[String, Bool]
category_scores : Map[String, Double]
} derive(Debug)
///|
pub impl @json.FromJson for ModerationResult with fn from_json(
json : Json,
path : @json.JsonPath,
) -> ModerationResult {
guard json is Object(obj) else {
raise @json.JsonDecodeError((path, "ModerationResult: expected object"))
}
let flagged = match obj.get("flagged") {
Some(True) => true
_ => false
}
let categories = {}
match obj.get("categories") {
Some(Object(cats)) =>
for k, v in cats {
match v {
True => categories[k] = true
False => categories[k] = false
_ => ()
}
}
_ => ()
}
let category_scores = {}
match obj.get("category_scores") {
Some(Object(scores)) =>
for k, v in scores {
match v {
Number(n, ..) => category_scores[k] = n
_ => ()
}
}
_ => ()
}
{ flagged, categories, category_scores }
}
///|
/// The categories that were flagged, in no particular order.
pub fn ModerationResult::flagged_categories(
self : ModerationResult,
) -> Array[String] {
let out = []
for k, v in self.categories {
if v {
out.push(k)
}
}
out
}
///|
/// The response from the `/moderations` endpoint.
pub(all) struct ModerationResponse {
model : String
results : Array[ModerationResult]
} derive(Debug)
///|
pub impl @json.FromJson for ModerationResponse with fn from_json(
json : Json,
path : @json.JsonPath,
) -> ModerationResponse {
guard json is Object(obj) else {
raise @json.JsonDecodeError((path, "ModerationResponse: expected object"))
}
let model = match obj.get("model") {
Some(String(s)) => s
_ => ""
}
let results = match obj.get("results") {
Some(Array(_) as r) => @json.from_json(r)
_ => []
}
{ model, results }
}
///|
/// Whether any input in the batch was flagged.
pub fn ModerationResponse::any_flagged(self : ModerationResponse) -> Bool {
for r in self.results {
if r.flagged {
return true
}
}
false
}
///|
/// Perform a moderation request.
pub async fn Client::moderations(
self : Client,
request : ModerationRequest,
) -> ModerationResponse raise LLMError {
let json = self.post_json("/moderations", request.to_json())
@json.from_json(json) catch {
err => raise Decode(err.to_string())
}
}