AstrBot 4.13.1__py3-none-any.whl → 4.13.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- astrbot/builtin_stars/astrbot/process_llm_request.py +10 -2
- astrbot/cli/__init__.py +1 -1
- astrbot/core/__init__.py +2 -0
- astrbot/core/config/default.py +49 -1
- astrbot/core/core_lifecycle.py +7 -3
- astrbot/core/event_bus.py +1 -0
- astrbot/core/log.py +189 -1
- astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +20 -1
- astrbot/core/pipeline/scheduler.py +2 -0
- astrbot/core/platform/astr_message_event.py +17 -0
- astrbot/core/utils/trace.py +73 -0
- {astrbot-4.13.1.dist-info → astrbot-4.13.2.dist-info}/METADATA +1 -1
- {astrbot-4.13.1.dist-info → astrbot-4.13.2.dist-info}/RECORD +16 -15
- {astrbot-4.13.1.dist-info → astrbot-4.13.2.dist-info}/WHEEL +0 -0
- {astrbot-4.13.1.dist-info → astrbot-4.13.2.dist-info}/entry_points.txt +0 -0
- {astrbot-4.13.1.dist-info → astrbot-4.13.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -38,7 +38,12 @@ class ProcessLLMRequest:
|
|
|
38
38
|
req.func_tool.add_tool(LOCAL_PYTHON_TOOL)
|
|
39
39
|
|
|
40
40
|
async def _ensure_persona(
|
|
41
|
-
self,
|
|
41
|
+
self,
|
|
42
|
+
req: ProviderRequest,
|
|
43
|
+
cfg: dict,
|
|
44
|
+
umo: str,
|
|
45
|
+
platform_type: str,
|
|
46
|
+
event: AstrMessageEvent,
|
|
42
47
|
):
|
|
43
48
|
"""确保用户人格已加载"""
|
|
44
49
|
if not req.conversation:
|
|
@@ -121,6 +126,9 @@ class ProcessLLMRequest:
|
|
|
121
126
|
req.func_tool = toolset
|
|
122
127
|
else:
|
|
123
128
|
req.func_tool.merge(toolset)
|
|
129
|
+
event.trace.record(
|
|
130
|
+
"sel_persona", persona_id=persona_id, persona_toolset=toolset.names()
|
|
131
|
+
)
|
|
124
132
|
logger.debug(f"Tool set for persona {persona_id}: {toolset.names()}")
|
|
125
133
|
|
|
126
134
|
async def _ensure_img_caption(
|
|
@@ -225,7 +233,7 @@ class ProcessLLMRequest:
|
|
|
225
233
|
# inject persona for this request
|
|
226
234
|
platform_type = event.get_platform_name()
|
|
227
235
|
await self._ensure_persona(
|
|
228
|
-
req, cfg, event.unified_msg_origin, platform_type
|
|
236
|
+
req, cfg, event.unified_msg_origin, platform_type, event
|
|
229
237
|
)
|
|
230
238
|
|
|
231
239
|
# image caption
|
astrbot/cli/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "4.13.
|
|
1
|
+
__version__ = "4.13.2"
|
astrbot/core/__init__.py
CHANGED
|
@@ -20,6 +20,8 @@ astrbot_config = AstrBotConfig()
|
|
|
20
20
|
t2i_base_url = astrbot_config.get("t2i_endpoint", "https://t2i.soulter.top/text2img")
|
|
21
21
|
html_renderer = HtmlRenderer(t2i_base_url)
|
|
22
22
|
logger = LogManager.GetLogger(log_name="astrbot")
|
|
23
|
+
LogManager.configure_logger(logger, astrbot_config)
|
|
24
|
+
LogManager.configure_trace_logger(astrbot_config)
|
|
23
25
|
db_helper = SQLiteDatabase(DB_PATH)
|
|
24
26
|
# 简单的偏好设置存储, 这里后续应该存储到数据库中, 一些部分可以存储到配置中
|
|
25
27
|
sp = SharedPreferences(db_helper=db_helper)
|
astrbot/core/config/default.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Any, TypedDict
|
|
|
5
5
|
|
|
6
6
|
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
|
7
7
|
|
|
8
|
-
VERSION = "4.13.
|
|
8
|
+
VERSION = "4.13.2"
|
|
9
9
|
DB_PATH = os.path.join(get_astrbot_data_path(), "data_v4.db")
|
|
10
10
|
|
|
11
11
|
WEBHOOK_SUPPORTED_PLATFORMS = [
|
|
@@ -182,6 +182,12 @@ DEFAULT_CONFIG = {
|
|
|
182
182
|
},
|
|
183
183
|
"wake_prefix": ["/"],
|
|
184
184
|
"log_level": "INFO",
|
|
185
|
+
"log_file_enable": False,
|
|
186
|
+
"log_file_path": "logs/astrbot.log",
|
|
187
|
+
"log_file_max_mb": 20,
|
|
188
|
+
"trace_log_enable": False,
|
|
189
|
+
"trace_log_path": "logs/astrbot.trace.log",
|
|
190
|
+
"trace_log_max_mb": 20,
|
|
185
191
|
"pip_install_arg": "",
|
|
186
192
|
"pypi_index_url": "https://mirrors.aliyun.com/pypi/simple/",
|
|
187
193
|
"persona": [], # deprecated
|
|
@@ -2321,6 +2327,18 @@ CONFIG_METADATA_2 = {
|
|
|
2321
2327
|
"type": "string",
|
|
2322
2328
|
"options": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
2323
2329
|
},
|
|
2330
|
+
"log_file_enable": {"type": "bool"},
|
|
2331
|
+
"log_file_path": {"type": "string", "condition": {"log_file_enable": True}},
|
|
2332
|
+
"log_file_max_mb": {"type": "int", "condition": {"log_file_enable": True}},
|
|
2333
|
+
"trace_log_enable": {"type": "bool"},
|
|
2334
|
+
"trace_log_path": {
|
|
2335
|
+
"type": "string",
|
|
2336
|
+
"condition": {"trace_log_enable": True},
|
|
2337
|
+
},
|
|
2338
|
+
"trace_log_max_mb": {
|
|
2339
|
+
"type": "int",
|
|
2340
|
+
"condition": {"trace_log_enable": True},
|
|
2341
|
+
},
|
|
2324
2342
|
"t2i_strategy": {
|
|
2325
2343
|
"type": "string",
|
|
2326
2344
|
"options": ["remote", "local"],
|
|
@@ -3253,6 +3271,36 @@ CONFIG_METADATA_3_SYSTEM = {
|
|
|
3253
3271
|
"hint": "控制台输出日志的级别。",
|
|
3254
3272
|
"options": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
3255
3273
|
},
|
|
3274
|
+
"log_file_enable": {
|
|
3275
|
+
"description": "启用文件日志",
|
|
3276
|
+
"type": "bool",
|
|
3277
|
+
"hint": "开启后会将日志写入指定文件。",
|
|
3278
|
+
},
|
|
3279
|
+
"log_file_path": {
|
|
3280
|
+
"description": "日志文件路径",
|
|
3281
|
+
"type": "string",
|
|
3282
|
+
"hint": "相对路径以 data 目录为基准,例如 logs/astrbot.log;支持绝对路径。",
|
|
3283
|
+
},
|
|
3284
|
+
"log_file_max_mb": {
|
|
3285
|
+
"description": "日志文件大小上限 (MB)",
|
|
3286
|
+
"type": "int",
|
|
3287
|
+
"hint": "超过大小后自动轮转,默认 20MB。",
|
|
3288
|
+
},
|
|
3289
|
+
"trace_log_enable": {
|
|
3290
|
+
"description": "启用 Trace 文件日志",
|
|
3291
|
+
"type": "bool",
|
|
3292
|
+
"hint": "将 Trace 事件写入独立文件(不影响控制台输出)。",
|
|
3293
|
+
},
|
|
3294
|
+
"trace_log_path": {
|
|
3295
|
+
"description": "Trace 日志文件路径",
|
|
3296
|
+
"type": "string",
|
|
3297
|
+
"hint": "相对路径以 data 目录为基准,例如 logs/astrbot.trace.log;支持绝对路径。",
|
|
3298
|
+
},
|
|
3299
|
+
"trace_log_max_mb": {
|
|
3300
|
+
"description": "Trace 日志大小上限 (MB)",
|
|
3301
|
+
"type": "int",
|
|
3302
|
+
"hint": "超过大小后自动轮转,默认 20MB。",
|
|
3303
|
+
},
|
|
3256
3304
|
"pip_install_arg": {
|
|
3257
3305
|
"description": "pip 安装额外参数",
|
|
3258
3306
|
"type": "string",
|
astrbot/core/core_lifecycle.py
CHANGED
|
@@ -17,7 +17,7 @@ import traceback
|
|
|
17
17
|
from asyncio import Queue
|
|
18
18
|
|
|
19
19
|
from astrbot.api import logger, sp
|
|
20
|
-
from astrbot.core import LogBroker
|
|
20
|
+
from astrbot.core import LogBroker, LogManager
|
|
21
21
|
from astrbot.core.astrbot_config_mgr import AstrBotConfigManager
|
|
22
22
|
from astrbot.core.config.default import VERSION
|
|
23
23
|
from astrbot.core.conversation_mgr import ConversationManager
|
|
@@ -80,9 +80,13 @@ class AstrBotCoreLifecycle:
|
|
|
80
80
|
# 初始化日志代理
|
|
81
81
|
logger.info("AstrBot v" + VERSION)
|
|
82
82
|
if os.environ.get("TESTING", ""):
|
|
83
|
-
|
|
83
|
+
LogManager.configure_logger(
|
|
84
|
+
logger, self.astrbot_config, override_level="DEBUG"
|
|
85
|
+
)
|
|
86
|
+
LogManager.configure_trace_logger(self.astrbot_config)
|
|
84
87
|
else:
|
|
85
|
-
|
|
88
|
+
LogManager.configure_logger(logger, self.astrbot_config)
|
|
89
|
+
LogManager.configure_trace_logger(self.astrbot_config)
|
|
86
90
|
|
|
87
91
|
await self.db.initialize()
|
|
88
92
|
|
astrbot/core/event_bus.py
CHANGED
astrbot/core/log.py
CHANGED
|
@@ -27,13 +27,15 @@ import sys
|
|
|
27
27
|
import time
|
|
28
28
|
from asyncio import Queue
|
|
29
29
|
from collections import deque
|
|
30
|
+
from logging.handlers import RotatingFileHandler
|
|
30
31
|
|
|
31
32
|
import colorlog
|
|
32
33
|
|
|
33
34
|
from astrbot.core.config.default import VERSION
|
|
35
|
+
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
|
34
36
|
|
|
35
37
|
# 日志缓存大小
|
|
36
|
-
CACHED_SIZE =
|
|
38
|
+
CACHED_SIZE = 500
|
|
37
39
|
# 日志颜色配置
|
|
38
40
|
log_color_config = {
|
|
39
41
|
"DEBUG": "green",
|
|
@@ -163,6 +165,9 @@ class LogManager:
|
|
|
163
165
|
提供了获取默认日志记录器logger和设置队列处理器的方法
|
|
164
166
|
"""
|
|
165
167
|
|
|
168
|
+
_FILE_HANDLER_FLAG = "_astrbot_file_handler"
|
|
169
|
+
_TRACE_FILE_HANDLER_FLAG = "_astrbot_trace_file_handler"
|
|
170
|
+
|
|
166
171
|
@classmethod
|
|
167
172
|
def GetLogger(cls, log_name: str = "default"):
|
|
168
173
|
"""获取指定名称的日志记录器logger
|
|
@@ -266,3 +271,186 @@ class LogManager:
|
|
|
266
271
|
),
|
|
267
272
|
)
|
|
268
273
|
logger.addHandler(handler)
|
|
274
|
+
|
|
275
|
+
@classmethod
|
|
276
|
+
def _default_log_path(cls) -> str:
|
|
277
|
+
return os.path.join(get_astrbot_data_path(), "logs", "astrbot.log")
|
|
278
|
+
|
|
279
|
+
@classmethod
|
|
280
|
+
def _resolve_log_path(cls, configured_path: str | None) -> str:
|
|
281
|
+
if not configured_path:
|
|
282
|
+
return cls._default_log_path()
|
|
283
|
+
if os.path.isabs(configured_path):
|
|
284
|
+
return configured_path
|
|
285
|
+
return os.path.join(get_astrbot_data_path(), configured_path)
|
|
286
|
+
|
|
287
|
+
@classmethod
|
|
288
|
+
def _get_file_handlers(cls, logger: logging.Logger) -> list[logging.Handler]:
|
|
289
|
+
return [
|
|
290
|
+
handler
|
|
291
|
+
for handler in logger.handlers
|
|
292
|
+
if getattr(handler, cls._FILE_HANDLER_FLAG, False)
|
|
293
|
+
]
|
|
294
|
+
|
|
295
|
+
@classmethod
|
|
296
|
+
def _get_trace_file_handlers(cls, logger: logging.Logger) -> list[logging.Handler]:
|
|
297
|
+
return [
|
|
298
|
+
handler
|
|
299
|
+
for handler in logger.handlers
|
|
300
|
+
if getattr(handler, cls._TRACE_FILE_HANDLER_FLAG, False)
|
|
301
|
+
]
|
|
302
|
+
|
|
303
|
+
@classmethod
|
|
304
|
+
def _remove_file_handlers(cls, logger: logging.Logger):
|
|
305
|
+
for handler in cls._get_file_handlers(logger):
|
|
306
|
+
logger.removeHandler(handler)
|
|
307
|
+
try:
|
|
308
|
+
handler.close()
|
|
309
|
+
except Exception:
|
|
310
|
+
pass
|
|
311
|
+
|
|
312
|
+
@classmethod
|
|
313
|
+
def _remove_trace_file_handlers(cls, logger: logging.Logger):
|
|
314
|
+
for handler in cls._get_trace_file_handlers(logger):
|
|
315
|
+
logger.removeHandler(handler)
|
|
316
|
+
try:
|
|
317
|
+
handler.close()
|
|
318
|
+
except Exception:
|
|
319
|
+
pass
|
|
320
|
+
|
|
321
|
+
@classmethod
|
|
322
|
+
def _add_file_handler(
|
|
323
|
+
cls,
|
|
324
|
+
logger: logging.Logger,
|
|
325
|
+
file_path: str,
|
|
326
|
+
max_mb: int | None = None,
|
|
327
|
+
backup_count: int = 3,
|
|
328
|
+
trace: bool = False,
|
|
329
|
+
):
|
|
330
|
+
os.makedirs(os.path.dirname(file_path) or ".", exist_ok=True)
|
|
331
|
+
max_bytes = 0
|
|
332
|
+
if max_mb and max_mb > 0:
|
|
333
|
+
max_bytes = max_mb * 1024 * 1024
|
|
334
|
+
if max_bytes > 0:
|
|
335
|
+
file_handler = RotatingFileHandler(
|
|
336
|
+
file_path,
|
|
337
|
+
maxBytes=max_bytes,
|
|
338
|
+
backupCount=backup_count,
|
|
339
|
+
encoding="utf-8",
|
|
340
|
+
)
|
|
341
|
+
else:
|
|
342
|
+
file_handler = logging.FileHandler(file_path, encoding="utf-8")
|
|
343
|
+
file_handler.setLevel(logger.level)
|
|
344
|
+
if trace:
|
|
345
|
+
formatter = logging.Formatter(
|
|
346
|
+
"[%(asctime)s] %(message)s",
|
|
347
|
+
datefmt="%Y-%m-%d %H:%M:%S",
|
|
348
|
+
)
|
|
349
|
+
else:
|
|
350
|
+
formatter = logging.Formatter(
|
|
351
|
+
"[%(asctime)s] %(plugin_tag)s [%(short_levelname)s]%(astrbot_version_tag)s [%(filename)s:%(lineno)d]: %(message)s",
|
|
352
|
+
datefmt="%Y-%m-%d %H:%M:%S",
|
|
353
|
+
)
|
|
354
|
+
file_handler.setFormatter(formatter)
|
|
355
|
+
setattr(
|
|
356
|
+
file_handler,
|
|
357
|
+
cls._TRACE_FILE_HANDLER_FLAG if trace else cls._FILE_HANDLER_FLAG,
|
|
358
|
+
True,
|
|
359
|
+
)
|
|
360
|
+
logger.addHandler(file_handler)
|
|
361
|
+
|
|
362
|
+
@classmethod
|
|
363
|
+
def configure_logger(
|
|
364
|
+
cls,
|
|
365
|
+
logger: logging.Logger,
|
|
366
|
+
config: dict | None,
|
|
367
|
+
override_level: str | None = None,
|
|
368
|
+
):
|
|
369
|
+
"""根据配置设置日志级别和文件日志。
|
|
370
|
+
|
|
371
|
+
Args:
|
|
372
|
+
logger: 需要配置的 logger
|
|
373
|
+
config: 配置字典
|
|
374
|
+
override_level: 若提供,将覆盖配置中的日志级别
|
|
375
|
+
"""
|
|
376
|
+
if not config:
|
|
377
|
+
return
|
|
378
|
+
|
|
379
|
+
level = override_level or config.get("log_level")
|
|
380
|
+
if level:
|
|
381
|
+
try:
|
|
382
|
+
logger.setLevel(level)
|
|
383
|
+
except Exception:
|
|
384
|
+
logger.setLevel(logging.INFO)
|
|
385
|
+
|
|
386
|
+
# 兼容旧版嵌套配置
|
|
387
|
+
if "log_file" in config:
|
|
388
|
+
file_conf = config.get("log_file") or {}
|
|
389
|
+
enable_file = bool(file_conf.get("enable", False))
|
|
390
|
+
file_path = file_conf.get("path")
|
|
391
|
+
max_mb = file_conf.get("max_mb")
|
|
392
|
+
else:
|
|
393
|
+
enable_file = bool(config.get("log_file_enable", False))
|
|
394
|
+
file_path = config.get("log_file_path")
|
|
395
|
+
max_mb = config.get("log_file_max_mb")
|
|
396
|
+
|
|
397
|
+
file_path = cls._resolve_log_path(file_path)
|
|
398
|
+
|
|
399
|
+
existing = cls._get_file_handlers(logger)
|
|
400
|
+
if not enable_file:
|
|
401
|
+
cls._remove_file_handlers(logger)
|
|
402
|
+
return
|
|
403
|
+
|
|
404
|
+
# 如果已有文件处理器且路径一致,则仅同步级别
|
|
405
|
+
if existing:
|
|
406
|
+
handler = existing[0]
|
|
407
|
+
base = getattr(handler, "baseFilename", "")
|
|
408
|
+
if base and os.path.abspath(base) == os.path.abspath(file_path):
|
|
409
|
+
handler.setLevel(logger.level)
|
|
410
|
+
return
|
|
411
|
+
cls._remove_file_handlers(logger)
|
|
412
|
+
|
|
413
|
+
cls._add_file_handler(logger, file_path, max_mb=max_mb)
|
|
414
|
+
|
|
415
|
+
@classmethod
|
|
416
|
+
def configure_trace_logger(cls, config: dict | None):
|
|
417
|
+
"""为 trace 事件配置独立的文件日志,不向控制台输出。"""
|
|
418
|
+
if not config:
|
|
419
|
+
return
|
|
420
|
+
|
|
421
|
+
enable = bool(
|
|
422
|
+
config.get("trace_log_enable")
|
|
423
|
+
or (config.get("log_file", {}) or {}).get("trace_enable", False)
|
|
424
|
+
)
|
|
425
|
+
path = config.get("trace_log_path")
|
|
426
|
+
max_mb = config.get("trace_log_max_mb")
|
|
427
|
+
if "log_file" in config:
|
|
428
|
+
legacy = config.get("log_file") or {}
|
|
429
|
+
path = path or legacy.get("trace_path")
|
|
430
|
+
max_mb = max_mb or legacy.get("trace_max_mb")
|
|
431
|
+
|
|
432
|
+
if not enable:
|
|
433
|
+
trace_logger = logging.getLogger("astrbot.trace")
|
|
434
|
+
cls._remove_trace_file_handlers(trace_logger)
|
|
435
|
+
return
|
|
436
|
+
|
|
437
|
+
file_path = cls._resolve_log_path(path or "logs/astrbot.trace.log")
|
|
438
|
+
trace_logger = logging.getLogger("astrbot.trace")
|
|
439
|
+
trace_logger.setLevel(logging.INFO)
|
|
440
|
+
trace_logger.propagate = False
|
|
441
|
+
|
|
442
|
+
existing = cls._get_trace_file_handlers(trace_logger)
|
|
443
|
+
if existing:
|
|
444
|
+
handler = existing[0]
|
|
445
|
+
base = getattr(handler, "baseFilename", "")
|
|
446
|
+
if base and os.path.abspath(base) == os.path.abspath(file_path):
|
|
447
|
+
handler.setLevel(trace_logger.level)
|
|
448
|
+
return
|
|
449
|
+
cls._remove_trace_file_handlers(trace_logger)
|
|
450
|
+
|
|
451
|
+
cls._add_file_handler(
|
|
452
|
+
trace_logger,
|
|
453
|
+
file_path,
|
|
454
|
+
max_mb=max_mb,
|
|
455
|
+
trace=True,
|
|
456
|
+
)
|
|
@@ -692,6 +692,17 @@ class InternalAgentSubStage(Stage):
|
|
|
692
692
|
if action_type == "live":
|
|
693
693
|
req.system_prompt += f"\n{LIVE_MODE_SYSTEM_PROMPT}\n"
|
|
694
694
|
|
|
695
|
+
event.trace.record(
|
|
696
|
+
"astr_agent_prepare",
|
|
697
|
+
system_prompt=req.system_prompt,
|
|
698
|
+
tools=req.func_tool.names() if req.func_tool else [],
|
|
699
|
+
stream=streaming_response,
|
|
700
|
+
chat_provider={
|
|
701
|
+
"id": provider.provider_config.get("id", ""),
|
|
702
|
+
"model": provider.get_model(),
|
|
703
|
+
},
|
|
704
|
+
)
|
|
705
|
+
|
|
695
706
|
await agent_runner.reset(
|
|
696
707
|
provider=provider,
|
|
697
708
|
request=req,
|
|
@@ -796,12 +807,20 @@ class InternalAgentSubStage(Stage):
|
|
|
796
807
|
):
|
|
797
808
|
yield
|
|
798
809
|
|
|
810
|
+
final_resp = agent_runner.get_final_llm_resp()
|
|
811
|
+
|
|
812
|
+
event.trace.record(
|
|
813
|
+
"astr_agent_complete",
|
|
814
|
+
stats=agent_runner.stats.to_dict(),
|
|
815
|
+
resp=final_resp.completion_text if final_resp else None,
|
|
816
|
+
)
|
|
817
|
+
|
|
799
818
|
# 检查事件是否被停止,如果被停止则不保存历史记录
|
|
800
819
|
if not event.is_stopped():
|
|
801
820
|
await self._save_to_history(
|
|
802
821
|
event,
|
|
803
822
|
req,
|
|
804
|
-
|
|
823
|
+
final_resp,
|
|
805
824
|
agent_runner.run_context.messages,
|
|
806
825
|
agent_runner.stats,
|
|
807
826
|
)
|
|
@@ -4,6 +4,7 @@ import hashlib
|
|
|
4
4
|
import re
|
|
5
5
|
import uuid
|
|
6
6
|
from collections.abc import AsyncGenerator
|
|
7
|
+
from time import time
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
9
10
|
from astrbot import logger
|
|
@@ -22,6 +23,7 @@ from astrbot.core.message.message_event_result import MessageChain, MessageEvent
|
|
|
22
23
|
from astrbot.core.platform.message_type import MessageType
|
|
23
24
|
from astrbot.core.provider.entities import ProviderRequest
|
|
24
25
|
from astrbot.core.utils.metrics import Metric
|
|
26
|
+
from astrbot.core.utils.trace import TraceSpan
|
|
25
27
|
|
|
26
28
|
from .astrbot_message import AstrBotMessage, Group
|
|
27
29
|
from .message_session import MessageSesion, MessageSession # noqa
|
|
@@ -59,6 +61,21 @@ class AstrMessageEvent(abc.ABC):
|
|
|
59
61
|
self._result: MessageEventResult | None = None
|
|
60
62
|
"""消息事件的结果"""
|
|
61
63
|
|
|
64
|
+
self.created_at = time()
|
|
65
|
+
"""事件创建时间(Unix timestamp)"""
|
|
66
|
+
self.trace = TraceSpan(
|
|
67
|
+
name="AstrMessageEvent",
|
|
68
|
+
umo=self.unified_msg_origin,
|
|
69
|
+
sender_name=self.get_sender_name(),
|
|
70
|
+
message_outline=self.get_message_outline(),
|
|
71
|
+
)
|
|
72
|
+
"""用于记录事件处理的 TraceSpan 对象"""
|
|
73
|
+
self.span = self.trace
|
|
74
|
+
"""事件级 TraceSpan(别名: span)"""
|
|
75
|
+
|
|
76
|
+
self.trace.record("umo", umo=self.unified_msg_origin)
|
|
77
|
+
self.trace.record("event_created", created_at=self.created_at)
|
|
78
|
+
|
|
62
79
|
self._has_send_oper = False
|
|
63
80
|
"""在此次事件中是否有过至少一次发送消息的操作"""
|
|
64
81
|
self.call_llm = False
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import time
|
|
4
|
+
import uuid
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from astrbot import logger
|
|
8
|
+
from astrbot.core import LogManager, astrbot_config
|
|
9
|
+
from astrbot.core.log import LogQueueHandler
|
|
10
|
+
|
|
11
|
+
_cached_log_broker = None
|
|
12
|
+
_trace_logger = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_log_broker():
|
|
16
|
+
global _cached_log_broker
|
|
17
|
+
if _cached_log_broker is not None:
|
|
18
|
+
return _cached_log_broker
|
|
19
|
+
for handler in logger.handlers:
|
|
20
|
+
if isinstance(handler, LogQueueHandler):
|
|
21
|
+
_cached_log_broker = handler.log_broker
|
|
22
|
+
return _cached_log_broker
|
|
23
|
+
return None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _get_trace_logger():
|
|
27
|
+
global _trace_logger
|
|
28
|
+
if _trace_logger is not None:
|
|
29
|
+
return _trace_logger
|
|
30
|
+
|
|
31
|
+
# 按配置初始化 trace 文件日志
|
|
32
|
+
LogManager.configure_trace_logger(astrbot_config)
|
|
33
|
+
_trace_logger = logging.getLogger("astrbot.trace")
|
|
34
|
+
return _trace_logger
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class TraceSpan:
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
name: str,
|
|
41
|
+
umo: str | None = None,
|
|
42
|
+
sender_name: str | None = None,
|
|
43
|
+
message_outline: str | None = None,
|
|
44
|
+
) -> None:
|
|
45
|
+
self.span_id = str(uuid.uuid4())
|
|
46
|
+
self.name = name
|
|
47
|
+
self.umo = umo
|
|
48
|
+
self.sender_name = sender_name
|
|
49
|
+
self.message_outline = message_outline
|
|
50
|
+
self.started_at = time.time()
|
|
51
|
+
|
|
52
|
+
def record(self, action: str, **fields: Any) -> None:
|
|
53
|
+
payload = {
|
|
54
|
+
"type": "trace",
|
|
55
|
+
"level": "TRACE",
|
|
56
|
+
"time": time.time(),
|
|
57
|
+
"span_id": self.span_id,
|
|
58
|
+
"name": self.name,
|
|
59
|
+
"umo": self.umo,
|
|
60
|
+
"sender_name": self.sender_name,
|
|
61
|
+
"message_outline": self.message_outline,
|
|
62
|
+
"action": action,
|
|
63
|
+
"fields": fields,
|
|
64
|
+
}
|
|
65
|
+
log_broker = _get_log_broker()
|
|
66
|
+
if log_broker:
|
|
67
|
+
log_broker.publish(payload)
|
|
68
|
+
else:
|
|
69
|
+
logger.info(f"[trace] {payload}")
|
|
70
|
+
|
|
71
|
+
trace_logger = _get_trace_logger()
|
|
72
|
+
if trace_logger and trace_logger.handlers:
|
|
73
|
+
trace_logger.info(json.dumps(payload, ensure_ascii=False))
|
|
@@ -11,7 +11,7 @@ astrbot/api/util/__init__.py,sha256=L1O_mFEUDk8V4lEPsT5iiNbIiOVh7HbrNmitqzUWMZg,
|
|
|
11
11
|
astrbot/builtin_stars/astrbot/long_term_memory.py,sha256=Gra7dqiqXLBH_u4M6TZmu49lxiolotbDNTwbh2aVTiA,7676
|
|
12
12
|
astrbot/builtin_stars/astrbot/main.py,sha256=KmiWqfQ1E7VR0Grf4jnO8d5_8tJJINbmFceAQ0FPeMU,4864
|
|
13
13
|
astrbot/builtin_stars/astrbot/metadata.yaml,sha256=GCPK0piMKr4C6Bb0kaBJYhiqPDoMEAYJJp2MV5pXs4k,197
|
|
14
|
-
astrbot/builtin_stars/astrbot/process_llm_request.py,sha256=
|
|
14
|
+
astrbot/builtin_stars/astrbot/process_llm_request.py,sha256=AMGlUWfyJM4c0Ed2F7vZCdFG_RmBmT0mThLxXUcpONQ,12479
|
|
15
15
|
astrbot/builtin_stars/builtin_commands/main.py,sha256=T8bNer22YgFkKZbLn9Zl-5Y1SIbKpQe_HvDJpUiyte4,7613
|
|
16
16
|
astrbot/builtin_stars/builtin_commands/metadata.yaml,sha256=x0URUKI3S14RRXQ-ewgJy4dYXMKxZcEo2pSKeApGleg,152
|
|
17
17
|
astrbot/builtin_stars/builtin_commands/commands/__init__.py,sha256=jHIh8Dg5EX5FcyWCEey-z84-iPVSBEamIYwhR75c4Rk,705
|
|
@@ -37,7 +37,7 @@ astrbot/builtin_stars/web_searcher/metadata.yaml,sha256=aHAKtP8UZJaddzIN2eFfglTO
|
|
|
37
37
|
astrbot/builtin_stars/web_searcher/engines/__init__.py,sha256=Gcp7k6m3w2Pb-hNCe3QIiYa9smQFcEzmb7jcfg2evuw,4300
|
|
38
38
|
astrbot/builtin_stars/web_searcher/engines/bing.py,sha256=pn3DPR-5SO2D_RtBIU3l9Ph7PTUB-FCZAMCYuk6kd6Q,1035
|
|
39
39
|
astrbot/builtin_stars/web_searcher/engines/sogo.py,sha256=YA7pA5-335r7UgKpyUPAeGGZQbYEwDBO8bm08Ro8Xg0,1701
|
|
40
|
-
astrbot/cli/__init__.py,sha256=
|
|
40
|
+
astrbot/cli/__init__.py,sha256=idpNMtxDYUTjhrcN9xIi-wIuzZpWEdWrn5pYd6O3qvE,23
|
|
41
41
|
astrbot/cli/__main__.py,sha256=QobgMyFoLNTgI_OYddhGOZ9ZvQeBVjjz79mA2cC2OEU,1758
|
|
42
42
|
astrbot/cli/commands/__init__.py,sha256=eAgppZQIqFO1ylQJFABeYrzQ0oZqPWjtE80aKIPB3ks,149
|
|
43
43
|
astrbot/cli/commands/cmd_conf.py,sha256=6-YLicBt_zjWTzaVLUJ1VQLQPbDEPYACB9IVnN8Zvng,6330
|
|
@@ -48,19 +48,19 @@ astrbot/cli/utils/__init__.py,sha256=Mo9646QOR9VOael2XL22CJK0OiifXRB7zu0vLJc9abY
|
|
|
48
48
|
astrbot/cli/utils/basic.py,sha256=-sjbBl0YfF-gt1jvkVyddBk-OWXIVpfG6JcF0DqOLZA,2682
|
|
49
49
|
astrbot/cli/utils/plugin.py,sha256=FdLVcDHH5dBpoBhLC6iWriUomp_5ONGlWNJnOG4ZOnM,8666
|
|
50
50
|
astrbot/cli/utils/version_comparator.py,sha256=NVUmshfb5LU4a-S453rI7opqo0QtIHvlT1KUD3pdoVM,3462
|
|
51
|
-
astrbot/core/__init__.py,sha256=
|
|
51
|
+
astrbot/core/__init__.py,sha256=ckFl_Qb7fYkYBpqB6DmWmw521_6yyub5w4N116hFEUc,1322
|
|
52
52
|
astrbot/core/astr_agent_context.py,sha256=bJnAm_CGzkhMnC99GA_j0Xwmi-OYoBPmgGanuS36DF4,637
|
|
53
53
|
astrbot/core/astr_agent_hooks.py,sha256=FTCQqhl-N8b163nxoPeoyfqhSGCG0bcAmnF1dAHMOm8,3020
|
|
54
54
|
astrbot/core/astr_agent_run_util.py,sha256=kPlWu2nLXfJzZddbtuoca0iZph9VRTJgdC9cLQf5UCQ,13592
|
|
55
55
|
astrbot/core/astr_agent_tool_exec.py,sha256=VPCJqVK4Teyrg8UgvUywtwKfLbJ29dZ0bj-NTNYzdmQ,10256
|
|
56
56
|
astrbot/core/astrbot_config_mgr.py,sha256=SUvusfo8Qk89eNpEmduWcXuczJ9g5TBH-VOV69ax28g,8950
|
|
57
57
|
astrbot/core/conversation_mgr.py,sha256=iELU-454tCOFRVs0DwJLZvx59mUSD55TYLlCVTEccyQ,15968
|
|
58
|
-
astrbot/core/core_lifecycle.py,sha256=
|
|
59
|
-
astrbot/core/event_bus.py,sha256=
|
|
58
|
+
astrbot/core/core_lifecycle.py,sha256=vRCtvRoh2yRcwVVnQVzpD7Ld9cFTEhaErgLaJUt7qOg,13018
|
|
59
|
+
astrbot/core/event_bus.py,sha256=hKF_fWEvIWB4RukqqTW6xda2ZbUzdaPFrOsUXUjiy8A,2797
|
|
60
60
|
astrbot/core/exceptions.py,sha256=GVCUgAjpvUHLL59MkJalFrSp_HbtliChu7XII_Px2WM,219
|
|
61
61
|
astrbot/core/file_token_service.py,sha256=8X0Qyo-NPGhtxy6IcRsJg7Z2tx_ULPf_7OKvw-KBk6o,3317
|
|
62
62
|
astrbot/core/initial_loader.py,sha256=q798G8wEti7-p3UC0y1GB3MOK-kO6z1Nt826iO5nJVA,1802
|
|
63
|
-
astrbot/core/log.py,sha256=
|
|
63
|
+
astrbot/core/log.py,sha256=b6xnedhtAAHSNza3KxytOv0T0o2uhPxNDBW2wtc9xOo,15570
|
|
64
64
|
astrbot/core/persona_mgr.py,sha256=whlJNS5FiFGZ8CwLBoJGVcWr3ZuLeZx3h6OB4YI17e0,12883
|
|
65
65
|
astrbot/core/platform_message_history_mgr.py,sha256=0frxrq6Bt18OXbt24uRnQl039wpi2gK5L9ONLtBuMsM,1580
|
|
66
66
|
astrbot/core/umop_config_router.py,sha256=K1Ya1Ke5iTZgrxgRp7VEiREAI2BcSGYeM3Os_05dUkE,3733
|
|
@@ -107,7 +107,7 @@ astrbot/core/computer/tools/python.py,sha256=E6-eRarOjE6AhYioOj5gZhfn10S3fC8uHjO
|
|
|
107
107
|
astrbot/core/computer/tools/shell.py,sha256=b2RWis65YJtUZHhmsLZI1L1LRvnfMlsZcXL4KPbqq_s,2211
|
|
108
108
|
astrbot/core/config/__init__.py,sha256=vZjtpC7vr-IvBgSUtbS04C0wpulmCG5tPmcEP1WYE_4,172
|
|
109
109
|
astrbot/core/config/astrbot_config.py,sha256=5r2VhCNO4VuGCqct12g10-TcvAKyXV40-suk5vRMGns,6436
|
|
110
|
-
astrbot/core/config/default.py,sha256=
|
|
110
|
+
astrbot/core/config/default.py,sha256=pd0QGJWF6tUi7toj0tG7ghrCCpXB0qYJAQ95aDx5Vyo,162833
|
|
111
111
|
astrbot/core/config/i18n_utils.py,sha256=HJn_0XeeVS9ryCBelYfnc0nEn10LlX702fcSSFrF1J8,3879
|
|
112
112
|
astrbot/core/db/__init__.py,sha256=ldEFdHkuQn_WpSNEC9X6knfthF2lD5YYLLZD4phwtdg,18515
|
|
113
113
|
astrbot/core/db/po.py,sha256=qGS8X2oXc1BWQCXHxqroBr9PhYCtXS6Of4Msm7NvMpI,13786
|
|
@@ -151,7 +151,7 @@ astrbot/core/message/message_event_result.py,sha256=1jC6NLeO7lzcTCi2NO28057sWpTs
|
|
|
151
151
|
astrbot/core/pipeline/__init__.py,sha256=nEepE3tnYYo0EYnzdLLyrp_k7XYg0LpQ3W6QuEeGL6k,1461
|
|
152
152
|
astrbot/core/pipeline/context.py,sha256=jfEyX9i34XM7uqeqqK6rKRDgBXfsV9UHgRpf9Wj_hnI,505
|
|
153
153
|
astrbot/core/pipeline/context_utils.py,sha256=Fvx_f7zi0VhgKCM3jBPhvB3V74oBc7m_KQdAeCKqvPo,3661
|
|
154
|
-
astrbot/core/pipeline/scheduler.py,sha256=
|
|
154
|
+
astrbot/core/pipeline/scheduler.py,sha256=iE9bsrv9ux4nSS-zexrKmm3djZaqcaSruMV86Pe19-Q,3538
|
|
155
155
|
astrbot/core/pipeline/stage.py,sha256=hpzghbberezaBJtb2cwhY8x0xi6lZrgWfD2BYv-te1g,1350
|
|
156
156
|
astrbot/core/pipeline/content_safety_check/stage.py,sha256=wzHadhasKyYswVXfRJ_8My6S3mo_0Xjm6DF95TxD57g,1389
|
|
157
157
|
astrbot/core/pipeline/content_safety_check/strategies/__init__.py,sha256=47gYlyvW-Dr401fO0dMAAAmMXnSkTI63MnYak3GGvNw,164
|
|
@@ -163,7 +163,7 @@ astrbot/core/pipeline/process_stage/stage.py,sha256=tOg6HYGVU1GoY921YBYVO1MTM7a5
|
|
|
163
163
|
astrbot/core/pipeline/process_stage/utils.py,sha256=aOAB6A-drxvoO3XYnncCbteW_DqCelR7cnSDqeb7MRM,9379
|
|
164
164
|
astrbot/core/pipeline/process_stage/method/agent_request.py,sha256=vHC2Z73Fe96iW4j6ZbNvWQkfXD49pVWy6XKoG-20CS8,2049
|
|
165
165
|
astrbot/core/pipeline/process_stage/method/star_request.py,sha256=C-PTq_Wpq4QMS2ecfRDCcDSX3rYyldfsAN-jAaEEb-w,2430
|
|
166
|
-
astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py,sha256=
|
|
166
|
+
astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py,sha256=5YJZ6xbVxz9Mc2mg16cVcIN26F4NjDswxsmg9hrsNms,34682
|
|
167
167
|
astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py,sha256=LNBRItSpZn0MLP4fyHQ_3gUJ8lnmCwuPlqnZDVFLI6Q,7332
|
|
168
168
|
astrbot/core/pipeline/rate_limit_check/stage.py,sha256=9EVJ0zYtxATFsj7ADyWDYcSGBRqmrMiKWp1kkD9LONI,3962
|
|
169
169
|
astrbot/core/pipeline/respond/stage.py,sha256=RIYGXTG-XvBhgRqaHyJYWlsZjskS9pgV-2jm5o956ho,11042
|
|
@@ -172,7 +172,7 @@ astrbot/core/pipeline/session_status_check/stage.py,sha256=448eWo72O-JZCXMGBLznJ
|
|
|
172
172
|
astrbot/core/pipeline/waking_check/stage.py,sha256=eDxbk_nWEhiwrARJ8DFoH8qf1mi_OdeOutWq3xLA41c,9787
|
|
173
173
|
astrbot/core/pipeline/whitelist_check/stage.py,sha256=x6o4oswIvVtHFRbuKuLFoyFEgx-gSo3IMGYvopu8d9A,2411
|
|
174
174
|
astrbot/core/platform/__init__.py,sha256=5Hhb2mIb8mS2RWfxILIMuV03XiyfqEbn4pAjvi8ntl0,361
|
|
175
|
-
astrbot/core/platform/astr_message_event.py,sha256=
|
|
175
|
+
astrbot/core/platform/astr_message_event.py,sha256=s_ZmELWxvadFIl_Y3mfSV9kpvuE16Wu6sFJk4s6ULi4,16098
|
|
176
176
|
astrbot/core/platform/astrbot_message.py,sha256=kdoiyZoCaH3iVua4pvKw7HHlfVpVB4bI36UeqYX1o38,2670
|
|
177
177
|
astrbot/core/platform/manager.py,sha256=iz6mnYE6DAIZ_b_bkqWfTNYCffRKJVHqsbxuugM3pTU,11549
|
|
178
178
|
astrbot/core/platform/message_session.py,sha256=Fg0MWI4i6IB2jsD39a7fAduFtNcVdFIi40HAHeR9brk,1092
|
|
@@ -298,6 +298,7 @@ astrbot/core/utils/session_lock.py,sha256=fZDIbyy1nYfgsQSGUc_pWHZp4Kv6inXjENP8ay
|
|
|
298
298
|
astrbot/core/utils/session_waiter.py,sha256=Q4zdrvxs-cLLopLCQES6bYZ6MQrajl4fzqZjmmXX170,7073
|
|
299
299
|
astrbot/core/utils/shared_preferences.py,sha256=4mj6FuUdejSbSQ4HVCiRWUIlvE0YK5MvTn7GlOCWK1I,7302
|
|
300
300
|
astrbot/core/utils/tencent_record_helper.py,sha256=utfxCdqn4Beiv7Vd5OosNSLJQuLMusUXdbsxpDV2IxM,5048
|
|
301
|
+
astrbot/core/utils/trace.py,sha256=ArG-pRjSbf52U0t2b8VQhq9JkZvyGPw9nsoQ7etYvy4,2038
|
|
301
302
|
astrbot/core/utils/version_comparator.py,sha256=_VnI50v1xqcZ-wXtOCwknUVwq-wk2Pjh3TLBVe1MTf8,3405
|
|
302
303
|
astrbot/core/utils/webhook_utils.py,sha256=B-dnZdXFAoRo4GMO8FjjT4Em7IYIsU8olJlMCqJt2pc,2021
|
|
303
304
|
astrbot/core/utils/t2i/__init__.py,sha256=wAPd4gcBfuUfFmp_QdYR2AyxmQgMgtY3-AhblbGHqMk,336
|
|
@@ -333,8 +334,8 @@ astrbot/dashboard/routes/t2i.py,sha256=F6smxdL99MF7cRw3hqS6-2GErw8Zhsv0V0mfBUeEk
|
|
|
333
334
|
astrbot/dashboard/routes/tools.py,sha256=mMwVFw_VOlpqy_WZg1A-ddGtYa5L5QLWYawl37PT0-c,15354
|
|
334
335
|
astrbot/dashboard/routes/update.py,sha256=qXiqQ_dbqRVftOzGgCQrvK8-qopVK6zKhhVVJ9SK26U,6648
|
|
335
336
|
astrbot/dashboard/routes/util.py,sha256=Ewf5EgWs0evjOyIbgFffJH6T4DzgDrIoacd6VZ5Ix2c,2856
|
|
336
|
-
astrbot-4.13.
|
|
337
|
-
astrbot-4.13.
|
|
338
|
-
astrbot-4.13.
|
|
339
|
-
astrbot-4.13.
|
|
340
|
-
astrbot-4.13.
|
|
337
|
+
astrbot-4.13.2.dist-info/METADATA,sha256=rRD6HXbf61csviihXAED9fhbqnSgOhl8zdJjAbnNXx4,12192
|
|
338
|
+
astrbot-4.13.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
339
|
+
astrbot-4.13.2.dist-info/entry_points.txt,sha256=OEF09YmhBWYuViXrvTLLpstF4ccmNwDL8r7nnFD0pfI,53
|
|
340
|
+
astrbot-4.13.2.dist-info/licenses/LICENSE,sha256=zPfQj5Mq8-gThIiBcxETr7t8gND9bZWOjTGQAr80TQI,34500
|
|
341
|
+
astrbot-4.13.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|