Skip to content

Commit 8d84f92

Browse files
authored
Refactor to expose agents.RichHandler (#489)
1 parent f2d8c6e commit 8d84f92

File tree

2 files changed

+55
-46
lines changed

2 files changed

+55
-46
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ repos:
9292
- pandas-stubs
9393
- pydantic~=2.0 # Match pyproject.toml
9494
- pydantic-settings
95+
- rich
9596
- tantivy
9697
- tenacity
9798
- tiktoken>=0.4.0 # Match pyproject.toml

paperqa/agents/__init__.py

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,66 +19,74 @@
1919

2020
logger = logging.getLogger(__name__)
2121

22-
23-
def configure_cli_logging(verbosity: int = 0) -> None:
24-
"""Suppress loquacious loggers according to verbosity level."""
25-
setup_default_logs()
26-
27-
verbosity_map = {
28-
0: {
29-
"paperqa.agents": logging.INFO,
30-
"paperqa.agents.helpers": logging.WARNING,
31-
"paperqa.agents.main": logging.WARNING,
32-
"paperqa.agents.main.agent_callers": logging.INFO,
33-
"anthropic": logging.WARNING,
34-
"openai": logging.WARNING,
35-
"httpx": logging.WARNING,
36-
"paperqa.agents.models": logging.WARNING,
37-
"paperqa.agents.search": logging.INFO,
38-
"litellm": logging.WARNING,
39-
"LiteLLM Router": logging.WARNING,
40-
"LiteLLM Proxy": logging.WARNING,
41-
}
42-
}
43-
44-
verbosity_map[1] = verbosity_map[0] | {
45-
"paperqa.agents.main": logging.INFO,
46-
"paperqa.models": logging.INFO,
47-
}
48-
49-
verbosity_map[2] = verbosity_map[1] | {
50-
"paperqa.agents.helpers": logging.DEBUG,
51-
"paperqa.agents.main": logging.DEBUG,
52-
"paperqa.agents.main.agent_callers": logging.DEBUG,
53-
"paperqa.models": logging.DEBUG,
54-
"paperqa.agents.search": logging.DEBUG,
55-
"litellm": logging.INFO,
56-
"LiteLLM Router": logging.INFO,
57-
"LiteLLM Proxy": logging.INFO,
58-
}
59-
60-
verbosity_map[3] = verbosity_map[2] | {
61-
"litellm": logging.DEBUG, # <-- every single LLM call
22+
LOG_VERBOSITY_MAP = {
23+
0: {
24+
"paperqa.agents": logging.INFO,
25+
"paperqa.agents.helpers": logging.WARNING,
26+
"paperqa.agents.main": logging.WARNING,
27+
"paperqa.agents.main.agent_callers": logging.INFO,
28+
"paperqa.agents.models": logging.WARNING,
29+
"paperqa.agents.search": logging.INFO,
30+
"anthropic": logging.WARNING,
31+
"openai": logging.WARNING,
32+
"httpx": logging.WARNING,
33+
"LiteLLM": logging.WARNING,
34+
"LiteLLM Router": logging.WARNING,
35+
"LiteLLM Proxy": logging.WARNING,
6236
}
63-
37+
}
38+
LOG_VERBOSITY_MAP[1] = LOG_VERBOSITY_MAP[0] | {
39+
"paperqa.models": logging.INFO,
40+
"paperqa.agents.main": logging.INFO,
41+
}
42+
LOG_VERBOSITY_MAP[2] = LOG_VERBOSITY_MAP[1] | {
43+
"paperqa.models": logging.DEBUG,
44+
"paperqa.agents.helpers": logging.DEBUG,
45+
"paperqa.agents.main": logging.DEBUG,
46+
"paperqa.agents.main.agent_callers": logging.DEBUG,
47+
"paperqa.agents.search": logging.DEBUG,
48+
"LiteLLM": logging.INFO,
49+
"LiteLLM Router": logging.INFO,
50+
"LiteLLM Proxy": logging.INFO,
51+
}
52+
LOG_VERBOSITY_MAP[3] = LOG_VERBOSITY_MAP[2] | {
53+
"LiteLLM": logging.DEBUG, # <-- every single LLM call
54+
}
55+
56+
_PAPERQA_ROOT_LOGGER = logging.getLogger(__name__.split(".", maxsplit=1)[0])
57+
58+
59+
def is_running_under_cli() -> bool:
60+
"""Check if the current Python process comes from the CLI."""
61+
return any(isinstance(h, RichHandler) for h in _PAPERQA_ROOT_LOGGER.handlers)
62+
63+
64+
def set_up_rich_handler() -> RichHandler:
65+
"""Add a RichHandler to the paper-qa "root" logger, and return it."""
6466
rich_handler = RichHandler(
6567
rich_tracebacks=True,
6668
markup=True,
6769
show_path=False,
6870
show_level=False,
6971
console=Console(force_terminal=True),
7072
)
71-
7273
rich_handler.setFormatter(logging.Formatter("%(message)s", datefmt="[%X]"))
74+
if not is_running_under_cli():
75+
_PAPERQA_ROOT_LOGGER.addHandler(rich_handler)
76+
return rich_handler
7377

74-
module_logger = logging.getLogger(__name__.split(".", maxsplit=1)[0])
7578

76-
if not any(isinstance(h, RichHandler) for h in module_logger.handlers):
77-
module_logger.addHandler(rich_handler)
79+
def configure_cli_logging(verbosity: int = 0) -> None:
80+
"""Suppress loquacious loggers according to verbosity level."""
81+
setup_default_logs()
82+
set_up_rich_handler()
7883

84+
max_preset_verbosity: int = max(list(LOG_VERBOSITY_MAP.keys()))
7985
for logger_name, logger_ in logging.Logger.manager.loggerDict.items():
8086
if isinstance(logger_, logging.Logger) and (
81-
log_level := verbosity_map.get(min(verbosity, 2), {}).get(logger_name)
87+
log_level := LOG_VERBOSITY_MAP.get(
88+
min(verbosity, max_preset_verbosity), {}
89+
).get(logger_name)
8290
):
8391
logger_.setLevel(log_level)
8492

0 commit comments

Comments
 (0)