3030import com .fasterxml .jackson .annotation .JsonProperty ;
3131import com .fasterxml .jackson .annotation .JsonSubTypes ;
3232import com .fasterxml .jackson .annotation .JsonTypeInfo ;
33+ import com .fasterxml .jackson .databind .annotation .JsonDeserialize ;
34+ import com .fasterxml .jackson .databind .annotation .JsonSerialize ;
3335import reactor .core .publisher .Flux ;
3436import reactor .core .publisher .Mono ;
3537
3638import org .springframework .ai .anthropic .api .StreamHelper .ChatCompletionResponseBuilder ;
3739import org .springframework .ai .model .ApiKey ;
40+ import org .springframework .ai .anthropic .api .tool .Tool ;
41+ import org .springframework .ai .anthropic .util .ContentFieldDeserializer ;
42+ import org .springframework .ai .anthropic .util .ContentFieldSerializer ;
3843import org .springframework .ai .model .ChatModelDescription ;
3944import org .springframework .ai .model .ModelOptionsUtils ;
4045import org .springframework .ai .model .SimpleApiKey ;
@@ -750,7 +755,11 @@ public record ContentBlock(
750755
751756 // tool_result response only
752757 @ JsonProperty ("tool_use_id" ) String toolUseId ,
753- @ JsonProperty ("content" ) String content ,
758+
759+ @ JsonSerialize (using = ContentFieldSerializer .class )
760+ @ JsonDeserialize (using = ContentFieldDeserializer .class )
761+ @ JsonProperty ("content" )
762+ Object content ,
754763
755764 // Thinking only
756765 @ JsonProperty ("signature" ) String signature ,
@@ -761,6 +770,15 @@ public record ContentBlock(
761770 ) {
762771 // @formatter:on
763772
773+ @ JsonInclude (Include .NON_NULL )
774+ @ JsonIgnoreProperties (ignoreUnknown = true )
775+ public record WebSearchToolContentBlock (@ JsonProperty ("type" ) String type , @ JsonProperty ("title" ) String title ,
776+ @ JsonProperty ("url" ) String url , @ JsonProperty ("encrypted_content" ) String EncryptedContent ,
777+ @ JsonProperty ("page_age" ) String pageAge ) {
778+
779+ }
780+ // @formatter:on
781+
764782 /**
765783 * Create content block
766784 * @param mediaType The media type of the content.
@@ -846,6 +864,18 @@ public enum Type {
846864 @ JsonProperty ("tool_result" )
847865 TOOL_RESULT ("tool_result" ),
848866
867+ /**
868+ * Server Tool request
869+ */
870+ @ JsonProperty ("server_tool_use" )
871+ SERVER_TOOL_USE ("server_tool_use" ),
872+
873+ /**
874+ * Web search tool result
875+ */
876+ @ JsonProperty ("web_search_tool_result" )
877+ WEB_SEARCH_TOOL_RESULT ("web_search_tool_result" ),
878+
849879 /**
850880 * Text message.
851881 */
@@ -959,22 +989,6 @@ public Source(String url) {
959989 /// CONTENT_BLOCK EVENTS
960990 ///////////////////////////////////////
961991
962- /**
963- * Tool description.
964- *
965- * @param name The name of the tool.
966- * @param description A description of the tool.
967- * @param inputSchema The input schema of the tool.
968- */
969- @ JsonInclude (Include .NON_NULL )
970- public record Tool (
971- // @formatter:off
972- @ JsonProperty ("name" ) String name ,
973- @ JsonProperty ("description" ) String description ,
974- @ JsonProperty ("input_schema" ) Map <String , Object > inputSchema ) {
975- // @formatter:on
976- }
977-
978992 // CB START EVENT
979993
980994 /**
@@ -1020,16 +1034,25 @@ public record ChatCompletionResponse(
10201034 public record Usage (
10211035 // @formatter:off
10221036 @ JsonProperty ("input_tokens" ) Integer inputTokens ,
1023- @ JsonProperty ("output_tokens" ) Integer outputTokens ) {
1024- // @formatter:off
1037+ @ JsonProperty ("output_tokens" ) Integer outputTokens ,
1038+ @ JsonProperty ("server_tool_use" ) ServerToolUse serverToolUse ) {
1039+ // @formatter:on
1040+ }
1041+
1042+ @ JsonInclude (Include .NON_NULL )
1043+ @ JsonIgnoreProperties (ignoreUnknown = true )
1044+ public record ServerToolUse (
1045+ // @formatter:off
1046+ @ JsonProperty ("web_search_requests" ) Integer webSearchRequests ) {
1047+ // @formatter:on
10251048 }
10261049
1027- /// ECB STOP
1050+ /// ECB STOP
10281051
10291052 /**
10301053 * Special event used to aggregate multiple tool use events into a single event with
10311054 * list of aggregated ContentBlockToolUse.
1032- */
1055+ */
10331056 public static class ToolUseAggregationEvent implements StreamEvent {
10341057
10351058 private Integer index ;
@@ -1048,17 +1071,17 @@ public EventType type() {
10481071 }
10491072
10501073 /**
1051- * Get tool content blocks.
1052- * @return The tool content blocks.
1053- */
1074+ * Get tool content blocks.
1075+ * @return The tool content blocks.
1076+ */
10541077 public List <ContentBlockStartEvent .ContentBlockToolUse > getToolContentBlocks () {
10551078 return this .toolContentBlocks ;
10561079 }
10571080
10581081 /**
1059- * Check if the event is empty.
1060- * @return True if the event is empty, false otherwise.
1061- */
1082+ * Check if the event is empty.
1083+ * @return True if the event is empty, false otherwise.
1084+ */
10621085 public boolean isEmpty () {
10631086 return (this .index == null || this .id == null || this .name == null
10641087 || !StringUtils .hasText (this .partialJson ));
@@ -1087,7 +1110,8 @@ ToolUseAggregationEvent appendPartialJson(String partialJson) {
10871110 void squashIntoContentBlock () {
10881111 Map <String , Object > map = (StringUtils .hasText (this .partialJson ))
10891112 ? ModelOptionsUtils .jsonToMap (this .partialJson ) : Map .of ();
1090- this .toolContentBlocks .add (new ContentBlockStartEvent .ContentBlockToolUse ("tool_use" , this .id , this .name , map ));
1113+ this .toolContentBlocks
1114+ .add (new ContentBlockStartEvent .ContentBlockToolUse ("tool_use" , this .id , this .name , map ));
10911115 this .index = null ;
10921116 this .id = null ;
10931117 this .name = null ;
@@ -1096,28 +1120,29 @@ void squashIntoContentBlock() {
10961120
10971121 @ Override
10981122 public String toString () {
1099- return "EventToolUseBuilder [index=" + this .index + ", id=" + this .id + ", name=" + this .name + ", partialJson="
1100- + this .partialJson + ", toolUseMap=" + this .toolContentBlocks + "]" ;
1123+ return "EventToolUseBuilder [index=" + this .index + ", id=" + this .id + ", name=" + this .name
1124+ + ", partialJson=" + this .partialJson + ", toolUseMap=" + this .toolContentBlocks + "]" ;
11011125 }
11021126
11031127 }
11041128
1105- ///////////////////////////////////////
1106- /// MESSAGE EVENTS
1107- ///////////////////////////////////////
1129+ ///////////////////////////////////////
1130+ /// MESSAGE EVENTS
1131+ ///////////////////////////////////////
11081132
1109- // MESSAGE START EVENT
1133+ // MESSAGE START EVENT
11101134
11111135 /**
11121136 * Content block start event.
1137+ *
11131138 * @param type The event type.
11141139 * @param index The index of the content block.
11151140 * @param contentBlock The content block body.
1116- */
1141+ */
11171142 @ JsonInclude (Include .NON_NULL )
11181143 @ JsonIgnoreProperties (ignoreUnknown = true )
11191144 public record ContentBlockStartEvent (
1120- // @formatter:off
1145+ // @formatter:off
11211146 @ JsonProperty ("type" ) EventType type ,
11221147 @ JsonProperty ("index" ) Integer index ,
11231148 @ JsonProperty ("content_block" ) ContentBlockBody contentBlock ) implements StreamEvent {
0 commit comments