|
39 | 39 |
|
40 | 40 | from langchain_oci.chat_models import ChatOCIGenAI |
41 | 41 |
|
| 42 | + |
| 43 | +def _content_to_str(content: str | list) -> str: |
| 44 | + """Convert message content to string for assertions. |
| 45 | +
|
| 46 | + AIMessage.content can be str or list[str | dict], so we need to |
| 47 | + handle both cases for string operations like .lower(). |
| 48 | + """ |
| 49 | + if isinstance(content, str): |
| 50 | + return content |
| 51 | + # Handle list content by joining text parts |
| 52 | + parts = [] |
| 53 | + for item in content: |
| 54 | + if isinstance(item, str): |
| 55 | + parts.append(item) |
| 56 | + elif isinstance(item, dict) and "text" in item: |
| 57 | + parts.append(str(item["text"])) |
| 58 | + return " ".join(parts) |
| 59 | + |
| 60 | + |
42 | 61 | # Test configuration from environment |
43 | 62 | COMPARTMENT_ID = os.getenv( |
44 | 63 | "OCI_COMPARTMENT_ID", |
@@ -140,7 +159,7 @@ def test_single_tool_result(self, model_id: str) -> None: |
140 | 159 | assert response is not None |
141 | 160 | assert response.content |
142 | 161 | # Verify the response mentions the weather data |
143 | | - content_lower = response.content.lower() |
| 162 | + content_lower = _content_to_str(response.content).lower() |
144 | 163 | assert any( |
145 | 164 | term in content_lower for term in ["22", "sunny", "rome", "temperature"] |
146 | 165 | ), f"Response should mention weather data: {response.content}" |
@@ -173,7 +192,7 @@ def test_tool_result_with_system_message(self, model_id: str) -> None: |
173 | 192 |
|
174 | 193 | assert response is not None |
175 | 194 | assert response.content |
176 | | - content_lower = response.content.lower() |
| 195 | + content_lower = _content_to_str(response.content).lower() |
177 | 196 | assert any(term in content_lower for term in ["18", "tokyo", "cloudy"]), ( |
178 | 197 | f"Response should mention Tokyo weather: {response.content}" |
179 | 198 | ) |
@@ -221,7 +240,7 @@ def test_multiple_sequential_tool_results(self, model_id: str) -> None: |
221 | 240 | assert response is not None |
222 | 241 | assert response.content |
223 | 242 | # Should mention both cities or their weather |
224 | | - content_lower = response.content.lower() |
| 243 | + content_lower = _content_to_str(response.content).lower() |
225 | 244 | assert any( |
226 | 245 | term in content_lower |
227 | 246 | for term in ["paris", "london", "15", "12", "rainy", "foggy", "compare"] |
@@ -316,7 +335,8 @@ def test_simple_chat_still_works(self, model_id: str) -> None: |
316 | 335 | assert response is not None |
317 | 336 | assert response.content |
318 | 337 | # Model should return "4" or mention "four" |
319 | | - assert "4" in response.content or "four" in response.content.lower() |
| 338 | + content_str = _content_to_str(response.content) |
| 339 | + assert "4" in content_str or "four" in content_str.lower() |
320 | 340 |
|
321 | 341 |
|
322 | 342 | @pytest.mark.requires("oci") |
@@ -394,7 +414,7 @@ def test_json_tool_result(self, model_id: str) -> None: |
394 | 414 | assert response is not None |
395 | 415 | assert response.content |
396 | 416 | # Should reference some of the forecast data |
397 | | - content_lower = response.content.lower() |
| 417 | + content_lower = _content_to_str(response.content).lower() |
398 | 418 | assert any( |
399 | 419 | term in content_lower |
400 | 420 | for term in ["monday", "tuesday", "22", "24", "forecast", "weather"] |
@@ -494,7 +514,7 @@ def test_parallel_tool_results_same_function(self, model_id: str) -> None: |
494 | 514 |
|
495 | 515 | assert response is not None |
496 | 516 | assert response.content |
497 | | - content_lower = response.content.lower() |
| 517 | + content_lower = _content_to_str(response.content).lower() |
498 | 518 | # Should mention at least some of the cities or their weather data |
499 | 519 | mentioned_cities = sum( |
500 | 520 | 1 for city in ["new york", "london", "tokyo", "ny"] if city in content_lower |
@@ -546,7 +566,7 @@ def test_parallel_tool_results_different_functions(self, model_id: str) -> None: |
546 | 566 |
|
547 | 567 | assert response is not None |
548 | 568 | assert response.content |
549 | | - content_lower = response.content.lower() |
| 569 | + content_lower = _content_to_str(response.content).lower() |
550 | 570 | # Should reference both weather and stock data |
551 | 571 | has_weather_ref = any( |
552 | 572 | term in content_lower |
@@ -675,7 +695,7 @@ def test_parallel_tool_calls_with_errors(self, model_id: str) -> None: |
675 | 695 | assert response is not None |
676 | 696 | assert response.content |
677 | 697 | # Should handle the mixed success/error gracefully |
678 | | - content_lower = response.content.lower() |
| 698 | + content_lower = _content_to_str(response.content).lower() |
679 | 699 | # Should at least mention the successful weather data |
680 | 700 | assert any( |
681 | 701 | term in content_lower |
|
0 commit comments