@@ -19,7 +19,7 @@ import io.cequence.openaiscala.anthropic.domain.response.{
19
19
CreateMessageResponse ,
20
20
DeltaText
21
21
}
22
- import io .cequence .openaiscala .anthropic .domain .{ChatRole , Content , Message }
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
25
import play .api .libs .json ._
@@ -44,11 +44,11 @@ trait JsonFormats {
44
44
45
45
implicit lazy val contentBlocksFormat : Format [ContentBlocks ] = Json .format[ContentBlocks ]
46
46
47
- // implicit val textBlockWrites: Writes[TextBlock] = Json.writes[TextBlock]
48
- implicit val textBlockReads : Reads [TextBlock ] = Json .reads[TextBlock ]
47
+ // implicit lazy val textBlockWrites: Writes[TextBlock] = Json.writes[TextBlock]
48
+ implicit lazy val textBlockReads : Reads [TextBlock ] = Json .reads[TextBlock ]
49
49
50
- implicit val textBlockWrites : Writes [TextBlock ] = Json .writes[TextBlock ]
51
- implicit val imageBlockWrites : Writes [ImageBlock ] =
50
+ implicit lazy val textBlockWrites : Writes [TextBlock ] = Json .writes[TextBlock ]
51
+ implicit lazy val imageBlockWrites : Writes [ImageBlock ] =
52
52
(block : ImageBlock ) =>
53
53
Json .obj(
54
54
" type" -> " image" ,
@@ -59,16 +59,22 @@ trait JsonFormats {
59
59
)
60
60
)
61
61
62
- implicit val contentBlockWrites : Writes [ContentBlock ] = {
62
+ implicit lazy val contentBlockWrites : Writes [ContentBlock ] = {
63
63
case tb : TextBlock =>
64
64
Json .obj(" type" -> " text" ) ++ Json .toJson(tb)(textBlockWrites).as[JsObject ]
65
65
case ib : ImageBlock => Json .toJson(ib)(imageBlockWrites)
66
66
}
67
67
68
- implicit val contentBlockReads : Reads [ContentBlock ] =
68
+ implicit lazy val contentBlockReads : Reads [ContentBlock ] =
69
69
(json : JsValue ) => {
70
70
(json \ " type" ).validate[String ].flatMap {
71
- case " text" => (json \ " text" ).validate[String ].map(TextBlock .apply)
71
+ case " text" =>
72
+ ((json \ " text" ).validate[String ] and
73
+ (json \ " cache_control" ).validateOpt[CacheControl ]).tupled.flatMap {
74
+ case (text, cacheControl) => JsSuccess (TextBlock (text, cacheControl))
75
+ case _ => JsError (" Invalid text block" )
76
+ }
77
+
72
78
case " image" =>
73
79
for {
74
80
source <- (json \ " source" ).validate[JsObject ]
@@ -80,44 +86,65 @@ trait JsonFormats {
80
86
}
81
87
}
82
88
83
- implicit val contentReads : Reads [Content ] = new Reads [Content ] {
89
+ // CacheControl Reads and Writes
90
+ implicit lazy val cacheControlReads : Reads [CacheControl ] = Reads [CacheControl ] {
91
+ case JsString (" ephemeral" ) => JsSuccess (CacheControl .Ephemeral )
92
+ case JsNull | JsUndefined () => JsSuccess (null )
93
+ case _ => JsError (" Invalid cache control" )
94
+ }
95
+
96
+ implicit lazy val cacheControlWrites : Writes [CacheControl ] = Writes [CacheControl ] {
97
+ case CacheControl .Ephemeral => JsString (" ephemeral" )
98
+ }
99
+
100
+ implicit lazy val contentReads : Reads [Content ] = new Reads [Content ] {
84
101
def reads (json : JsValue ): JsResult [Content ] = json match {
85
102
case JsString (str) => JsSuccess (SingleString (str))
86
103
case JsArray (_) => Json .fromJson[Seq [ContentBlock ]](json).map(ContentBlocks (_))
87
104
case _ => JsError (" Invalid content format" )
88
105
}
89
106
}
90
107
91
- implicit val baseMessageWrites : Writes [Message ] = new Writes [Message ] {
92
- def writes (message : Message ): JsValue = message match {
93
- case UserMessage (content) => Json .obj(" role" -> " user" , " content" -> content)
94
- case UserMessageContent (content) =>
95
- Json .obj(
96
- " role" -> " user" ,
97
- " content" -> content.map(Json .toJson(_)(contentBlockWrites))
98
- )
99
- case AssistantMessage (content) => Json .obj(" role" -> " assistant" , " content" -> content)
100
- case AssistantMessageContent (content) =>
101
- Json .obj(
102
- " role" -> " assistant" ,
103
- " content" -> content.map(Json .toJson(_)(contentBlockWrites))
104
- )
105
- // Add cases for other subclasses if necessary
106
- }
107
- }
108
-
109
- implicit val baseMessageReads : Reads [Message ] = (
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
+ // }
125
+
126
+ implicit lazy val baseMessageReads : Reads [Message ] = (
110
127
(__ \ " role" ).read[String ] and
111
- (__ \ " content" ).lazyRead(contentReads)
128
+ (__ \ " content" ).read[JsValue ] and
129
+ (__ \ " cache_control" ).readNullable[CacheControl ]
112
130
).tupled.flatMap {
113
- case (" user" , SingleString (text)) => Reads .pure(UserMessage (text))
114
- case (" user" , ContentBlocks (blocks)) => Reads .pure(UserMessageContent (blocks))
115
- case (" assistant" , SingleString (text)) => Reads .pure(AssistantMessage (text))
116
- case (" assistant" , ContentBlocks (blocks)) => Reads .pure(AssistantMessageContent (blocks))
117
- case _ => Reads (_ => JsError (" Unsupported role or content type" ))
131
+ 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
+
135
+ }
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"))
118
145
}
119
146
120
- implicit val createMessageResponseReads : Reads [CreateMessageResponse ] = (
147
+ implicit lazy val createMessageResponseReads : Reads [CreateMessageResponse ] = (
121
148
(__ \ " id" ).read[String ] and
122
149
(__ \ " role" ).read[ChatRole ] and
123
150
(__ \ " content" ).read[Seq [ContentBlock ]].map(ContentBlocks (_)) and
@@ -127,9 +154,10 @@ trait JsonFormats {
127
154
(__ \ " usage" ).read[UsageInfo ]
128
155
)(CreateMessageResponse .apply _)
129
156
130
- implicit val createMessageChunkResponseReads : Reads [CreateMessageChunkResponse ] =
157
+ implicit lazy val createMessageChunkResponseReads : Reads [CreateMessageChunkResponse ] =
131
158
Json .reads[CreateMessageChunkResponse ]
132
159
133
- implicit val deltaTextReads : Reads [DeltaText ] = Json .reads[DeltaText ]
134
- implicit val contentBlockDeltaReads : Reads [ContentBlockDelta ] = Json .reads[ContentBlockDelta ]
160
+ implicit lazy val deltaTextReads : Reads [DeltaText ] = Json .reads[DeltaText ]
161
+ implicit lazy val contentBlockDeltaReads : Reads [ContentBlockDelta ] =
162
+ Json .reads[ContentBlockDelta ]
135
163
}
0 commit comments