Skip to content

Commit 248103b

Browse files
braisedpork1964wangzy
and
wangzy
authored
[Feat] Support message logging (#267)
* add a message logging hook * update * change the default logger name --------- Co-authored-by: wangzy <[email protected]>
1 parent 5dabf3d commit 248103b

File tree

6 files changed

+104
-13
lines changed

6 files changed

+104
-13
lines changed

lagent/agents/agent.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ def reset(self, session_id=0):
168168
if self.memory:
169169
self.memory.reset(session_id=session_id)
170170

171+
def __repr__(self):
172+
return f"{self.__class__.__name__}(name='{self.name}', description='{self.description or ''}')"
173+
171174

172175
class AsyncAgent(Agent):
173176

@@ -273,15 +276,15 @@ def _backup(d):
273276
setattr(cls, method, wrap_api(getattr(cls, method)))
274277

275278

276-
class AgentList(Agent, UserList, AgentContainerMixin):
279+
class AgentList(UserList, Agent, AgentContainerMixin):
277280

278281
def __init__(self,
279282
agents: Optional[Iterable[Union[Agent, AsyncAgent]]] = None):
280283
Agent.__init__(self, memory=None)
281284
UserList.__init__(self, agents)
282285

283286

284-
class AgentDict(Agent, UserDict, AgentContainerMixin):
287+
class AgentDict(UserDict, Agent, AgentContainerMixin):
285288

286289
def __init__(self,
287290
agents: Optional[Mapping[str, Union[Agent,

lagent/hooks/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from .action_preprocessor import ActionPreprocessor, InternLMActionProcessor
22
from .hook import Hook, RemovableHandle
3+
from .logger import MessageLogger
34

45
__all__ = [
5-
'Hook', 'RemovableHandle', 'ActionPreprocessor', 'InternLMActionProcessor'
6+
'Hook', 'RemovableHandle', 'ActionPreprocessor', 'InternLMActionProcessor',
7+
'MessageLogger'
68
]

lagent/hooks/hook.py

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,40 @@
11
from itertools import count
2+
from typing import Tuple
3+
4+
from lagent.schema import AgentMessage
25

36

47
class Hook:
58

69
def before_agent(
710
self,
811
agent,
9-
message,
10-
session_id,
12+
message: Tuple[AgentMessage],
13+
session_id: int,
1114
):
1215
pass
1316

1417
def after_agent(
1518
self,
1619
agent,
17-
message,
18-
session_id,
20+
message: AgentMessage,
21+
session_id: int,
1922
):
2023
pass
2124

2225
def before_action(
2326
self,
2427
executor,
25-
message,
26-
session_id,
28+
message: AgentMessage,
29+
session_id: int,
2730
):
2831
pass
2932

3033
def after_action(
3134
self,
3235
executor,
33-
message,
34-
session_id,
36+
message: AgentMessage,
37+
session_id: int,
3538
):
3639
pass
3740

lagent/hooks/logger.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import random
2+
from typing import Optional
3+
4+
from termcolor import COLORS, colored
5+
6+
from lagent.utils import get_logger
7+
from .hook import Hook
8+
9+
10+
class MessageLogger(Hook):
11+
12+
def __init__(self, name: str = 'lagent'):
13+
self.logger = get_logger(name, 'info')
14+
self.sender2color = {}
15+
16+
def before_agent(self, agent, messages, session_id):
17+
for message in messages:
18+
self._process_message(message, session_id)
19+
20+
def after_agent(self, agent, message, session_id):
21+
self._process_message(message, session_id)
22+
23+
def before_action(self, executor, message, session_id):
24+
self._process_message(message, session_id)
25+
26+
def after_action(self, executor, message, session_id):
27+
self._process_message(message, session_id)
28+
29+
def _process_message(self, message, session_id):
30+
sender = message.sender
31+
color = self.sender2color.setdefault(sender,
32+
random.choice(list(COLORS)))
33+
self.logger.info(
34+
colored(
35+
f'session id: {session_id}, message sender: {sender}\n'
36+
f'{message.content}', color))

lagent/utils/__init__.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
from .package import is_module_exist
2-
from .util import GeneratorWithReturn, async_as_completed, create_object, filter_suffix, load_class_from_string
2+
from .util import (
3+
GeneratorWithReturn,
4+
async_as_completed,
5+
create_object,
6+
filter_suffix,
7+
get_logger,
8+
load_class_from_string,
9+
)
310

411
__all__ = [
5-
'is_module_exist', 'filter_suffix', 'create_object',
12+
'is_module_exist', 'filter_suffix', 'create_object', 'get_logger',
613
'load_class_from_string', 'async_as_completed', 'GeneratorWithReturn'
714
]

lagent/utils/util.py

+40
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import asyncio
22
import importlib
33
import inspect
4+
import logging
5+
import os
6+
import os.path as osp
47
import sys
8+
import time
59
from functools import partial
10+
from logging.handlers import RotatingFileHandler
611
from typing import Any, Dict, Generator, Iterable, List, Optional, Union
712

813

@@ -87,6 +92,41 @@ def filter_suffix(response: Union[str, List[str]],
8792
return processed
8893

8994

95+
def get_logger(
96+
name: str = 'lagent',
97+
level: str = 'debug',
98+
fmt:
99+
str = '%(asctime)s %(levelname)8s %(filename)20s %(lineno)4s - %(message)s',
100+
add_file_handler: bool = False,
101+
log_dir: str = 'log',
102+
log_file: str = time.strftime('%Y-%m-%d.log', time.localtime()),
103+
max_bytes: int = 5 * 1024 * 1024,
104+
backup_count: int = 3,
105+
):
106+
logger = logging.getLogger(name)
107+
logger.propagate = False
108+
logger.setLevel(getattr(logging, level.upper(), logging.DEBUG))
109+
110+
formatter = logging.Formatter(fmt)
111+
console_handler = logging.StreamHandler()
112+
console_handler.setFormatter(formatter)
113+
logger.addHandler(console_handler)
114+
115+
if add_file_handler:
116+
if not osp.exists(log_dir):
117+
os.makedirs(log_dir)
118+
log_file_path = osp.join(log_dir, log_file)
119+
file_handler = RotatingFileHandler(
120+
log_file_path,
121+
maxBytes=max_bytes,
122+
backupCount=backup_count,
123+
encoding='utf-8')
124+
file_handler.setFormatter(formatter)
125+
logger.addHandler(file_handler)
126+
127+
return logger
128+
129+
90130
class GeneratorWithReturn:
91131
"""Generator wrapper to capture the return value."""
92132

0 commit comments

Comments
 (0)