All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sttp.openai.requests.completions.chat.message.Content.scala Maven / Gradle / Ivy

package sttp.openai.requests.completions.chat.message

import sttp.openai.OpenAIExceptions.OpenAIException.DeserializationOpenAIException
import sttp.openai.json.SnakePickle
import ujson._

sealed trait Content

object Content {
  case class TextContent(value: String) extends Content
  case class ArrayContent(value: Seq[ContentPart]) extends Content

  implicit val contentRW: SnakePickle.ReadWriter[Content] = SnakePickle
    .readwriter[Value]
    .bimap[Content](
      {
        case TextContent(value)  => SnakePickle.writeJs(value)
        case ArrayContent(value) => SnakePickle.writeJs(value)
      },
      jsonValue =>
        SnakePickle.read[Value](jsonValue) match {
          case Str(value) => TextContent(value)
          case Arr(value) => ArrayContent(value.toSeq.map(SnakePickle.read[ContentPart](_)))
          case e          => throw DeserializationOpenAIException(new Exception(s"Could not deserialize: $e"))
        }
    )

  sealed trait ContentPart
  case class TextContentPart(text: String) extends ContentPart
  case class ImageContentPart(imageUrl: ImageUrl) extends ContentPart

  implicit val textContentPartRW: SnakePickle.ReadWriter[TextContentPart] =
    SnakePickle
      .readwriter[Value]
      .bimap[TextContentPart](
        textPart => Obj("type" -> "text", "text" -> textPart.text),
        json => TextContentPart(json("text").str)
      )

  implicit val imageContentPartRW: SnakePickle.ReadWriter[ImageContentPart] =
    SnakePickle
      .readwriter[Value]
      .bimap[ImageContentPart](
        imagePart => Obj("type" -> "image_url", "image_url" -> SnakePickle.writeJs(imagePart.imageUrl)),
        json => ImageContentPart(SnakePickle.read[ImageUrl](json("image_url")))
      )

  implicit val contentPartRW: SnakePickle.ReadWriter[ContentPart] =
    SnakePickle
      .readwriter[Value]
      .bimap[ContentPart](
        {
          case textPart: TextContentPart   => SnakePickle.writeJs(textPart)
          case imagePart: ImageContentPart => SnakePickle.writeJs(imagePart)
        },
        json =>
          json("type").str match {
            case "text"      => SnakePickle.read[TextContentPart](json)
            case "image_url" => SnakePickle.read[ImageContentPart](json)
          }
      )

  case class ImageUrl(url: String, detail: Option[String] = None)

  implicit val imageUrlRW: SnakePickle.ReadWriter[ImageUrl] = SnakePickle.macroRW[ImageUrl]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy