@@ -1183,6 +1183,7 @@ impl Thread {
1183
1183
mode : None ,
1184
1184
messages : vec ! [ ] ,
1185
1185
tools : Vec :: new ( ) ,
1186
+ tool_choice : None ,
1186
1187
stop : Vec :: new ( ) ,
1187
1188
temperature : AssistantSettings :: temperature_for_model ( & model, cx) ,
1188
1189
} ;
@@ -1227,6 +1228,7 @@ impl Thread {
1227
1228
} ) ) ;
1228
1229
}
1229
1230
1231
+ let mut message_ix_to_cache = None ;
1230
1232
for message in & self . messages {
1231
1233
let mut request_message = LanguageModelRequestMessage {
1232
1234
role : message. role ,
@@ -1263,19 +1265,57 @@ impl Thread {
1263
1265
} ;
1264
1266
}
1265
1267
1266
- self . tool_use
1267
- . attach_tool_uses ( message. id , & mut request_message) ;
1268
+ let mut cache_message = true ;
1269
+ let mut tool_results_message = LanguageModelRequestMessage {
1270
+ role : Role :: User ,
1271
+ content : Vec :: new ( ) ,
1272
+ cache : false ,
1273
+ } ;
1274
+ for ( tool_use, tool_result) in self . tool_use . tool_results ( message. id ) {
1275
+ if let Some ( tool_result) = tool_result {
1276
+ request_message
1277
+ . content
1278
+ . push ( MessageContent :: ToolUse ( tool_use. clone ( ) ) ) ;
1279
+ tool_results_message
1280
+ . content
1281
+ . push ( MessageContent :: ToolResult ( LanguageModelToolResult {
1282
+ tool_use_id : tool_use. id . clone ( ) ,
1283
+ tool_name : tool_result. tool_name . clone ( ) ,
1284
+ is_error : tool_result. is_error ,
1285
+ content : if tool_result. content . is_empty ( ) {
1286
+ // Surprisingly, the API fails if we return an empty string here.
1287
+ // It thinks we are sending a tool use without a tool result.
1288
+ "<Tool returned an empty string>" . into ( )
1289
+ } else {
1290
+ tool_result. content . clone ( )
1291
+ } ,
1292
+ output : None ,
1293
+ } ) ) ;
1294
+ } else {
1295
+ cache_message = false ;
1296
+ log:: debug!(
1297
+ "skipped tool use {:?} because it is still pending" ,
1298
+ tool_use
1299
+ ) ;
1300
+ }
1301
+ }
1268
1302
1303
+ if cache_message {
1304
+ message_ix_to_cache = Some ( request. messages . len ( ) ) ;
1305
+ }
1269
1306
request. messages . push ( request_message) ;
1270
1307
1271
- if let Some ( tool_results_message) = self . tool_use . tool_results_message ( message. id ) {
1308
+ if !tool_results_message. content . is_empty ( ) {
1309
+ if cache_message {
1310
+ message_ix_to_cache = Some ( request. messages . len ( ) ) ;
1311
+ }
1272
1312
request. messages . push ( tool_results_message) ;
1273
1313
}
1274
1314
}
1275
1315
1276
1316
// https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching
1277
- if let Some ( last ) = request . messages . last_mut ( ) {
1278
- last . cache = true ;
1317
+ if let Some ( message_ix_to_cache ) = message_ix_to_cache {
1318
+ request . messages [ message_ix_to_cache ] . cache = true ;
1279
1319
}
1280
1320
1281
1321
self . attached_tracked_files_state ( & mut request. messages , cx) ;
@@ -1302,6 +1342,7 @@ impl Thread {
1302
1342
mode : None ,
1303
1343
messages : vec ! [ ] ,
1304
1344
tools : Vec :: new ( ) ,
1345
+ tool_choice : None ,
1305
1346
stop : Vec :: new ( ) ,
1306
1347
temperature : AssistantSettings :: temperature_for_model ( model, cx) ,
1307
1348
} ;
@@ -1918,8 +1959,7 @@ impl Thread {
1918
1959
model : Arc < dyn LanguageModel > ,
1919
1960
) -> Vec < PendingToolUse > {
1920
1961
self . auto_capture_telemetry ( cx) ;
1921
- let request = self . to_completion_request ( model. clone ( ) , cx) ;
1922
- let messages = Arc :: new ( request. messages ) ;
1962
+ let request = Arc :: new ( self . to_completion_request ( model. clone ( ) , cx) ) ;
1923
1963
let pending_tool_uses = self
1924
1964
. tool_use
1925
1965
. pending_tool_uses ( )
@@ -1937,7 +1977,7 @@ impl Thread {
1937
1977
tool_use. id . clone ( ) ,
1938
1978
tool_use. ui_text . clone ( ) ,
1939
1979
tool_use. input . clone ( ) ,
1940
- messages . clone ( ) ,
1980
+ request . clone ( ) ,
1941
1981
tool,
1942
1982
) ;
1943
1983
cx. emit ( ThreadEvent :: ToolConfirmationNeeded ) ;
@@ -1946,7 +1986,7 @@ impl Thread {
1946
1986
tool_use. id . clone ( ) ,
1947
1987
tool_use. ui_text . clone ( ) ,
1948
1988
tool_use. input . clone ( ) ,
1949
- & messages ,
1989
+ request . clone ( ) ,
1950
1990
tool,
1951
1991
model. clone ( ) ,
1952
1992
window,
@@ -2041,29 +2081,22 @@ impl Thread {
2041
2081
tool_use_id : LanguageModelToolUseId ,
2042
2082
ui_text : impl Into < SharedString > ,
2043
2083
input : serde_json:: Value ,
2044
- messages : & [ LanguageModelRequestMessage ] ,
2084
+ request : Arc < LanguageModelRequest > ,
2045
2085
tool : Arc < dyn Tool > ,
2046
2086
model : Arc < dyn LanguageModel > ,
2047
2087
window : Option < AnyWindowHandle > ,
2048
2088
cx : & mut Context < Thread > ,
2049
2089
) {
2050
- let task = self . spawn_tool_use (
2051
- tool_use_id. clone ( ) ,
2052
- messages,
2053
- input,
2054
- tool,
2055
- model,
2056
- window,
2057
- cx,
2058
- ) ;
2090
+ let task =
2091
+ self . spawn_tool_use ( tool_use_id. clone ( ) , request, input, tool, model, window, cx) ;
2059
2092
self . tool_use
2060
2093
. run_pending_tool ( tool_use_id, ui_text. into ( ) , task) ;
2061
2094
}
2062
2095
2063
2096
fn spawn_tool_use (
2064
2097
& mut self ,
2065
2098
tool_use_id : LanguageModelToolUseId ,
2066
- messages : & [ LanguageModelRequestMessage ] ,
2099
+ request : Arc < LanguageModelRequest > ,
2067
2100
input : serde_json:: Value ,
2068
2101
tool : Arc < dyn Tool > ,
2069
2102
model : Arc < dyn LanguageModel > ,
@@ -2077,7 +2110,7 @@ impl Thread {
2077
2110
} else {
2078
2111
tool. run (
2079
2112
input,
2080
- messages ,
2113
+ request ,
2081
2114
self . project . clone ( ) ,
2082
2115
self . action_log . clone ( ) ,
2083
2116
model,
0 commit comments