|
1 | 1 | """Base agent abstraction with model selection and SDK integration points.""" |
2 | 2 |
|
3 | 3 | import asyncio |
| 4 | +import logging |
4 | 5 | import os |
5 | 6 | from abc import ABC, abstractmethod |
6 | 7 | from dataclasses import dataclass |
7 | 8 | from time import perf_counter |
8 | 9 | from typing import Any, AsyncGenerator, Awaitable, Callable |
9 | 10 |
|
| 11 | +logger = logging.getLogger(__name__) |
| 12 | + |
10 | 13 | from agent_framework import BaseAgent |
11 | 14 | from holiday_peak_lib.agents.complexity import assess_complexity |
12 | 15 |
|
@@ -380,10 +383,22 @@ async def __invoke_target( |
380 | 383 | except asyncio.TimeoutError: |
381 | 384 | outcome = "timeout" |
382 | 385 | error_text = "Model invocation timed out" |
| 386 | + logger.error( |
| 387 | + "agent_model_invocation_timeout service=%s model=%s", |
| 388 | + getattr(self, "service_name", "unknown"), |
| 389 | + target.model, |
| 390 | + ) |
383 | 391 | raise |
384 | 392 | except Exception as exc: |
385 | 393 | outcome = "error" |
386 | 394 | error_text = str(exc) |
| 395 | + logger.error( |
| 396 | + "agent_model_invocation_failed service=%s model=%s error=%s", |
| 397 | + getattr(self, "service_name", "unknown"), |
| 398 | + target.model, |
| 399 | + exc, |
| 400 | + exc_info=True, |
| 401 | + ) |
387 | 402 | raise |
388 | 403 | finally: |
389 | 404 | elapsed_ms = (perf_counter() - started) * 1000 |
@@ -641,3 +656,38 @@ async def invoke_model_stream( |
641 | 656 | @abstractmethod |
642 | 657 | async def handle(self, request: dict[str, Any]) -> dict[str, Any]: |
643 | 658 | """Handle an incoming request.""" |
| 659 | + |
| 660 | + def __init_subclass__(cls, **kwargs: Any) -> None: |
| 661 | + """Auto-wrap concrete handle() implementations with entry/exit logging.""" |
| 662 | + super().__init_subclass__(**kwargs) |
| 663 | + original_handle = cls.__dict__.get("handle") |
| 664 | + if original_handle is None: |
| 665 | + return |
| 666 | + |
| 667 | + async def _logged_handle(self: Any, request: dict[str, Any]) -> dict[str, Any]: |
| 668 | + svc = getattr(self, "service_name", cls.__name__) |
| 669 | + logger.info("agent_handle_entry service=%s", svc) |
| 670 | + started = perf_counter() |
| 671 | + try: |
| 672 | + result = await original_handle(self, request) |
| 673 | + elapsed = (perf_counter() - started) * 1000 |
| 674 | + logger.info( |
| 675 | + "agent_handle_success service=%s elapsed_ms=%.1f", |
| 676 | + svc, |
| 677 | + elapsed, |
| 678 | + ) |
| 679 | + return result |
| 680 | + except Exception as exc: |
| 681 | + elapsed = (perf_counter() - started) * 1000 |
| 682 | + logger.error( |
| 683 | + "agent_handle_failed service=%s elapsed_ms=%.1f error=%s", |
| 684 | + svc, |
| 685 | + elapsed, |
| 686 | + exc, |
| 687 | + exc_info=True, |
| 688 | + ) |
| 689 | + raise |
| 690 | + |
| 691 | + _logged_handle.__name__ = "handle" |
| 692 | + _logged_handle.__qualname__ = f"{cls.__qualname__}.handle" |
| 693 | + cls.handle = _logged_handle # type: ignore[method-assign] |
0 commit comments