myagent-ai 1.15.78 → 1.15.79
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.
- package/agents/main_agent.py +3 -2
- package/config.py +1 -0
- package/core/context_builder.py +5 -2
- package/core/utils.py +18 -2
- package/memory/manager.py +3 -2
- package/package.json +1 -1
- package/web/api_server.py +15 -9
package/agents/main_agent.py
CHANGED
|
@@ -280,8 +280,9 @@ class MainAgent(BaseAgent):
|
|
|
280
280
|
return None
|
|
281
281
|
|
|
282
282
|
from datetime import datetime
|
|
283
|
+
from core.utils import get_config_tz
|
|
283
284
|
old_time = old_memory.created_at or "未知时间"
|
|
284
|
-
new_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
285
|
+
new_time = datetime.now(get_config_tz()).strftime("%Y-%m-%d %H:%M:%S")
|
|
285
286
|
user_msg = context.user_message or ""
|
|
286
287
|
|
|
287
288
|
merge_prompt = f"""你是一个记忆管理系统。现在系统检测到两条高度相似的记忆,请你判断如何合并它们。
|
|
@@ -377,7 +378,7 @@ class MainAgent(BaseAgent):
|
|
|
377
378
|
safe_session = session_id.replace("-", "").replace("/", "_")[:12] if session_id else "default"
|
|
378
379
|
kb_file = auto_kb_dir / f"{safe_session}.md"
|
|
379
380
|
|
|
380
|
-
now_str = datetime.now().strftime("%Y-%m-%d %H:%M")
|
|
381
|
+
now_str = datetime.now(get_config_tz()).strftime("%Y-%m-%d %H:%M")
|
|
381
382
|
|
|
382
383
|
# 检查重复:与已有文件内容做相似度比较
|
|
383
384
|
existing_content = ""
|
package/config.py
CHANGED
|
@@ -150,6 +150,7 @@ class AppConfig:
|
|
|
150
150
|
log_level: str = "INFO"
|
|
151
151
|
data_dir: str = "" # 数据目录,默认 ~/.myagent/
|
|
152
152
|
language: str = "zh-CN"
|
|
153
|
+
timezone: str = "Asia/Shanghai" # 时区,用于生成时间戳和提示词中的当前时间
|
|
153
154
|
|
|
154
155
|
|
|
155
156
|
# ==============================================================================
|
package/core/context_builder.py
CHANGED
|
@@ -191,9 +191,12 @@ class ContextBuilder:
|
|
|
191
191
|
"""
|
|
192
192
|
构建 <datetime> 段落 —— 当前日期时间(精确到秒)。
|
|
193
193
|
让 LLM 知道当前时间,以便给出与时间相关的回答。
|
|
194
|
+
使用配置的时区,而非系统时区。
|
|
194
195
|
"""
|
|
196
|
+
from core.utils import get_config_tz
|
|
195
197
|
from datetime import datetime
|
|
196
|
-
|
|
198
|
+
tz = get_config_tz()
|
|
199
|
+
now = datetime.now(tz)
|
|
197
200
|
weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
|
|
198
201
|
date_str = now.strftime("%Y年%m月%d日")
|
|
199
202
|
time_str = now.strftime("%H:%M:%S")
|
|
@@ -201,7 +204,7 @@ class ContextBuilder:
|
|
|
201
204
|
return (
|
|
202
205
|
f"<datetime>\n"
|
|
203
206
|
f"当前时间: {date_str} {weekday} {time_str}\n"
|
|
204
|
-
f"
|
|
207
|
+
f"时区: {tz}\n"
|
|
205
208
|
f"</datetime>"
|
|
206
209
|
)
|
|
207
210
|
|
package/core/utils.py
CHANGED
|
@@ -9,14 +9,30 @@ import uuid
|
|
|
9
9
|
import time
|
|
10
10
|
import re
|
|
11
11
|
from datetime import datetime, timezone
|
|
12
|
+
from zoneinfo import ZoneInfo
|
|
12
13
|
from typing import Any, Dict, Optional, TypeVar
|
|
13
14
|
|
|
14
15
|
T = TypeVar("T")
|
|
15
16
|
|
|
17
|
+
# 时区缓存,避免每次调用都重新解析
|
|
18
|
+
_tz_cache: Optional[ZoneInfo] = None
|
|
19
|
+
|
|
20
|
+
def get_config_tz() -> ZoneInfo:
|
|
21
|
+
"""获取配置的时区对象(带缓存)"""
|
|
22
|
+
global _tz_cache
|
|
23
|
+
if _tz_cache is not None:
|
|
24
|
+
return _tz_cache
|
|
25
|
+
try:
|
|
26
|
+
from config import ConfigManager
|
|
27
|
+
tz_name = ConfigManager().get("timezone", "Asia/Shanghai")
|
|
28
|
+
_tz_cache = ZoneInfo(tz_name)
|
|
29
|
+
except Exception:
|
|
30
|
+
_tz_cache = ZoneInfo("Asia/Shanghai")
|
|
31
|
+
return _tz_cache
|
|
16
32
|
|
|
17
33
|
def timestamp() -> str:
|
|
18
|
-
"""返回 ISO 8601
|
|
19
|
-
return datetime.now().isoformat()
|
|
34
|
+
"""返回 ISO 8601 格式时间戳(使用配置时区)"""
|
|
35
|
+
return datetime.now(get_config_tz()).isoformat()
|
|
20
36
|
|
|
21
37
|
|
|
22
38
|
def timestamp_ms() -> int:
|
package/memory/manager.py
CHANGED
|
@@ -473,7 +473,8 @@ class MemoryManager:
|
|
|
473
473
|
def add_global(self, session_id="global", key="", content="", summary="", importance=0.7, metadata=None) -> str:
|
|
474
474
|
"""添加全局记忆(跨会话可检索)"""
|
|
475
475
|
from datetime import datetime
|
|
476
|
-
|
|
476
|
+
from core.utils import get_config_tz
|
|
477
|
+
now_str = datetime.now(get_config_tz()).strftime("%Y-%m-%d %H:%M:%S")
|
|
477
478
|
ts_summary = summary or truncate_str(content, 200)
|
|
478
479
|
entry = MemoryEntry(
|
|
479
480
|
session_id=session_id, category="global", key=key,
|
|
@@ -676,7 +677,7 @@ class MemoryManager:
|
|
|
676
677
|
try:
|
|
677
678
|
# 解析 ISO 8601 时间戳
|
|
678
679
|
created_dt = datetime.fromisoformat(created_at.replace("Z", "+00:00"))
|
|
679
|
-
now_dt = datetime.now(
|
|
680
|
+
now_dt = datetime.now(get_config_tz())
|
|
680
681
|
|
|
681
682
|
age_seconds = (now_dt - created_dt).total_seconds()
|
|
682
683
|
if age_seconds <= 0:
|
package/package.json
CHANGED
package/web/api_server.py
CHANGED
|
@@ -18,6 +18,11 @@ from web.tts_handler import synthesize, preprocess_for_tts, AVAILABLE_VOICES
|
|
|
18
18
|
|
|
19
19
|
logger = get_logger("myagent.api")
|
|
20
20
|
|
|
21
|
+
def _now_iso():
|
|
22
|
+
"""返回配置时区的 ISO 时间戳"""
|
|
23
|
+
from core.utils import get_config_tz
|
|
24
|
+
return datetime.datetime.now(get_config_tz()).isoformat()
|
|
25
|
+
|
|
21
26
|
def _safe_load_json(filepath, default=None):
|
|
22
27
|
"""安全读取 JSON 文件,解析失败返回默认值"""
|
|
23
28
|
try:
|
|
@@ -1619,7 +1624,7 @@ class ApiServer:
|
|
|
1619
1624
|
# 迁移后再次检查(损坏文件可能已被删除)
|
|
1620
1625
|
if not (ad / "config.json").exists():
|
|
1621
1626
|
ad.mkdir(parents=True, exist_ok=True)
|
|
1622
|
-
now =
|
|
1627
|
+
now = _now_iso()
|
|
1623
1628
|
cfg = {
|
|
1624
1629
|
"id": uuid.uuid4().hex[:12],
|
|
1625
1630
|
"name": "全权Agent",
|
|
@@ -1667,7 +1672,7 @@ class ApiServer:
|
|
|
1667
1672
|
# 其他 agent:创建一个最小 config
|
|
1668
1673
|
ad = self._agent_dir(path)
|
|
1669
1674
|
if ad.exists():
|
|
1670
|
-
now =
|
|
1675
|
+
now = _now_iso()
|
|
1671
1676
|
cfg = {
|
|
1672
1677
|
"id": uuid.uuid4().hex[:12],
|
|
1673
1678
|
"name": path,
|
|
@@ -1682,7 +1687,7 @@ class ApiServer:
|
|
|
1682
1687
|
logger.info(f"已重建 Agent 配置: {path}")
|
|
1683
1688
|
return
|
|
1684
1689
|
changed = False
|
|
1685
|
-
now =
|
|
1690
|
+
now = _now_iso()
|
|
1686
1691
|
if "id" not in cfg:
|
|
1687
1692
|
cfg["id"] = uuid.uuid4().hex[:12]
|
|
1688
1693
|
changed = True
|
|
@@ -1708,7 +1713,7 @@ class ApiServer:
|
|
|
1708
1713
|
# 迁移后再次检查(损坏文件可能已被删除)
|
|
1709
1714
|
if not (ad / "config.json").exists():
|
|
1710
1715
|
ad.mkdir(parents=True, exist_ok=True)
|
|
1711
|
-
now =
|
|
1716
|
+
now = _now_iso()
|
|
1712
1717
|
cfg = {
|
|
1713
1718
|
"id": uuid.uuid4().hex[:12],
|
|
1714
1719
|
"name": "配置助手",
|
|
@@ -1737,7 +1742,7 @@ class ApiServer:
|
|
|
1737
1742
|
cfg = json.loads((ad / "config.json").read_text(encoding="utf-8"))
|
|
1738
1743
|
if cfg.get("system_prompt") != CONFIG_HELPER_PROMPT:
|
|
1739
1744
|
cfg["system_prompt"] = CONFIG_HELPER_PROMPT
|
|
1740
|
-
cfg["updated_at"] =
|
|
1745
|
+
cfg["updated_at"] = _now_iso()
|
|
1741
1746
|
(ad / "config.json").write_text(json.dumps(cfg, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
1742
1747
|
logger.info("已同步配置助手最新的系统提示词")
|
|
1743
1748
|
except Exception as e:
|
|
@@ -1962,7 +1967,7 @@ class ApiServer:
|
|
|
1962
1967
|
if (ad / "config.json").exists():
|
|
1963
1968
|
return web.json_response({"error": f"Agent '{name}' already exists"}, status=409)
|
|
1964
1969
|
|
|
1965
|
-
now =
|
|
1970
|
+
now = _now_iso()
|
|
1966
1971
|
cfg = {
|
|
1967
1972
|
"id": uuid.uuid4().hex[:12],
|
|
1968
1973
|
"name": name,
|
|
@@ -2186,7 +2191,7 @@ class ApiServer:
|
|
|
2186
2191
|
if "system" in data:
|
|
2187
2192
|
del data["system"]
|
|
2188
2193
|
# 自动更新 updated_at
|
|
2189
|
-
cfg["updated_at"] =
|
|
2194
|
+
cfg["updated_at"] = _now_iso()
|
|
2190
2195
|
(ad / "config.json").write_text(json.dumps(cfg, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
2191
2196
|
# 部门变更时同步部门成员列表(old_dept 已在 cfg 修改前保存)
|
|
2192
2197
|
new_dept = data.get("department", old_dept)
|
|
@@ -4697,8 +4702,9 @@ class ApiServer:
|
|
|
4697
4702
|
include_secrets = data.get("include_secrets", False)
|
|
4698
4703
|
|
|
4699
4704
|
try:
|
|
4705
|
+
from core.utils import get_config_tz
|
|
4700
4706
|
export_data = self.core.config_mgr.export_config(include_secrets=include_secrets)
|
|
4701
|
-
filename = f"myagent_config_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
|
|
4707
|
+
filename = f"myagent_config_{datetime.datetime.now(get_config_tz()).strftime('%Y%m%d_%H%M%S')}.json"
|
|
4702
4708
|
|
|
4703
4709
|
resp = web.Response(
|
|
4704
4710
|
body=json.dumps(export_data, ensure_ascii=False, indent=2),
|
|
@@ -6221,7 +6227,7 @@ class ApiServer:
|
|
|
6221
6227
|
self._execution_lock = {
|
|
6222
6228
|
"locked": True,
|
|
6223
6229
|
"locked_by": agent_path,
|
|
6224
|
-
"locked_at":
|
|
6230
|
+
"locked_at": _now_iso(),
|
|
6225
6231
|
}
|
|
6226
6232
|
logger.info(f"全局执行锁已获取: {agent_path}")
|
|
6227
6233
|
return web.json_response({
|