@@ -22,6 +22,7 @@ import io.cequence.openaiscala.anthropic.domain.response.{
22
22
import io .cequence .openaiscala .anthropic .domain .{CacheControl , ChatRole , Content , Message }
23
23
import io .cequence .wsclient .JsonUtil
24
24
import play .api .libs .functional .syntax ._
25
+ import play .api .libs .json .JsonNaming .SnakeCase
25
26
import play .api .libs .json ._
26
27
27
28
object JsonFormats extends JsonFormats
@@ -45,9 +46,15 @@ trait JsonFormats {
45
46
implicit lazy val contentBlocksFormat : Format [ContentBlocks ] = Json .format[ContentBlocks ]
46
47
47
48
// implicit lazy val textBlockWrites: Writes[TextBlock] = Json.writes[TextBlock]
48
- implicit lazy val textBlockReads : Reads [TextBlock ] = Json .reads[TextBlock ]
49
+ implicit lazy val textBlockReads : Reads [TextBlock ] = {
50
+ implicit val config : JsonConfiguration = JsonConfiguration (SnakeCase )
51
+ Json .reads[TextBlock ]
52
+ }
49
53
50
- implicit lazy val textBlockWrites : Writes [TextBlock ] = Json .writes[TextBlock ]
54
+ implicit lazy val textBlockWrites : Writes [TextBlock ] = {
55
+ implicit val config : JsonConfiguration = JsonConfiguration (SnakeCase )
56
+ Json .writes[TextBlock ]
57
+ }
51
58
implicit lazy val imageBlockWrites : Writes [ImageBlock ] =
52
59
(block : ImageBlock ) =>
53
60
Json .obj(
@@ -105,43 +112,57 @@ trait JsonFormats {
105
112
}
106
113
}
107
114
108
- // implicit lazy val baseMessageWrites: Writes[Message] = new Writes[Message] {
109
- // def writes(message: Message): JsValue = message match {
110
- // case UserMessage(content) => Json.obj("role" -> "user", "content" -> content)
111
- // case UserMessageContent(content) =>
112
- // Json.obj(
113
- // "role" -> "user",
114
- // "content" -> content.map(Json.toJson(_)(contentBlockWrites))
115
- // )
116
- // case AssistantMessage(content) => Json.obj("role" -> "assistant", "content" -> content)
117
- // case AssistantMessageContent(content) =>
118
- // Json.obj(
119
- // "role" -> "assistant",
120
- // "content" -> content.map(Json.toJson(_)(contentBlockWrites))
121
- // )
122
- // // Add cases for other subclasses if necessary
123
- // }
124
- // }
115
+ implicit lazy val baseMessageWrites : Writes [Message ] = new Writes [Message ] {
116
+ def writes (message : Message ): JsValue = message match {
117
+ case UserMessage (content, cacheControl) =>
118
+ val baseObj = Json .obj(" role" -> " user" , " content" -> content)
119
+ cacheControl.fold(baseObj)(cc => baseObj + (" cache_control" -> Json .toJson(cc)))
120
+
121
+ case UserMessageContent (content) =>
122
+ Json .obj(
123
+ " role" -> " user" ,
124
+ " content" -> content.map(Json .toJson(_)(contentBlockWrites))
125
+ )
126
+
127
+ case AssistantMessage (content, cacheControl) =>
128
+ val baseObj = Json .obj(" role" -> " assistant" , " content" -> content)
129
+ cacheControl.fold(baseObj)(cc => baseObj + (" cache_control" -> Json .toJson(cc)))
130
+
131
+ case AssistantMessageContent (content) =>
132
+ Json .obj(
133
+ " role" -> " assistant" ,
134
+ " content" -> content.map(Json .toJson(_)(contentBlockWrites))
135
+ )
136
+ // Add cases for other subclasses if necessary
137
+ }
138
+ }
125
139
126
140
implicit lazy val baseMessageReads : Reads [Message ] = (
127
141
(__ \ " role" ).read[String ] and
128
142
(__ \ " content" ).read[JsValue ] and
129
143
(__ \ " cache_control" ).readNullable[CacheControl ]
130
144
).tupled.flatMap {
131
145
case (" user" , JsString (str), cacheControl) => Reads .pure(UserMessage (str, cacheControl))
132
- case (" user" , json @ JsArray (_), cacheControl) => {
133
- val contentBlocks = Json .fromJson[Seq [ContentBlock ]](json).map(ContentBlocks (_))
134
-
146
+ case (" user" , json @ JsArray (_), _) => {
147
+ Json .fromJson[Seq [ContentBlock ]](json) match {
148
+ case JsSuccess (contentBlocks, _) =>
149
+ Reads .pure(UserMessageContent (contentBlocks))
150
+ case JsError (errors) =>
151
+ Reads (_ => JsError (errors))
152
+ }
135
153
}
136
-
137
- // case ("user", SingleString(text), None) => Reads.pure(UserMessage(text))
138
- // case ("user", SingleString(text), Some(cacheControl)) => Reads.pure(UserMessage(text))
139
- // case ("user", ContentBlocks(blocks), None) => Reads.pure(UserMessageContent(blocks))
140
- // case ("user", ContentBlocks(blocks), Some(cacheControl)) =>
141
- // Reads.pure(UserMessageContent(blocks))
142
- // case ("assistant", SingleString(text)) => Reads.pure(AssistantMessage(text))
143
- // case ("assistant", ContentBlocks(blocks)) => Reads.pure(AssistantMessageContent(blocks))
144
- // case _ => Reads(_ => JsError("Unsupported role or content type"))
154
+ case (" assistant" , JsString (str), cacheControl) =>
155
+ Reads .pure(AssistantMessage (str, cacheControl))
156
+
157
+ case (" assistant" , json @ JsArray (_), _) => {
158
+ Json .fromJson[Seq [ContentBlock ]](json) match {
159
+ case JsSuccess (contentBlocks, _) =>
160
+ Reads .pure(AssistantMessageContent (contentBlocks))
161
+ case JsError (errors) =>
162
+ Reads (_ => JsError (errors))
163
+ }
164
+ }
165
+ case _ => Reads (_ => JsError (" Unsupported role or content type" ))
145
166
}
146
167
147
168
implicit lazy val createMessageResponseReads : Reads [CreateMessageResponse ] = (
0 commit comments