(agent_dir, test_file, monkeypatch)
| 451 | get_test_files(), |
| 452 | ) |
| 453 | def test_agent_replay(agent_dir, test_file, monkeypatch): |
| 454 | # Add agent_dir.parent to sys.path so relative imports work |
| 455 | import sys |
| 456 | |
| 457 | sys_path_saved = list(sys.path) |
| 458 | sys.path.insert(0, str(agent_dir.parent)) |
| 459 | |
| 460 | try: |
| 461 | import random |
| 462 | |
| 463 | random.seed(42) |
| 464 | |
| 465 | loader = AgentLoader(str(agent_dir.parent)) |
| 466 | loader.remove_agent_from_cache(agent_dir.name) |
| 467 | agent_or_app = loader.load_agent(agent_dir.name) |
| 468 | |
| 469 | root_agent = ( |
| 470 | agent_or_app.root_agent |
| 471 | if isinstance(agent_or_app, App) |
| 472 | else agent_or_app |
| 473 | ) |
| 474 | _make_nodes_sequential(root_agent) |
| 475 | agent_names = _get_all_agent_names(root_agent) |
| 476 | |
| 477 | import inspect |
| 478 | |
| 479 | # Dynamically locate the loaded agent module from sys.modules |
| 480 | mod = sys.modules.get(f"{agent_dir.name}.agent") or sys.modules.get( |
| 481 | agent_dir.name |
| 482 | ) |
| 483 | if not mod: |
| 484 | # Fallback for namespace packages or nested imports |
| 485 | for k, v in sys.modules.items(): |
| 486 | if k.endswith(f"{agent_dir.name}.agent") or k.endswith(agent_dir.name): |
| 487 | mod = v |
| 488 | break |
| 489 | |
| 490 | # Reflectively find all Agent instances defined in the module (e.g. dynamic agents) |
| 491 | if mod: |
| 492 | for _, obj in inspect.getmembers(mod): |
| 493 | if isinstance(obj, BaseAgent) and hasattr(obj, "name"): |
| 494 | agent_names.add(obj.name) |
| 495 | |
| 496 | with open(test_file, "r") as f: |
| 497 | session_data = json.load(f) |
| 498 | |
| 499 | events_data = session_data.get("events", []) |
| 500 | if not events_data: |
| 501 | pytest.skip(f"No events in {test_file}") |
| 502 | |
| 503 | first_event = events_data[0] |
| 504 | user_message = "" |
| 505 | if first_event.get("author") == "user": |
| 506 | parts = first_event.get("content", {}).get("parts", []) |
| 507 | if parts and "text" in parts[0]: |
| 508 | user_message = parts[0]["text"] |
| 509 | |
| 510 | if not user_message: |
nothing calls this directly
no test coverage detected