1
1
package io .cequence .openaiscala .anthropic
2
2
3
3
import io .cequence .openaiscala .anthropic .domain .CacheControl .Ephemeral
4
- import io .cequence .openaiscala .anthropic .domain .Content .ContentBlock .{ImageBlock , TextBlock }
4
+ import io .cequence .openaiscala .anthropic .domain .Content .ContentBlock .{
5
+ DocumentBlock ,
6
+ ImageBlock ,
7
+ TextBlock
8
+ }
5
9
import io .cequence .openaiscala .anthropic .domain .Content .{
6
10
ContentBlock ,
7
11
ContentBlockBase ,
@@ -35,6 +39,30 @@ trait JsonFormats {
35
39
JsonUtil .enumFormat[ChatRole ](ChatRole .allValues: _* )
36
40
implicit lazy val usageInfoFormat : Format [UsageInfo ] = Json .format[UsageInfo ]
37
41
42
+ implicit lazy val cacheControlFormat : Format [CacheControl ] = new Format [CacheControl ] {
43
+ def reads (json : JsValue ): JsResult [CacheControl ] = json match {
44
+ case JsObject (Seq ((" type" , JsString (" ephemeral" )))) => JsSuccess (CacheControl .Ephemeral )
45
+ case _ => JsError (" Invalid cache control" )
46
+ }
47
+
48
+ def writes (cacheControl : CacheControl ): JsValue = cacheControl match {
49
+ case CacheControl .Ephemeral => Json .obj(" type" -> " ephemeral" )
50
+ }
51
+ }
52
+
53
+ implicit lazy val cacheControlOptionFormat : Format [Option [CacheControl ]] =
54
+ new Format [Option [CacheControl ]] {
55
+ def reads (json : JsValue ): JsResult [Option [CacheControl ]] = json match {
56
+ case JsNull => JsSuccess (None )
57
+ case _ => cacheControlFormat.reads(json).map(Some (_))
58
+ }
59
+
60
+ def writes (option : Option [CacheControl ]): JsValue = option match {
61
+ case None => JsNull
62
+ case Some (cacheControl) => cacheControlFormat.writes(cacheControl)
63
+ }
64
+ }
65
+
38
66
implicit lazy val userMessageFormat : Format [UserMessage ] = Json .format[UserMessage ]
39
67
implicit lazy val userMessageContentFormat : Format [UserMessageContent ] =
40
68
Json .format[UserMessageContent ]
@@ -59,25 +87,8 @@ trait JsonFormats {
59
87
implicit val config : JsonConfiguration = JsonConfiguration (SnakeCase )
60
88
Json .writes[TextBlock ]
61
89
}
62
- // implicit lazy val imageBlockWrites: Writes[ImageBlock] =
63
- // (block: ImageBlock) =>
64
- // Json.obj(
65
- // "type" -> "image",
66
- // "source" -> Json.obj(
67
- // "type" -> block.`type`,
68
- // "media_type" -> block.mediaType,
69
- // "data" -> block.data
70
- // )
71
- // )
72
-
73
- implicit lazy val contentBlockWrites : Writes [ContentBlockBase ] = {
74
- case ContentBlockBase (tb : TextBlock , None ) =>
75
- Json .obj(" type" -> " text" ) ++ Json .toJson(tb)(textBlockWrites).as[JsObject ]
76
- case ContentBlockBase (tb : TextBlock , Some (Ephemeral )) =>
77
- Json .obj(" type" -> " text" , " cache_control" -> " ephemeral" ) ++ Json
78
- .toJson(tb)(textBlockWrites)
79
- .as[JsObject ]
80
- case ContentBlockBase (block : ImageBlock , None ) =>
90
+ implicit lazy val imageBlockWrites : Writes [ImageBlock ] =
91
+ (block : ImageBlock ) =>
81
92
Json .obj(
82
93
" type" -> " image" ,
83
94
" source" -> Json .obj(
@@ -86,16 +97,35 @@ trait JsonFormats {
86
97
" data" -> block.data
87
98
)
88
99
)
89
- case ContentBlockBase (block : ImageBlock , Some (Ephemeral )) =>
100
+ implicit lazy val documentBlockWrites : Writes [DocumentBlock ] =
101
+ (block : DocumentBlock ) =>
90
102
Json .obj(
91
- " type" -> " image" ,
92
- " cache_control" -> " ephemeral" ,
103
+ " type" -> " document" ,
93
104
" source" -> Json .obj(
94
105
" type" -> block.`type`,
95
106
" media_type" -> block.mediaType,
96
107
" data" -> block.data
97
108
)
98
109
)
110
+
111
+ private def cacheControlToJsObject (maybeCacheControl : Option [CacheControl ]): JsObject =
112
+ maybeCacheControl.fold(Json .obj())(cc => Json .obj(" cache_control" -> Json .toJson(cc)))
113
+
114
+ implicit lazy val contentBlockWrites : Writes [ContentBlockBase ] = {
115
+ case ContentBlockBase (textBlock @ TextBlock (_), cacheControl) =>
116
+ Json .obj(" type" -> " text" ) ++
117
+ Json .toJson(textBlock)(textBlockWrites).as[JsObject ] ++
118
+ cacheControlToJsObject(cacheControl)
119
+ case ContentBlockBase (imageBlock @ ImageBlock (_, _, _), maybeCacheControl) =>
120
+ Json .toJson(imageBlock)(imageBlockWrites).as[JsObject ] ++
121
+ cacheControlToJsObject(maybeCacheControl)
122
+ case ContentBlockBase (documentBlock @ DocumentBlock (_, _, _), maybeCacheControl) =>
123
+ Json .toJson(documentBlock)(documentBlockWrites).as[JsObject ] ++
124
+ cacheControlToJsObject(maybeCacheControl) ++
125
+ maybeCacheControl
126
+ .map(cc => Json .toJson(cc)(cacheControlFormat.writes))
127
+ .getOrElse(Json .obj())
128
+
99
129
}
100
130
101
131
implicit lazy val contentBlockReads : Reads [ContentBlockBase ] =
@@ -117,20 +147,33 @@ trait JsonFormats {
117
147
data <- (source \ " data" ).validate[String ]
118
148
cacheControl <- (json \ " cache_control" ).validateOpt[CacheControl ]
119
149
} yield ContentBlockBase (ImageBlock (`type`, mediaType, data), cacheControl)
150
+
151
+ case " document" =>
152
+ for {
153
+ source <- (json \ " source" ).validate[JsObject ]
154
+ `type` <- (source \ " type" ).validate[String ]
155
+ mediaType <- (source \ " media_type" ).validate[String ]
156
+ data <- (source \ " data" ).validate[String ]
157
+ cacheControl <- (json \ " cache_control" ).validateOpt[CacheControl ]
158
+ } yield ContentBlockBase (DocumentBlock (`type`, mediaType, data), cacheControl)
159
+
120
160
case _ => JsError (" Unsupported or invalid content block" )
121
161
}
122
162
}
123
163
124
164
// CacheControl Reads and Writes
125
- implicit lazy val cacheControlReads : Reads [CacheControl ] = Reads [CacheControl ] {
126
- case JsString (" ephemeral" ) => JsSuccess (CacheControl .Ephemeral )
127
- case JsNull | JsUndefined () => JsSuccess (null )
128
- case _ => JsError (" Invalid cache control" )
129
- }
130
-
131
- implicit lazy val cacheControlWrites : Writes [CacheControl ] = Writes [CacheControl ] {
132
- case CacheControl .Ephemeral => JsString (" ephemeral" )
133
- }
165
+ // implicit lazy val cacheControlReads: Reads[Option[CacheControl]] =
166
+ // Reads[Option[CacheControl]] {
167
+ // case JsObject(Seq("type", JsString("ephemeral"))) =>
168
+ // JsSuccess(Some(CacheControl.Ephemeral))
169
+ // case JsNull | JsUndefined() => JsSuccess(None)
170
+ // case _ => JsError("Invalid cache control")
171
+ // }
172
+ //
173
+ // implicit lazy val cacheControlWrites: Writes[CacheControl] =
174
+ // Writes[CacheControl] { case CacheControl.Ephemeral =>
175
+ // Json.obj("cache_control" -> Json.obj("type" -> "ephemeral"))
176
+ // }
134
177
135
178
implicit lazy val contentReads : Reads [Content ] = new Reads [Content ] {
136
179
def reads (json : JsValue ): JsResult [Content ] = json match {
0 commit comments