sycommon-python-lib 0.2.5a42__py3-none-any.whl → 0.2.6a0__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.
@@ -49,6 +49,7 @@ from langchain_core.messages import HumanMessage, BaseMessage, AIMessageChunk, A
49
49
  from langchain_core.tools import BaseTool, tool
50
50
 
51
51
  from sycommon.logging.kafka_log import SYLogger
52
+ from sycommon.tools.snowflake import Snowflake
52
53
  from sycommon.llm.get_llm import get_llm
53
54
  from sycommon.agent.sandbox.http_sandbox_backend import HTTPSandboxBackend
54
55
  from sycommon.agent.sandbox.sandbox_recovery import SandboxRecoveryManager
@@ -447,6 +448,11 @@ class DeepAgent:
447
448
  total_input_tokens = 0
448
449
  total_output_tokens = 0
449
450
 
451
+ # ── 设置 chat turn 级 trace_id ──
452
+ # 如果上层(HTTP 中间件等)已设置 trace_id 则沿用,否则生成新的
453
+ _chat_trace_id = SYLogger.get_trace_id() or str(Snowflake.id)
454
+ _trace_token = SYLogger.set_trace_id(_chat_trace_id)
455
+
450
456
  try:
451
457
  input_state = {"messages": [HumanMessage(content=message)]}
452
458
  if rubric:
@@ -911,6 +917,7 @@ class DeepAgent:
911
917
  SYLogger.warning(f"[DeepAgent] Token 兜底统计失败: {te}")
912
918
 
913
919
  event = ChatEventBuilder.done()
920
+ event.data["trace_id"] = _chat_trace_id
914
921
  if total_input_tokens > 0 or total_output_tokens > 0:
915
922
  event.data["input_tokens"] = total_input_tokens
916
923
  event.data["output_tokens"] = total_output_tokens
@@ -936,9 +943,12 @@ class DeepAgent:
936
943
  await on_event(event)
937
944
  yield event
938
945
  event = ChatEventBuilder.done()
946
+ event.data["trace_id"] = _chat_trace_id
939
947
  if on_event:
940
948
  await on_event(event)
941
949
  yield event
950
+ finally:
951
+ SYLogger.reset_trace_id(_trace_token)
942
952
 
943
953
  # ============== 内部方法 ==============
944
954
 
@@ -1267,16 +1277,31 @@ async def _sync_skill_to_minio(
1267
1277
  return count
1268
1278
 
1269
1279
 
1280
+ async def _get_minio_skill_version(minio_service, skill_name: str) -> str:
1281
+ """从 MinIO 全局 skills/ 路径下读取技能版本"""
1282
+ try:
1283
+ content = await asyncio.to_thread(
1284
+ minio_service._client.get_object,
1285
+ minio_service._bucket,
1286
+ f"skills/{skill_name}/SKILL.md",
1287
+ )
1288
+ data = content.read()
1289
+ content.close()
1290
+ return _parse_skill_version(data.decode("utf-8"))
1291
+ except Exception:
1292
+ return ""
1293
+
1294
+
1270
1295
  async def _sync_skills_to_sandbox(
1271
1296
  skills_dir: str,
1272
1297
  backend: HTTPSandboxBackend,
1273
1298
  ) -> None:
1274
1299
  """同步技能目录到沙箱和 MinIO(按版本检查,版本不一致则全量覆盖)
1275
1300
 
1276
- 遍历本地 skills_dir 下所有技能子目录,比较本地与沙箱的 SKILL.md version:
1277
- - 版本一致:跳过
1278
- - 版本不一致或沙箱无版本:删除旧目录,全量上传到沙箱和 MinIO
1279
- 同步完成后将技能名加入 backend._synced_skills,跳过后续懒同步。
1301
+ 版本检查优先级:
1302
+ 1. 沙箱 /skills/{name}/SKILL.md — 最快,无需额外 IO
1303
+ 2. MinIO skills/{name}/SKILL.md — 沙箱为空时(新 Pod / 新沙箱)的兜底
1304
+ 版本一致则跳过,不一致或无版本则全量上传到沙箱和 MinIO。
1280
1305
  """
1281
1306
  if not os.path.isdir(skills_dir):
1282
1307
  return
@@ -1315,9 +1340,9 @@ async def _sync_skills_to_sandbox(
1315
1340
  except Exception:
1316
1341
  pass
1317
1342
 
1318
- # 比较版本:一致则跳过
1343
+ # 比较版本:优先从沙箱读,沙箱无则从 MinIO 读
1344
+ remote_version = ""
1319
1345
  if skill_name in existing_dirs:
1320
- remote_version = ""
1321
1346
  try:
1322
1347
  remote_content = await backend.aread(
1323
1348
  f"/skills/{skill_name}/SKILL.md")
@@ -1326,14 +1351,26 @@ async def _sync_skills_to_sandbox(
1326
1351
  except Exception:
1327
1352
  pass
1328
1353
 
1329
- if remote_version and remote_version == local_version:
1330
- SYLogger.debug(
1331
- f"[DeepAgent] 技能版本一致,跳过: {skill_name} v{local_version}")
1332
- backend._synced_skills.add(skill_name)
1333
- skip_count += 1
1334
- continue
1354
+ # 沙箱无版本,尝试从 MinIO 全局 skills/ 读取
1355
+ if not remote_version and minio_service:
1356
+ remote_version = await _get_minio_skill_version(
1357
+ minio_service, skill_name)
1358
+
1359
+ if remote_version and remote_version == local_version:
1360
+ SYLogger.debug(
1361
+ f"[DeepAgent] 技能版本一致,跳过: {skill_name} v{local_version}")
1362
+ backend._synced_skills.add(skill_name)
1363
+ skip_count += 1
1364
+ # 沙箱为空但 MinIO 有(版本一致):只恢复到沙箱,不再上传 MinIO
1365
+ if skill_name not in existing_dirs:
1366
+ await backend.async_sync_dirs(
1367
+ [(src, f"/skills/{skill_name}")])
1368
+ SYLogger.info(
1369
+ f"[DeepAgent] 从本地恢复技能到沙箱: {skill_name} v{local_version}")
1370
+ continue
1335
1371
 
1336
- # 版本不一致或沙箱无版本,删除旧目录后全量覆盖
1372
+ # 版本不一致或无版本,删除旧目录后全量覆盖
1373
+ if skill_name in existing_dirs:
1337
1374
  try:
1338
1375
  await backend.aexecute(f"rm -rf /skills/{skill_name}")
1339
1376
  SYLogger.info(
@@ -37,6 +37,7 @@ from langchain_core.messages import HumanMessage, BaseMessage
37
37
  from langchain_core.tools import BaseTool, tool
38
38
 
39
39
  from sycommon.logging.kafka_log import SYLogger
40
+ from sycommon.tools.snowflake import Snowflake
40
41
  from sycommon.llm.get_llm import get_llm
41
42
  from sycommon.agent.sandbox.http_sandbox_backend import HTTPSandboxBackend
42
43
  from sycommon.tools.env import get_env_var
@@ -221,6 +222,10 @@ class MultiAgentTeam:
221
222
  current_agent = self.coordinator_name
222
223
  seen_tool_call_ids = set() # 去重:流式分片中同一 tool_call 多次到达
223
224
 
225
+ # ── 设置 chat turn 级 trace_id ──
226
+ _chat_trace_id = SYLogger.get_trace_id() or str(Snowflake.id)
227
+ _trace_token = SYLogger.set_trace_id(_chat_trace_id)
228
+
224
229
  try:
225
230
  async for chunk in self._astream_with_retry(
226
231
  {"messages": [HumanMessage(content=message)]},
@@ -420,6 +425,7 @@ class MultiAgentTeam:
420
425
  SYLogger.debug(f"[ai_message] {repr(ai_chunk_buffer[:100])}...")
421
426
 
422
427
  event = ChatEventBuilder.done()
428
+ event.data["trace_id"] = _chat_trace_id
423
429
  if on_event:
424
430
  await on_event(event)
425
431
  yield event
@@ -437,9 +443,12 @@ class MultiAgentTeam:
437
443
  await on_event(event)
438
444
  yield event
439
445
  event = ChatEventBuilder.done()
446
+ event.data["trace_id"] = _chat_trace_id
440
447
  if on_event:
441
448
  await on_event(event)
442
449
  yield event
450
+ finally:
451
+ SYLogger.reset_trace_id(_trace_token)
443
452
 
444
453
  # ============== 内部方法 ==============
445
454
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.5a42
3
+ Version: 0.2.6a0
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -129,8 +129,8 @@ 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=KaFYhb6yDcjKPqOS-hUpqzFmmAiuOuCUKMQzkr0W7DU,65273
133
- sycommon/agent/multi_agent_team.py,sha256=SRCZHswfflU1w38_YaF0pqh20qa5N5xqcGAVCBoZzmM,26675
132
+ sycommon/agent/deep_agent.py,sha256=TY2C4AnF609ZFjjz2OrpcAqjRZ2v2fPFtG7LzpWVpgQ,66892
133
+ sycommon/agent/multi_agent_team.py,sha256=mskS-FJbAB_n5kghjHhiWxpA3L9cD1lObeW_wjrLI6s,27079
134
134
  sycommon/agent/summarization_utils.py,sha256=fiwvKYE_eQc1EtBiPT4UyOZoqQdd4JwEsLRDsJNioLQ,14928
135
135
  sycommon/agent/mcp/__init__.py,sha256=iKrdDhIrFsNIkqG_kgcwNe-nOiM6uVfolKv44LfQ-FQ,636
136
136
  sycommon/agent/mcp/models.py,sha256=zda4ho-UTYOJ5oPAZPZ-vxhfDRLghUCsMroHnA2A2QQ,1490
@@ -282,8 +282,8 @@ sycommon/tools/syemail.py,sha256=BDFhgf7WDOQeTcjxJEQdu0dQhnHFPO_p3eI0-Ni3LhQ,561
282
282
  sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
283
283
  sycommon/xxljob/__init__.py,sha256=7eoBlQxv-B39IfRSCY2bkqdGYs1QRe1umAWd88VMEEM,86
284
284
  sycommon/xxljob/xxljob_service.py,sha256=JIEJaGXhqrTLcyxlyynSrsHg9bBnDNzX-D4qIWLRPUE,6815
285
- sycommon_python_lib-0.2.5a42.dist-info/METADATA,sha256=1W1XtiQJptn_RJ5dRXRg8br_cDUEl9FK4lCRxu1PCiA,7914
286
- sycommon_python_lib-0.2.5a42.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
287
- sycommon_python_lib-0.2.5a42.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
288
- sycommon_python_lib-0.2.5a42.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
289
- sycommon_python_lib-0.2.5a42.dist-info/RECORD,,
285
+ sycommon_python_lib-0.2.6a0.dist-info/METADATA,sha256=SZCYl4eAehrnZBS5MnF5Rr-VMP3XbDcKv5XbHQ8GPhI,7913
286
+ sycommon_python_lib-0.2.6a0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
287
+ sycommon_python_lib-0.2.6a0.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
288
+ sycommon_python_lib-0.2.6a0.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
289
+ sycommon_python_lib-0.2.6a0.dist-info/RECORD,,