1+ use crate :: prelude:: * ;
2+ use base64:: prelude:: * ;
3+
14use crate :: llm:: {
25 LlmGenerateRequest , LlmGenerateResponse , LlmGenerationClient , OutputFormat ,
36 ToJsonSchemaOptions , detect_image_mime_type,
47} ;
5- use anyhow:: { Context , Result , bail} ;
6- use async_trait:: async_trait;
7- use base64:: prelude:: * ;
8+ use anyhow:: Context ;
89use json5;
9- use serde_json:: Value ;
10-
11- use crate :: api_bail;
1210use urlencoding:: encode;
1311
1412pub struct Client {
@@ -91,23 +89,26 @@ impl LlmGenerationClient for Client {
9189
9290 let encoded_api_key = encode ( & self . api_key ) ;
9391
94- let resp = self
95- . client
96- . post ( url)
97- . header ( "x-api-key" , encoded_api_key. as_ref ( ) )
98- . header ( "anthropic-version" , "2023-06-01" )
99- . json ( & payload)
100- . send ( )
101- . await
102- . context ( "HTTP error" ) ?;
92+ let resp = retryable:: run (
93+ || {
94+ self . client
95+ . post ( url)
96+ . header ( "x-api-key" , encoded_api_key. as_ref ( ) )
97+ . header ( "anthropic-version" , "2023-06-01" )
98+ . json ( & payload)
99+ . send ( )
100+ } ,
101+ & retryable:: HEAVY_LOADED_OPTIONS ,
102+ )
103+ . await ?;
103104 if !resp. status ( ) . is_success ( ) {
104105 bail ! (
105106 "Anthropic API error: {:?}\n {}\n " ,
106107 resp. status( ) ,
107108 resp. text( ) . await ?
108109 ) ;
109110 }
110- let mut resp_json: Value = resp. json ( ) . await . context ( "Invalid JSON" ) ?;
111+ let mut resp_json: serde_json :: Value = resp. json ( ) . await . context ( "Invalid JSON" ) ?;
111112 if let Some ( error) = resp_json. get ( "error" ) {
112113 bail ! ( "Anthropic API error: {:?}" , error) ;
113114 }
@@ -117,11 +118,11 @@ impl LlmGenerationClient for Client {
117118
118119 let resp_content = & resp_json[ "content" ] ;
119120 let tool_name = "report_result" ;
120- let mut extracted_json: Option < Value > = None ;
121+ let mut extracted_json: Option < serde_json :: Value > = None ;
121122 if let Some ( array) = resp_content. as_array ( ) {
122123 for item in array {
123- if item. get ( "type" ) == Some ( & Value :: String ( "tool_use" . to_string ( ) ) )
124- && item. get ( "name" ) == Some ( & Value :: String ( tool_name. to_string ( ) ) )
124+ if item. get ( "type" ) == Some ( & serde_json :: Value :: String ( "tool_use" . to_string ( ) ) )
125+ && item. get ( "name" ) == Some ( & serde_json :: Value :: String ( tool_name. to_string ( ) ) )
125126 {
126127 if let Some ( input) = item. get ( "input" ) {
127128 extracted_json = Some ( input. clone ( ) ) ;
@@ -136,7 +137,7 @@ impl LlmGenerationClient for Client {
136137 } else {
137138 // Fallback: try text if no tool output found
138139 match & mut resp_json[ "content" ] [ 0 ] [ "text" ] {
139- Value :: String ( s) => {
140+ serde_json :: Value :: String ( s) => {
140141 // Try strict JSON parsing first
141142 match serde_json:: from_str :: < serde_json:: Value > ( s) {
142143 Ok ( _) => std:: mem:: take ( s) ,
0 commit comments