sycommon-python-lib 0.2.5a31__py3-none-any.whl → 0.2.5a32__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.
@@ -37,10 +37,13 @@
37
37
  import asyncio
38
38
  import json
39
39
  import os
40
+ import re
40
41
  from collections.abc import Awaitable, Callable
41
42
  from pathlib import Path
42
43
  from typing import Any, AsyncGenerator, Dict, List, Optional, Tuple, TYPE_CHECKING
43
44
 
45
+ import yaml
46
+
44
47
  from pydantic import BaseModel, Field
45
48
  from langchain_core.messages import HumanMessage, BaseMessage, AIMessageChunk, AIMessage, SystemMessage
46
49
  from langchain_core.tools import BaseTool, tool
@@ -1104,11 +1107,25 @@ async def create_deep_agent(
1104
1107
  )
1105
1108
 
1106
1109
 
1110
+ def _parse_skill_version(content: str) -> str:
1111
+ """从 SKILL.md 内容中解析 version 字段,无 version 返回空字符串"""
1112
+ match = re.match(r"^---\s*\n(.*?)\n---\s*\n", content, re.DOTALL)
1113
+ if not match:
1114
+ return ""
1115
+ try:
1116
+ data = yaml.safe_load(match.group(1))
1117
+ if isinstance(data, dict):
1118
+ return str(data.get("version", ""))
1119
+ except Exception:
1120
+ pass
1121
+ return ""
1122
+
1123
+
1107
1124
  async def _sync_skills_to_sandbox(
1108
1125
  skills_dir: str,
1109
1126
  backend: HTTPSandboxBackend,
1110
1127
  ) -> None:
1111
- """同步 skills 到沙箱(按目录名检查,已存在则跳过,不覆盖用户文件)"""
1128
+ """同步 skills 到沙箱(按版本检查,版本不一致则覆盖)"""
1112
1129
  if not os.path.isdir(skills_dir):
1113
1130
  return
1114
1131
 
@@ -1121,16 +1138,46 @@ async def _sync_skills_to_sandbox(
1121
1138
  if child.is_dir:
1122
1139
  existing_dirs.add(child.name)
1123
1140
 
1124
- # 只上传沙箱中不存在的技能
1141
+ # 遍历本地 skills,按版本决定是否同步
1125
1142
  for skill_name in os.listdir(skills_dir):
1126
1143
  src = os.path.join(skills_dir, skill_name)
1127
1144
  if not os.path.isdir(src):
1128
1145
  continue
1146
+
1147
+ # 读取本地版本
1148
+ local_skill_md = os.path.join(src, "SKILL.md")
1149
+ local_version = ""
1150
+ if os.path.isfile(local_skill_md):
1151
+ try:
1152
+ with open(local_skill_md, "r", encoding="utf-8") as f:
1153
+ local_version = _parse_skill_version(f.read())
1154
+ except Exception:
1155
+ pass
1156
+
1129
1157
  if skill_name in existing_dirs:
1130
- SYLogger.debug(f"[DeepAgent] 技能已存在,跳过: {skill_name}")
1131
- continue
1158
+ # 读取沙箱中的版本
1159
+ remote_version = ""
1160
+ try:
1161
+ remote_content = await backend.aread(f"/skills/{skill_name}/SKILL.md")
1162
+ if remote_content:
1163
+ remote_version = _parse_skill_version(remote_content)
1164
+ except Exception:
1165
+ pass
1166
+
1167
+ if remote_version and remote_version == local_version:
1168
+ SYLogger.debug(f"[DeepAgent] 技能版本一致,跳过: {skill_name} v{local_version}")
1169
+ continue
1170
+
1171
+ # 版本不一致或沙箱无版本,删除后重新上传
1172
+ try:
1173
+ await backend.aexecute(f"rm -rf /skills/{skill_name}")
1174
+ SYLogger.info(f"[DeepAgent] 技能版本不一致,覆盖: {skill_name} ({remote_version or '无版本'} → {local_version})")
1175
+ except Exception as e:
1176
+ SYLogger.warning(f"[DeepAgent] 删除旧版技能失败: {skill_name}, {e}")
1177
+ continue
1178
+
1132
1179
  await backend.async_sync_dirs([(src, f"/skills/{skill_name}")])
1133
- SYLogger.info(f"[DeepAgent] 同步技能到沙箱: {skill_name}")
1180
+ SYLogger.info(f"[DeepAgent] 同步技能到沙箱: {skill_name} v{local_version}")
1134
1181
  except Exception as e:
1135
1182
  SYLogger.warning(f"[DeepAgent] 技能同步失败: {e}")
1136
1183
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.5a31
3
+ Version: 0.2.5a32
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -129,7 +129,7 @@ sycommon/services.py,sha256=pUcV0xFrn1hrArD9YwE8m6CMrrWPwNBAqUIWhgsVkzY,24943
129
129
  sycommon/agent/__init__.py,sha256=mxceAeUifQ-DKvWp7ZEJIFlmOCb5wpYHPGQw3rwEN8I,4378
130
130
  sycommon/agent/agent_manager.py,sha256=UhhaekEumT7g4v_Z1UB4jTp13X0n8M8erYaQdkGGWkA,13620
131
131
  sycommon/agent/chat_events.py,sha256=t7qWa6OrIWLfqtd1AnqaVP67QWkn1JxpCBTZYQpoLuM,14226
132
- sycommon/agent/deep_agent.py,sha256=zZRmjEYAEx8LgnDCRFf6QS9Xxyy67WSzomjdC2I732Q,55405
132
+ sycommon/agent/deep_agent.py,sha256=m3syXhyV0Y4zsqy-Qo_jvszER5nbgZ5jl9v_YepW5wY,57219
133
133
  sycommon/agent/multi_agent_team.py,sha256=W5gP6sWIYhhXf6iBLHfyTIs9eAhUdkWrn_PF6W2cESs,26059
134
134
  sycommon/agent/summarization_utils.py,sha256=5eiLtxRZKTzO0tnr8sVaL-H3a0eUtvXpCa28Jw_j2eE,10889
135
135
  sycommon/agent/mcp/__init__.py,sha256=iKrdDhIrFsNIkqG_kgcwNe-nOiM6uVfolKv44LfQ-FQ,636
@@ -279,8 +279,8 @@ sycommon/tools/syemail.py,sha256=BDFhgf7WDOQeTcjxJEQdu0dQhnHFPO_p3eI0-Ni3LhQ,561
279
279
  sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
280
280
  sycommon/xxljob/__init__.py,sha256=7eoBlQxv-B39IfRSCY2bkqdGYs1QRe1umAWd88VMEEM,86
281
281
  sycommon/xxljob/xxljob_service.py,sha256=JIEJaGXhqrTLcyxlyynSrsHg9bBnDNzX-D4qIWLRPUE,6815
282
- sycommon_python_lib-0.2.5a31.dist-info/METADATA,sha256=QP-iiLOW9iiICa42zGhSK_x_iWW2TTmRNp-9IMhee6c,7914
283
- sycommon_python_lib-0.2.5a31.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
284
- sycommon_python_lib-0.2.5a31.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
285
- sycommon_python_lib-0.2.5a31.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
286
- sycommon_python_lib-0.2.5a31.dist-info/RECORD,,
282
+ sycommon_python_lib-0.2.5a32.dist-info/METADATA,sha256=BTCQAIi4BIvkS2K6H4dwTOBfgxLPil556tTTROONDJc,7914
283
+ sycommon_python_lib-0.2.5a32.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
284
+ sycommon_python_lib-0.2.5a32.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
285
+ sycommon_python_lib-0.2.5a32.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
286
+ sycommon_python_lib-0.2.5a32.dist-info/RECORD,,