zio / zio-http

A next-generation Scala framework for building scalable, correct, and efficient HTTP clients and servers
https://zio.dev/zio-http
Apache License 2.0
800 stars 403 forks source link

Make `JsonSchema.fromSerializableSchema` package private #3170

Closed guersam closed 1 month ago

guersam commented 1 month ago

While working with OpenAI structured outputs, I need an uncommon requirement like omitting format field from the schema.

To overcome such technical constraint, I need an escape hatch between JsonSchema and SerializableJsonSchema for a workaround like the below:

package zio.http.endpoint.openapi

import zio.prelude.Newtype
import zio.schema.Schema

object OpenAIJsonSchema extends Newtype[JsonSchema] {

  given Schema[Type] =
    SerializableJsonSchema.schema.transform[Type](
      ss => wrap(JsonSchema.fromSerializableSchema(ss)), // `JsonSchema.fromSerializableSchema` is inaccessible
      s => {
        val ss = unwrap(s).toSerializableSchema
        println(s)
        println(unwrap(s).toJson)
        adjustForOpenAI(ss)
      }
    )

  def fromZSchema(s: Schema[?]): Type =
    wrap(JsonSchema.fromZSchema(s, JsonSchema.SchemaStyle.Inline))

  private def adjustForOpenAI(s: SerializableJsonSchema): SerializableJsonSchema =
    s.copy(
      format = None,
      properties = s.properties.map(_.view.mapValues(adjustForOpenAI).toMap),
      items = s.items.map(adjustForOpenAI),
      additionalProperties =
        Option.when(s.properties.nonEmpty) {
          BoolOrSchema.BooleanWrapper(false)
        }
    )
}
type OpenAIJsonSchema = OpenAIJsonSchema.Type
guersam commented 1 month ago

Failed test:

    - AuthSpec - With server - Auth from query parameter with context and endpoint client
      Exception in thread "zio-fiber-174869" zio.http.codec.HttpCodecError$MalformedStatus: Expected status code BadRequest but found NotFound
        at zio.http.endpoint.AuthSpec.spec.response(AuthSpec.scala:204)
        at zio.http.endpoint.AuthSpec.spec.response(AuthSpec.scala:205)
        at zio.http.endpoint.AuthSpec.spec(AuthSpec.scala:213)
        at zio.http.endpoint.AuthSpec.spec(AuthSpec.scala:214)

This spec is failing consistently on the current main branch since last week. Maybe there's a race among the parallel cases on http://localhost:8080?