File size: 2,598 Bytes
75bea1c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from __future__ import annotations
"""Logging configuration for the Ask-the-Web Agent."""

import logging
import sys
from typing import Any

from rich.console import Console
from rich.logging import RichHandler

from src.utils.config import settings

# Rich console for pretty output
console = Console()


def get_logger(name: str) -> logging.Logger:
    """Get a configured logger instance.
    
    Args:
        name: Logger name (typically __name__)
        
    Returns:
        Configured logger instance
    """
    logger = logging.getLogger(name)

    if not logger.handlers:
        logger.setLevel(getattr(logging, settings.log_level.upper()))

        if settings.log_format == "json":
            # JSON format for production
            handler = logging.StreamHandler(sys.stdout)
            formatter = logging.Formatter(
                '{"timestamp": "%(asctime)s", "level": "%(levelname)s", '
                '"name": "%(name)s", "message": "%(message)s"}'
            )
            handler.setFormatter(formatter)
        else:
            # Rich handler for development
            handler = RichHandler(
                console=console,
                show_time=True,
                show_path=False,
                rich_tracebacks=True,
            )

        logger.addHandler(handler)
        logger.propagate = False

    return logger


def log_agent_step(
    logger: logging.Logger,
    step_type: str,
    content: dict[str, Any],
    iteration: int | None = None,
) -> None:
    """Log an agent step with structured data.
    
    Args:
        logger: Logger instance
        step_type: Type of step (thought, action, observation, etc.)
        content: Step content as dictionary
        iteration: Optional iteration number
    """
    prefix = f"[Iteration {iteration}] " if iteration is not None else ""
    logger.info(f"{prefix}{step_type.upper()}: {content}")


def log_tool_call(
    logger: logging.Logger,
    tool_name: str,
    parameters: dict[str, Any],
    result: Any = None,
    error: str | None = None,
) -> None:
    """Log a tool call with parameters and result.
    
    Args:
        logger: Logger instance
        tool_name: Name of the tool
        parameters: Tool parameters
        result: Tool result (optional)
        error: Error message if failed (optional)
    """
    if error:
        logger.error(f"Tool '{tool_name}' failed: {error} | Params: {parameters}")
    else:
        logger.info(f"Tool '{tool_name}' called | Params: {parameters}")
        if result:
            logger.debug(f"Tool '{tool_name}' result: {result}")