@@ -1085,6 +1085,106 @@ def test_files_api_pdf(block_format: str) -> None:
1085
1085
_ = llm .invoke ([input_message ])
1086
1086
1087
1087
1088
+ def test_search_result_tool_message () -> None :
1089
+ """Test that we can pass a search result tool message to the model."""
1090
+ llm = ChatAnthropic (
1091
+ model = "claude-3-5-haiku-latest" ,
1092
+ betas = ["search-results-2025-06-09" ],
1093
+ )
1094
+
1095
+ @tool
1096
+ def retrieval_tool (query : str ) -> list [dict ]:
1097
+ """Retrieve information from a knowledge base."""
1098
+ return [
1099
+ {
1100
+ "type" : "search_result" ,
1101
+ "title" : "Leave policy" ,
1102
+ "source" : "HR Leave Policy 2025" ,
1103
+ "citations" : {"enabled" : True },
1104
+ "content" : [
1105
+ {
1106
+ "type" : "text" ,
1107
+ "text" : (
1108
+ "To request vacation days, submit a leave request form "
1109
+ "through the HR portal. Approval will be sent by email."
1110
+ ),
1111
+ }
1112
+ ],
1113
+ }
1114
+ ]
1115
+
1116
+ tool_call = {
1117
+ "type" : "tool_call" ,
1118
+ "name" : "retrieval_tool" ,
1119
+ "args" : {"query" : "vacation days request process" },
1120
+ "id" : "toolu_abc123" ,
1121
+ }
1122
+
1123
+ tool_message = retrieval_tool .invoke (tool_call )
1124
+ assert isinstance (tool_message , ToolMessage )
1125
+ assert isinstance (tool_message .content , list )
1126
+
1127
+ messages = [
1128
+ HumanMessage ("How do I request vacation days?" ),
1129
+ AIMessage (
1130
+ [{"type" : "text" , "text" : "Let me look that up for you." }],
1131
+ tool_calls = [tool_call ],
1132
+ ),
1133
+ tool_message ,
1134
+ ]
1135
+
1136
+ result = llm .invoke (messages )
1137
+ assert isinstance (result , AIMessage )
1138
+ assert isinstance (result .content , list )
1139
+ assert any ("citations" in block for block in result .content )
1140
+
1141
+
1142
+ def test_search_result_top_level () -> None :
1143
+ llm = ChatAnthropic (
1144
+ model = "claude-3-5-haiku-latest" ,
1145
+ betas = ["search-results-2025-06-09" ],
1146
+ )
1147
+ input_message = HumanMessage (
1148
+ [
1149
+ {
1150
+ "type" : "search_result" ,
1151
+ "title" : "Leave policy" ,
1152
+ "source" : "HR Leave Policy 2025 - page 1" ,
1153
+ "citations" : {"enabled" : True },
1154
+ "content" : [
1155
+ {
1156
+ "type" : "text" ,
1157
+ "text" : (
1158
+ "To request vacation days, submit a leave request form "
1159
+ "through the HR portal. Approval will be sent by email."
1160
+ ),
1161
+ }
1162
+ ],
1163
+ },
1164
+ {
1165
+ "type" : "search_result" ,
1166
+ "title" : "Leave policy" ,
1167
+ "source" : "HR Leave Policy 2025 - page 2" ,
1168
+ "citations" : {"enabled" : True },
1169
+ "content" : [
1170
+ {
1171
+ "type" : "text" ,
1172
+ "text" : "Managers have 3 days to approve a request." ,
1173
+ }
1174
+ ],
1175
+ },
1176
+ {
1177
+ "type" : "text" ,
1178
+ "text" : "How do I request vacation days?" ,
1179
+ },
1180
+ ]
1181
+ )
1182
+ result = llm .invoke ([input_message ])
1183
+ assert isinstance (result , AIMessage )
1184
+ assert isinstance (result .content , list )
1185
+ assert any ("citations" in block for block in result .content )
1186
+
1187
+
1088
1188
def test_async_shared_client () -> None :
1089
1189
llm = ChatAnthropic (model = "claude-3-5-haiku-latest" )
1090
1190
llm ._async_client # Instantiates lazily
0 commit comments