Merge branch 'feat/quiet-llm' into 'dev'

feat: implemented extra log level for LLM token stream

See merge request ics/sp/2025/n25b/pepperplus-cb!37
This commit was merged in pull request #37.
This commit is contained in:
JobvAlewijk
2025-12-16 11:26:37 +00:00
4 changed files with 23 additions and 6 deletions

View File

@@ -3,6 +3,7 @@ version: 1
custom_levels: custom_levels:
OBSERVATION: 25 OBSERVATION: 25
ACTION: 26 ACTION: 26
LLM: 9
formatters: formatters:
# Console output # Console output
@@ -26,7 +27,7 @@ handlers:
stream: ext://sys.stdout stream: ext://sys.stdout
ui: ui:
class: zmq.log.handlers.PUBHandler class: zmq.log.handlers.PUBHandler
level: DEBUG level: LLM
formatter: json_experiment formatter: json_experiment
# Level of external libraries # Level of external libraries
@@ -36,5 +37,5 @@ root:
loggers: loggers:
control_backend: control_backend:
level: DEBUG level: LLM
handlers: [ui] handlers: [ui]

View File

@@ -125,7 +125,7 @@ class LLMAgent(BaseAgent):
full_message += token full_message += token
current_chunk += token current_chunk += token
self.logger.info( self.logger.llm(
"Received token: %s", "Received token: %s",
full_message, full_message,
extra={"reference": message_id}, # Used in the UI to update old logs extra={"reference": message_id}, # Used in the UI to update old logs

View File

@@ -4,6 +4,7 @@ import os
import yaml import yaml
import zmq import zmq
from zmq.log.handlers import PUBHandler
from control_backend.core.config import settings from control_backend.core.config import settings
@@ -51,15 +52,27 @@ def setup_logging(path: str = ".logging_config.yaml") -> None:
logging.warning(f"Could not load logging configuration: {e}") logging.warning(f"Could not load logging configuration: {e}")
config = {} config = {}
if "custom_levels" in config: custom_levels = config.get("custom_levels", {}) or {}
for level_name, level_num in config["custom_levels"].items(): for level_name, level_num in custom_levels.items():
add_logging_level(level_name, level_num) add_logging_level(level_name, level_num)
if config.get("handlers") is not None and config.get("handlers").get("ui"): if config.get("handlers") is not None and config.get("handlers").get("ui"):
pub_socket = zmq.Context.instance().socket(zmq.PUB) pub_socket = zmq.Context.instance().socket(zmq.PUB)
pub_socket.connect(settings.zmq_settings.internal_pub_address) pub_socket.connect(settings.zmq_settings.internal_pub_address)
config["handlers"]["ui"]["interface_or_socket"] = pub_socket config["handlers"]["ui"]["interface_or_socket"] = pub_socket
logging.config.dictConfig(config) logging.config.dictConfig(config)
# Patch ZMQ PUBHandler to know about custom levels
if custom_levels:
for logger_name in ("control_backend",):
logger = logging.getLogger(logger_name)
for handler in logger.handlers:
if isinstance(handler, PUBHandler):
# Use the INFO formatter as the default template
default_fmt = handler.formatters[logging.INFO]
for level_num in custom_levels.values():
handler.setFormatter(default_fmt, level=level_num)
else: else:
logging.warning("Logging config file not found. Using default logging configuration.") logging.warning("Logging config file not found. Using default logging configuration.")

View File

@@ -49,6 +49,9 @@ async def test_llm_processing_success(mock_httpx_client, mock_settings):
agent = LLMAgent("llm_agent") agent = LLMAgent("llm_agent")
agent.send = AsyncMock() # Mock the send method to verify replies agent.send = AsyncMock() # Mock the send method to verify replies
mock_logger = MagicMock()
agent.logger = mock_logger
# Simulate receiving a message from BDI # Simulate receiving a message from BDI
prompt = LLMPromptMessage(text="Hi", norms=[], goals=[]) prompt = LLMPromptMessage(text="Hi", norms=[], goals=[])
msg = InternalMessage( msg = InternalMessage(