sycommon-python-lib 0.2.7a33__py3-none-any.whl → 0.2.7a34__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.
@@ -277,6 +277,11 @@ class SensitiveGuardMiddleware(AgentMiddleware):
277
277
  # False → 按 block_user_input(仅最后一条 HumanMessage)。绝不改 _action,避免
278
278
  # 与用户配的真 block 混淆(set_file_turn_degrade 在非 block_user_input 上为 no-op)。
279
279
  self._file_turn_degrade = False
280
+ # 本轮(last_human 范围)「用户输入已判过」标志:block_user_input 无附件时,
281
+ # 同一轮里用户输入恒定不变,第一次判过即可,工具执行后再进模型节点不再重复判
282
+ # (重复判定等价于白烧一次内网调用,见 awrap_model_call (c) last_human 分支)。
283
+ # 每轮 chat 前由 set_file_turn_degrade() 重置;命中敏感走 (b) 短路,本标志无影响。
284
+ self._last_human_judged = False
280
285
  self._enabled = enabled
281
286
  self._state = state or DowngradeState()
282
287
  self._detect_prompt = detect_prompt or DEFAULT_DETECT_PROMPT
@@ -322,6 +327,9 @@ class SensitiveGuardMiddleware(AgentMiddleware):
322
327
  self._file_turn_degrade = bool(on)
323
328
  else:
324
329
  self._file_turn_degrade = False
330
+ # 每轮 chat 开始时调用 → 重置「本轮用户输入已判过」标志。
331
+ # 新一轮用户输入到来,上一轮的判定结论不再复用,需重新判一次。
332
+ self._last_human_judged = False
325
333
 
326
334
  @property
327
335
  def effective_detect_messages(self) -> str:
@@ -392,6 +400,17 @@ class SensitiveGuardMiddleware(AgentMiddleware):
392
400
  识别失败时 fail-open 视为不敏感(默认放行),避免误伤正常请求。
393
401
  """
394
402
  content = _messages_to_text(messages)
403
+ # 🔍 sensitive judge 诊断:打印本轮发出去的 content 字符数 + action + 范围
404
+ # block_user_input 应只发最后一条 HumanMessage(短);命中场景下若 chars 异常大,
405
+ # 说明检测范围没按 has_file 切换。仅打印长度与首尾摘要,不泄露正文。
406
+ try:
407
+ _action_now = getattr(self, "action", None) or getattr(self, "_action", None)
408
+ SYLogger.info(
409
+ f"[SensitiveGuard][Detect] 发起判定: action={_action_now} "
410
+ f"messages={len(messages)} content_chars={len(content)} "
411
+ f"head={content[:80]!r} tail={content[-80:]!r}")
412
+ except Exception:
413
+ pass
395
414
  try:
396
415
  detector = await self._get_detector()
397
416
  # 🔑 提示词模板里含 {content} 占位符(应用层 SENSITIVE_DETECT_PROMPT)。
@@ -459,11 +478,22 @@ class SensitiveGuardMiddleware(AgentMiddleware):
459
478
  if detect_messages is None:
460
479
  # 无用户输入(理论上不会发生)→ 无从检测,放行
461
480
  return await handler(request)
481
+ # 🔑 block_user_input 无附件:本轮只判一次用户输入。
482
+ # 工具执行后模型节点会再次进入本方法,但用户输入本轮恒定不变 → 直接放行,
483
+ # 不重复调 detector(省一次内网判定调用 + 3s 延迟)。命中过则已在 (b) 短路,
484
+ # 不会走到这。set_file_turn_degrade() 每轮 chat 前会清本标志。
485
+ if self._last_human_judged:
486
+ SYLogger.info(
487
+ "[SensitiveGuard][Detect] 本轮用户输入已判过,跳过重复判定(last_human)")
488
+ return await handler(request)
462
489
  else:
463
490
  # block / downgrade / block_user_input+降级:整段上下文
464
491
  detect_messages = request.messages
465
492
 
466
493
  check = await self._detect(detect_messages)
494
+ # last_human 范围:无论命中与否,本轮用户输入的判定已完成,置位避免重复判定。
495
+ if self.effective_detect_messages == "last_human":
496
+ self._last_human_judged = True
467
497
  if not check.is_sensitive:
468
498
  return await handler(request)
469
499
 
@@ -29,6 +29,36 @@ class LLMLogger(AsyncCallbackHandler):
29
29
  **kwargs: Any
30
30
  ) -> None:
31
31
  model_name = serialized.get('name', 'unknown')
32
+ # 🔍 每次模型调用诊断:模型名 + 消息组数 + 各组消息类型/条数 + 每组总字符数
33
+ # (字符数≈4×token,可粗判 input 是否「固定长度分类器」还是「全文上下文」)。
34
+ # 跨意图识别/sensitive judge/主对话/rubric 全覆盖。
35
+ try:
36
+ groups_summary = []
37
+ for gi, group in enumerate(messages):
38
+ chars = 0
39
+ type_counts: Dict[str, int] = {}
40
+ for m in group:
41
+ c = m.content
42
+ if isinstance(c, str):
43
+ chars += len(c)
44
+ elif isinstance(c, list):
45
+ # 多模态:累加每个块的 text 长度
46
+ for blk in c:
47
+ if isinstance(blk, dict):
48
+ chars += len(str(blk.get("text", "")))
49
+ else:
50
+ chars += len(str(blk))
51
+ else:
52
+ chars += len(str(c))
53
+ t = getattr(m, "type", type(m).__name__)
54
+ type_counts[t] = type_counts.get(t, 0) + 1
55
+ groups_summary.append(
56
+ f"#{gi+1} msgs={len(group)} chars={chars} types={type_counts}")
57
+ SYLogger.info(
58
+ f"[LLM-DIAG] 调用开始 model={model_name} 组数={len(messages)} | "
59
+ f"{' || '.join(groups_summary)}")
60
+ except Exception as _e:
61
+ SYLogger.warning(f"[LLM-DIAG] 诊断统计失败(非致命): {_e}")
32
62
  SYLogger.info(
33
63
  f"聊天模型调用开始 | 模型: {model_name} | 消息组数: {len(messages)}")
34
64
  self._log_chat_messages(messages)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.7a33
3
+ Version: 0.2.7a34
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -148,7 +148,7 @@ sycommon/agent/mcp/__init__.py,sha256=iKrdDhIrFsNIkqG_kgcwNe-nOiM6uVfolKv44LfQ-F
148
148
  sycommon/agent/mcp/models.py,sha256=zda4ho-UTYOJ5oPAZPZ-vxhfDRLghUCsMroHnA2A2QQ,1490
149
149
  sycommon/agent/mcp/tool_loader.py,sha256=pwhZoSoZuQVYo6BgfdMoRHlGnRPDRxvOvxEgvUM5q7Q,17818
150
150
  sycommon/agent/middleware/sandbox_path_guard.py,sha256=K1SnxA8pDxkCSucOkranwUvC9_8rd3l_-TIR8gMMTK8,8102
151
- sycommon/agent/middleware/sensitive_guard.py,sha256=ChUU8twVVwkxt5c3Ymjf5FCrIqHexVR6kGWG70hhuEQ,27986
151
+ sycommon/agent/middleware/sensitive_guard.py,sha256=B6Dpii3m-IU9qFrIUSUHbtjEwELRrHx2Iez-Ri0fDiM,30276
152
152
  sycommon/agent/middleware/sitecustomize.py,sha256=Bt7XFnWV_LJo89l858AGp5VUkXwefpLGmjkCtLe-CMw,4800
153
153
  sycommon/agent/middleware/skill_api_whitelist.py,sha256=2qVsrwS6VkkPKHrvjJMNUfBDokdMJkP-mn-V-ZCn7X8,16643
154
154
  sycommon/agent/middleware/skill_wl_check.py,sha256=rCJ9F6aWPh8tVQBIPmcq2lKDsfwiJQduwSUku_8kXfs,3952
@@ -203,7 +203,7 @@ sycommon/heartbeat_process/heartbeat_process_worker.py,sha256=duuAEFwda43Y6pZE8t
203
203
  sycommon/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
204
204
  sycommon/llm/embedding.py,sha256=n2PtKlfJ4E1-V8DIHTilR-y9y1TYB5iaATlWOKjid28,19878
205
205
  sycommon/llm/get_llm.py,sha256=Mi4rWB07QQzv0NgAGOCXyB9Yd7jl_MbKd1J5Qml8BMk,8402
206
- sycommon/llm/llm_logger.py,sha256=8O8UAb76g3Jyk1fTpgqqnpKRz1SWB0-2wc4GBvdnvUk,4526
206
+ sycommon/llm/llm_logger.py,sha256=35R-6BOPKLe2FJA7PKeMPCMaPkFdSEc6_QERnHRhDcs,6114
207
207
  sycommon/llm/llm_tokens.py,sha256=yGEessxfk5wRMrPGyWHhiiIIQFDVT23FSaqnwqHGCoY,4712
208
208
  sycommon/llm/llm_with_token_tracking.py,sha256=VJYHQSSuqvAbJ7qFs7Zml_thFDZoqL2rXFj8Nrj6rNo,13834
209
209
  sycommon/llm/native_with_fallback_runnable.py,sha256=8g2q8cRqJv2miY7GrZz_f-zNmHxdb_5WSujD3frqObQ,8035
@@ -311,8 +311,8 @@ sycommon/tools/syemail.py,sha256=BDFhgf7WDOQeTcjxJEQdu0dQhnHFPO_p3eI0-Ni3LhQ,561
311
311
  sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
312
312
  sycommon/xxljob/__init__.py,sha256=7eoBlQxv-B39IfRSCY2bkqdGYs1QRe1umAWd88VMEEM,86
313
313
  sycommon/xxljob/xxljob_service.py,sha256=1yifwIBNGsCIxLnQjHKiBlbsigc_zvPH-dMTZcNxe-Q,7649
314
- sycommon_python_lib-0.2.7a33.dist-info/METADATA,sha256=46OEQuDknEAfGWnldU8AlXjHiXCldxKqj_ZFjbcQ_Ac,7963
315
- sycommon_python_lib-0.2.7a33.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
316
- sycommon_python_lib-0.2.7a33.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
317
- sycommon_python_lib-0.2.7a33.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
318
- sycommon_python_lib-0.2.7a33.dist-info/RECORD,,
314
+ sycommon_python_lib-0.2.7a34.dist-info/METADATA,sha256=g0qvNe0nB7HSgtEf-n3TBuARcIYTo8qdgkUJMYdge0M,7963
315
+ sycommon_python_lib-0.2.7a34.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
316
+ sycommon_python_lib-0.2.7a34.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
317
+ sycommon_python_lib-0.2.7a34.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
318
+ sycommon_python_lib-0.2.7a34.dist-info/RECORD,,