sycommon-python-lib 0.2.7a15__tar.gz → 0.2.7a17__tar.gz

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.
Files changed (334) hide show
  1. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/PKG-INFO +1 -1
  2. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/pyproject.toml +1 -1
  3. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/simple_chat_agent.py +3 -3
  4. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/deep_agent.py +4 -2
  5. sycommon_python_lib-0.2.7a17/src/sycommon/agent/middleware/sandbox_path_guard.py +143 -0
  6. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/middleware/sensitive_guard.py +7 -5
  7. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/multi_agent_team.py +1 -1
  8. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/sandbox/file_ops.py +4 -1
  9. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/llm_logger.py +10 -0
  10. sycommon_python_lib-0.2.7a17/src/sycommon/llm/token_utils.py +169 -0
  11. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/sandbox.py +11 -2
  12. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_dynamic_max_tokens.py +80 -10
  13. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
  14. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon_python_lib.egg-info/SOURCES.txt +1 -0
  15. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_sensitive_guard.py +4 -2
  16. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_simple_chat_agent.py +1 -1
  17. sycommon_python_lib-0.2.7a15/src/sycommon/llm/token_utils.py +0 -103
  18. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/README.md +0 -0
  19. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/setup.cfg +0 -0
  20. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/__init__.py +0 -0
  21. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/cli.py +0 -0
  22. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/core/__init__.py +0 -0
  23. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/core/console.py +0 -0
  24. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/core/models.py +0 -0
  25. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/core/project.py +0 -0
  26. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/core/utils.py +0 -0
  27. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/__init__.py +0 -0
  28. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/README.md.tpl +0 -0
  29. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/__init__.py +0 -0
  30. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/agent/__init__.py.tpl +0 -0
  31. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/agent/main_agent.py.tpl +0 -0
  32. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/agent/nodes/__init__.py.tpl +0 -0
  33. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/agent/nodes/example_node.py.tpl +0 -0
  34. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/agent/states/__init__.py.tpl +0 -0
  35. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/agent/states/agent_state.py.tpl +0 -0
  36. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/api/__init__.py.tpl +0 -0
  37. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/api/query.py.tpl +0 -0
  38. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/api/sse/__init__.py.tpl +0 -0
  39. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/api/sse/agent.py.tpl +0 -0
  40. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/app.py.tpl +0 -0
  41. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/client/__init__.py.tpl +0 -0
  42. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/db/__init__.py.tpl +0 -0
  43. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/db/model/__init__.py.tpl +0 -0
  44. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/db/model/entity.py.tpl +0 -0
  45. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/db/service.py.tpl +0 -0
  46. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/model/__init__.py.tpl +0 -0
  47. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/model/parse.py.tpl +0 -0
  48. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/tools/__init__.py.tpl +0 -0
  49. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/agent/tools/mq.py.tpl +0 -0
  50. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/.env.tpl +0 -0
  51. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/.gitignore.tpl +0 -0
  52. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/Dockerfile.tpl +0 -0
  53. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/README.md.tpl +0 -0
  54. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/__init__.py +0 -0
  55. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/app.py.tpl +0 -0
  56. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/app.yaml.tpl +0 -0
  57. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/client/FileServiceClient.py.tpl +0 -0
  58. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/client/__init__.py.tpl +0 -0
  59. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/model/__init__.py.tpl +0 -0
  60. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/model/file_info.py.tpl +0 -0
  61. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/base/requirements.txt.tpl +0 -0
  62. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/cli/README.md.tpl +0 -0
  63. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/cli/__init__.py +0 -0
  64. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/cli/app.py.tpl +0 -0
  65. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/cli/commands/__init__.py.tpl +0 -0
  66. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/cli/commands/hello.py.tpl +0 -0
  67. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/cli/pyproject.toml.tpl +0 -0
  68. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/cli/tools/__init__.py.tpl +0 -0
  69. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/README.md.tpl +0 -0
  70. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/__init__.py +0 -0
  71. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/api/__init__.py.tpl +0 -0
  72. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/api/echo.py.tpl +0 -0
  73. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/api/sse/__init__.py.tpl +0 -0
  74. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/api/sse/echo.py.tpl +0 -0
  75. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/app.py.tpl +0 -0
  76. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/client/__init__.py.tpl +0 -0
  77. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/model/__init__.py.tpl +0 -0
  78. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/tools/__init__.py.tpl +0 -0
  79. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/command/templates/web/tools/mq.py.tpl +0 -0
  80. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/nexus/__init__.py +0 -0
  81. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/__init__.py +0 -0
  82. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/__main__.py +0 -0
  83. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/acp/__init__.py +0 -0
  84. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/acp/config.py +0 -0
  85. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/acp/executor.py +0 -0
  86. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/acp/registry.py +0 -0
  87. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/acp/server.py +0 -0
  88. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/agents/__init__.py +0 -0
  89. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/agents/factory.py +0 -0
  90. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/agents/prompts.py +0 -0
  91. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/__init__.py +0 -0
  92. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/browser.py +0 -0
  93. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/capabilities/__init__.py +0 -0
  94. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/capabilities/console.py +0 -0
  95. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/capabilities/dom.py +0 -0
  96. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/capabilities/network.py +0 -0
  97. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/capabilities/page_errors.py +0 -0
  98. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/capabilities/performance.py +0 -0
  99. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/capabilities/screenshot.py +0 -0
  100. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/client.py +0 -0
  101. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/protocol.py +0 -0
  102. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cdp/repl.py +0 -0
  103. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/cli.py +0 -0
  104. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/__init__.py +0 -0
  105. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/acp_cmd.py +0 -0
  106. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/cdp_cmd.py +0 -0
  107. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/chat_cmd.py +0 -0
  108. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/create_cmd.py +0 -0
  109. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/evaluate_cmd.py +0 -0
  110. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/init_cmd.py +0 -0
  111. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/memory_cmd.py +0 -0
  112. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/resume_cmd.py +0 -0
  113. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/rollback_cmd.py +0 -0
  114. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/commands/run_cmd.py +0 -0
  115. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/core/__init__.py +0 -0
  116. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/core/backend.py +0 -0
  117. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/core/config.py +0 -0
  118. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/core/display.py +0 -0
  119. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/core/git_integration.py +0 -0
  120. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/core/llm.py +0 -0
  121. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/core/state.py +0 -0
  122. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/evaluate/__init__.py +0 -0
  123. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/evaluate/api_evaluator.py +0 -0
  124. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/memory/__init__.py +0 -0
  125. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/memory/compressor.py +0 -0
  126. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/memory/full.py +0 -0
  127. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/memory/hot.py +0 -0
  128. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/memory/manager.py +0 -0
  129. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/memory/warm.py +0 -0
  130. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/mode/__init__.py +0 -0
  131. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/mode/create.py +0 -0
  132. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/mode/optimize.py +0 -0
  133. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/models/__init__.py +0 -0
  134. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/models/config_models.py +0 -0
  135. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/__init__.py +0 -0
  136. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/baseline_tests.py +0 -0
  137. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/checkpoint.py +0 -0
  138. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/convergence.py +0 -0
  139. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/diagnosis.py +0 -0
  140. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/engine.py +0 -0
  141. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/environment.py +0 -0
  142. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/experience.py +0 -0
  143. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/harness_prompts.py +0 -0
  144. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/history.py +0 -0
  145. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/optimization_logger.py +0 -0
  146. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/pre_validation.py +0 -0
  147. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/reward.py +0 -0
  148. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/strategy_bandit.py +0 -0
  149. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/strategy_generator.py +0 -0
  150. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/rl/strategy_prompts.py +0 -0
  151. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycli/skills/__init__.py +0 -0
  152. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/__init__.py +0 -0
  153. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/__init__.py +0 -0
  154. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/acp/__init__.py +0 -0
  155. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/acp/client.py +0 -0
  156. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/acp/fetch.py +0 -0
  157. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/acp/ssh_init.py +0 -0
  158. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/acp/tool.py +0 -0
  159. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/agent_manager.py +0 -0
  160. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/chat_events.py +0 -0
  161. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/mcp/__init__.py +0 -0
  162. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/mcp/models.py +0 -0
  163. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/mcp/tool_loader.py +0 -0
  164. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/middleware/sitecustomize.py +0 -0
  165. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/middleware/skill_api_whitelist.py +0 -0
  166. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/middleware/skill_wl_check.py +0 -0
  167. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/middleware/skill_write_guard.py +0 -0
  168. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/sandbox/__init__.py +0 -0
  169. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/sandbox/consistent_hash.py +0 -0
  170. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/sandbox/http_sandbox_backend.py +0 -0
  171. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/sandbox/minio_sync.py +0 -0
  172. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
  173. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
  174. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/sandbox/session.py +0 -0
  175. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/agent/summarization_utils.py +0 -0
  176. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/auth/__init__.py +0 -0
  177. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/auth/ldap_service.py +0 -0
  178. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/auth/oa_cache.py +0 -0
  179. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/auth/oa_crypto.py +0 -0
  180. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/auth/oa_service.py +0 -0
  181. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/auth/wecom_ldap_service.py +0 -0
  182. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/ACPAgentConfig.py +0 -0
  183. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/Config.py +0 -0
  184. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/DatabaseConfig.py +0 -0
  185. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/ElasticsearchConfig.py +0 -0
  186. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/EmbeddingConfig.py +0 -0
  187. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/LLMConfig.py +0 -0
  188. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/LangfuseConfig.py +0 -0
  189. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/MQConfig.py +0 -0
  190. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/PgConfig.py +0 -0
  191. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/RedisConfig.py +0 -0
  192. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/RerankerConfig.py +0 -0
  193. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/SentryConfig.py +0 -0
  194. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/SkillApiWhitelistConfig.py +0 -0
  195. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/XxlJobConfig.py +0 -0
  196. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/__init__.py +0 -0
  197. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/config/config_change_notifier.py +0 -0
  198. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/async_base_db_service.py +0 -0
  199. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/async_database_service.py +0 -0
  200. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/base_db_service.py +0 -0
  201. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/database_service.py +0 -0
  202. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/elasticsearch_service.py +0 -0
  203. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/pg_checkpoint_service.py +0 -0
  204. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/redis_service.py +0 -0
  205. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/resilient_pg_saver.py +0 -0
  206. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/database/token_usage_db_service.py +0 -0
  207. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/health/__init__.py +0 -0
  208. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/health/health_check.py +0 -0
  209. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/health/metrics.py +0 -0
  210. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/health/ping.py +0 -0
  211. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/heartbeat_process/__init__.py +0 -0
  212. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
  213. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
  214. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
  215. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/__init__.py +0 -0
  216. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/embedding.py +0 -0
  217. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/get_llm.py +0 -0
  218. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/llm_tokens.py +0 -0
  219. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/llm_with_token_tracking.py +0 -0
  220. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
  221. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/output_fixing_runnable.py +0 -0
  222. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/struct_token.py +0 -0
  223. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/sy_langfuse.py +0 -0
  224. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
  225. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/tiktoken_cache/fb374d419588a4632f3f557e76b4b70aebbca790 +0 -0
  226. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/token_usage_es_service.py +0 -0
  227. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
  228. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/llm/usage_token.py +0 -0
  229. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/logging/__init__.py +0 -0
  230. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/logging/async_sql_logger.py +0 -0
  231. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/logging/kafka_log.py +0 -0
  232. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/logging/log_masker.py +0 -0
  233. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/logging/logger_levels.py +0 -0
  234. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/logging/logger_wrapper.py +0 -0
  235. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/logging/process_logger.py +0 -0
  236. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/logging/sql_logger.py +0 -0
  237. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/mcp_server/__init__.py +0 -0
  238. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/mcp_server/server.py +0 -0
  239. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/__init__.py +0 -0
  240. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/context.py +0 -0
  241. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/cors.py +0 -0
  242. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/docs.py +0 -0
  243. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/exception.py +0 -0
  244. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/middleware.py +0 -0
  245. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/monitor_memory.py +0 -0
  246. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/mq.py +0 -0
  247. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/timeout.py +0 -0
  248. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/token_tracking.py +0 -0
  249. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/tool_result_truncation.py +0 -0
  250. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/middleware/traceid.py +0 -0
  251. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/__init__.py +0 -0
  252. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/base_http.py +0 -0
  253. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/log.py +0 -0
  254. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/mcp_server_config.py +0 -0
  255. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/mqlistener_config.py +0 -0
  256. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/mqmsg_model.py +0 -0
  257. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/mqsend_config.py +0 -0
  258. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/sandbox.py +0 -0
  259. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/sso_user.py +0 -0
  260. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/token_usage.py +0 -0
  261. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/token_usage_mysql.py +0 -0
  262. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/models/xxljob_handler_config.py +0 -0
  263. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/notice/__init__.py +0 -0
  264. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/notice/uvicorn_monitor.py +0 -0
  265. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/notice/wecom_message.py +0 -0
  266. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
  267. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
  268. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
  269. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
  270. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
  271. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
  272. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
  273. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
  274. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
  275. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/sentry/__init__.py +0 -0
  276. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/sentry/sy_sentry.py +0 -0
  277. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/services.py +0 -0
  278. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/sse/__init__.py +0 -0
  279. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/sse/event.py +0 -0
  280. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/sse/sse.py +0 -0
  281. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/__init__.py +0 -0
  282. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/example.py +0 -0
  283. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/example2.py +0 -0
  284. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/feign.py +0 -0
  285. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/feign_client.py +0 -0
  286. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/nacos_client_base.py +0 -0
  287. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/nacos_config_manager.py +0 -0
  288. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
  289. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/nacos_service.py +0 -0
  290. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
  291. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/nacos_service_registration.py +0 -0
  292. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/synacos/param.py +0 -0
  293. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/deep_agent_server.py +0 -0
  294. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_consistent_hash.py +0 -0
  295. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_consumer_loss_rootcause.py +0 -0
  296. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_consumer_recovery.py +0 -0
  297. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_deep_agent.py +0 -0
  298. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_email.py +0 -0
  299. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_encoding_cache.py +0 -0
  300. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_fix_verification.py +0 -0
  301. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_mcp_server.py +0 -0
  302. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_minimax_reasoning.py +0 -0
  303. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_mq.py +0 -0
  304. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_oa_login.py +0 -0
  305. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_queue_priority_fallback.py +0 -0
  306. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_real_summarization.py +0 -0
  307. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_summarization_config.py +0 -0
  308. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_summarization_real.py +0 -0
  309. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tests/test_summary_leak_e2e.py +0 -0
  310. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tools/__init__.py +0 -0
  311. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tools/async_utils.py +0 -0
  312. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tools/docs.py +0 -0
  313. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tools/env.py +0 -0
  314. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tools/merge_headers.py +0 -0
  315. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tools/snowflake.py +0 -0
  316. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tools/syemail.py +0 -0
  317. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/tools/timing.py +0 -0
  318. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/xxljob/__init__.py +0 -0
  319. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon/xxljob/xxljob_service.py +0 -0
  320. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
  321. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
  322. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
  323. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
  324. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_acp_tool.py +0 -0
  325. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_asyncio_logging.py +0 -0
  326. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_config_change_notifier.py +0 -0
  327. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_hotreload_snapshot.py +0 -0
  328. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_llm_apikey_contextvar.py +0 -0
  329. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_log_masker.py +0 -0
  330. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_resilient_pg_saver.py +0 -0
  331. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_skill_regex_upgrade.py +0 -0
  332. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_skill_write_guard.py +0 -0
  333. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_sycli.py +0 -0
  334. {sycommon_python_lib-0.2.7a15 → sycommon_python_lib-0.2.7a17}/tests/test_sync_skills_to_sandbox.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.7a15
3
+ Version: 0.2.7a17
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sycommon-python-lib"
3
- version = "0.2.7a15"
3
+ version = "0.2.7a17"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -29,7 +29,7 @@ def _init_llm_config_from_env() -> None:
29
29
  base = os.getenv("ACP_CHAT_BASE")
30
30
  if not base:
31
31
  return # 无 env,走默认 Nacos 配置
32
- model = os.getenv("ACP_CHAT_MODEL", "digital-worker-llm")
32
+ model = os.getenv("ACP_CHAT_MODEL", "digital-worker-external")
33
33
  key = os.getenv("ACP_CHAT_KEY", "-")
34
34
  try:
35
35
  import sycommon.config.Config as cfgmod
@@ -64,14 +64,14 @@ def _init_llm_config_from_env() -> None:
64
64
  async def chat_once(message: str, on_chunk=None) -> str:
65
65
  """调一次 LLM 完成对话,可选流式回调。返回完整回复文本。
66
66
 
67
- 用 sycommon 的 get_llm,模型名从环境 ACP_CHAT_MODEL 读(默认 digital-worker-llm)。
67
+ 用 sycommon 的 get_llm,模型名从环境 ACP_CHAT_MODEL 读(默认 digital-worker-external)。
68
68
  若设置了 ACP_CHAT_BASE,则用环境变量配置(不依赖 Nacos)。
69
69
  """
70
70
  _init_llm_config_from_env()
71
71
  from sycommon.llm.get_llm import get_llm
72
72
  from langchain_core.messages import HumanMessage, SystemMessage
73
73
 
74
- model_name = os.getenv("ACP_CHAT_MODEL", "digital-worker-llm")
74
+ model_name = os.getenv("ACP_CHAT_MODEL", "digital-worker-external")
75
75
  llm = get_llm(model=model_name, streaming=True)
76
76
  messages = [
77
77
  SystemMessage(content="你是一个简洁的对话助手,用一两句话回答。"),
@@ -58,6 +58,7 @@ from sycommon.agent.chat_events import ChatEvent, ChatEventBuilder, DEFAULT_AGEN
58
58
  from sycommon.middleware.token_tracking import TokenTrackingMiddleware
59
59
  from sycommon.middleware.tool_result_truncation import ToolResultTruncationMiddleware
60
60
  from sycommon.agent.middleware.skill_write_guard import SkillWriteGuardMiddleware
61
+ from sycommon.agent.middleware.sandbox_path_guard import SandboxPathGuardMiddleware
61
62
  from sycommon.agent.middleware.sensitive_guard import SensitiveGuardMiddleware
62
63
  from deepagents.middleware.summarization import create_summarization_tool_middleware # noqa: F401 保留 re-export
63
64
  from sycommon.agent.summarization_utils import build_summarization_middleware
@@ -374,8 +375,8 @@ class AgentConfig(BaseModel):
374
375
  internal_model_name: Optional[str] = None
375
376
  # 敏感检测提示词(应用层可覆盖);未传(None)用基础库 DEFAULT_DETECT_PROMPT
376
377
  sensitive_detect_prompt: Optional[str] = None
377
- # 命中敏感后的动作:"downgrade"=降级内部模型继续;"block"=直接阻断不执行
378
- sensitive_action: str = "downgrade"
378
+ # 命中敏感后的动作:"allow"=不检测放行;"downgrade"=降级内部模型继续;"block"=直接阻断不执行
379
+ sensitive_action: str = "allow"
379
380
 
380
381
  # 系统提示词
381
382
  system_prompt: str = DEFAULT_SYSTEM_PROMPT
@@ -1254,6 +1255,7 @@ async def create_deep_agent(
1254
1255
  TokenTrackingMiddleware(model_name=config.model_name, user_id=user_id),
1255
1256
  summarization_mw,
1256
1257
  SkillWriteGuardMiddleware(), # 系统 /skills/system 只读守卫(先于白名单)
1258
+ SandboxPathGuardMiddleware(user_id), # 宿主绝对路径规范化/拦截(防越权读他人沙箱文件)
1257
1259
  ]
1258
1260
 
1259
1261
  # RubricMiddleware:复用 FilesystemMiddleware 的工具(底层走 HTTPSandboxBackend HTTP 远程调用)
@@ -0,0 +1,143 @@
1
+ """沙箱路径守卫中间件。
2
+
3
+ 拦所有吃路径的沙箱工具调用,在发到沙箱服务端之前规范化/拦截宿主绝对路径:
4
+
5
+ - **虚拟路径**(/skills/...、./x、output/...) → 放行
6
+ - **自己的工作目录绝对路径**(/data/.../sycommon_sandbox/<本人>/...) → 改写为虚拟路径放行
7
+ (零往返,体验最好;也兼容 agent 偶尔把工作目录当绝对路径写的写法)
8
+ - **越界/跨用户绝对路径**(别人的工作目录、/etc/passwd 等无关宿主路径) → 拦截返回 error
9
+ (防越权读他人数据;也避免把别的用户名/路径结构泄回 LLM 上下文)
10
+ - **execute 命令串里出现宿主绝对路径前缀** → 拦截(shell 里不能安全改写子串,只能挡)
11
+
12
+ 与 SkillWriteGuardMiddleware(管 /skills/system 只读)互不冲突,均为 fail-closed 短路。
13
+ 这是「事前拦截」层;沙箱服务端 resolve_sandbox_path 的越权拒绝 + /read 的 outside-sandbox
14
+ 提示作为 defense-in-depth 兜底(漏过此层仍会被服务端挡)。
15
+ """
16
+ import dataclasses
17
+ import os
18
+ import re
19
+
20
+ from langchain.agents.middleware.types import AgentMiddleware
21
+ from langchain_core.messages import ToolMessage
22
+ from langgraph.prebuilt.tool_node import ToolCallRequest
23
+
24
+ # 宿主工作目录根(Linux: /data/sycommon_sandbox;本地 macOS 测试: <tempdir>/sycommon_sandbox)。
25
+ # 从 sandbox 服务端模块取,保证「middleware 算的前缀」与「服务端实际隔离边界」一致,不漂移。
26
+ try:
27
+ from sycommon.middleware.sandbox import WORKSPACE_BASE, _sanitize_user_id
28
+ except Exception: # 测试/独立引入环境兜底,行为与 sandbox.py 保持一致
29
+ import tempfile
30
+ import platform
31
+ if platform.system() == "Linux":
32
+ WORKSPACE_BASE = os.environ.get("SANDBOX_WORKSPACE", "/data/sycommon_sandbox")
33
+ else:
34
+ WORKSPACE_BASE = os.environ.get(
35
+ "SANDBOX_WORKSPACE",
36
+ os.path.join(tempfile.gettempdir(), "sycommon_sandbox"))
37
+
38
+ def _sanitize_user_id(user_id: str) -> str:
39
+ import re as _re
40
+ return _re.sub(r'[^a-zA-Z0-9._\-]', '_', user_id.lower().replace(" ", ""))
41
+
42
+
43
+ # 宿主工作目录根的规范化形式(realpath,去尾斜杠)。所有绝对路径判定以此为锚。
44
+ _WORKSPACE_ROOT = os.path.realpath(WORKSPACE_BASE).rstrip(os.sep)
45
+
46
+
47
+ # 工具 → 路径字段名映射(结构化参数,可安全改写/拦截)
48
+ # get_share_url 是 app(base_tools)自定义工具,同样吃 file_path,纳入统一约束。
49
+ _PATH_TOOLS = {
50
+ "read_file": "file_path",
51
+ "write_file": "file_path",
52
+ "edit_file": "file_path",
53
+ "ls": "path",
54
+ "glob": "path",
55
+ "grep": "path",
56
+ "get_share_url": "file_path",
57
+ }
58
+
59
+ # 宿主沙箱根前缀(用于 execute 命令串扫描;shell 里无法安全改写,只能拦)。
60
+ # 命中即视为「引用了宿主沙箱真实路径」,一律拦。
61
+ _HOST_SANDBOX_RE = re.compile(re.escape(_WORKSPACE_ROOT) + r'(?:/|\\)')
62
+
63
+ _DENIED_MSG = (
64
+ "Error: 不允许使用宿主机绝对路径访问沙箱文件。"
65
+ "请改用沙箱相对路径(如 /skills/system/...、./output/report.pdf、result.xlsx)。"
66
+ )
67
+
68
+
69
+ def _is_host_absolute(path: str) -> bool:
70
+ """是否为「沙箱根之内」的宿主机绝对路径(才需规范化/拦截判断)。
71
+
72
+ 沙箱根之外的宿主绝对路径(/etc/passwd 等)在沙箱里本来就读不到,
73
+ 会自然落到服务端 'not found',无需此层干预——故这里只认沙箱根内的。
74
+ """
75
+ if not path or not os.path.isabs(path):
76
+ return False
77
+ rp = os.path.realpath(path)
78
+ return rp == _WORKSPACE_ROOT or rp.startswith(_WORKSPACE_ROOT + os.sep)
79
+
80
+
81
+ def _within_self_workspace(path: str, self_ws: str) -> bool:
82
+ """宿主绝对路径是否落在当前用户自己的工作目录内。"""
83
+ rp = os.path.realpath(path)
84
+ self_rp = os.path.realpath(self_ws).rstrip(os.sep)
85
+ return rp == self_rp or rp.startswith(self_rp + os.sep)
86
+
87
+
88
+ def _to_virtual(path: str, self_ws: str) -> str:
89
+ """把「自己工作目录内的宿主绝对路径」改写为沙箱虚拟路径(/ 开头 POSIX)。"""
90
+ rp = os.path.realpath(path)
91
+ self_rp = os.path.realpath(self_ws)
92
+ if rp == self_rp:
93
+ return "/"
94
+ rel = os.path.relpath(rp, self_rp)
95
+ return "/" + rel.replace("\\", "/")
96
+
97
+
98
+ class SandboxPathGuardMiddleware(AgentMiddleware):
99
+ """规范化/拦截沙箱工具调用里的宿主绝对路径。
100
+
101
+ 仅实现 awrap_tool_call(异步链路),与 SkillWriteGuardMiddleware 对齐。
102
+ 构造时传入 user_id,据此算出「本人工作目录」前缀,区分改写 vs 拦截。
103
+ """
104
+
105
+ def __init__(self, user_id: str):
106
+ self._user_id = user_id or ""
107
+ self._self_ws = os.path.join(WORKSPACE_BASE, _sanitize_user_id(self._user_id)) \
108
+ if self._user_id else ""
109
+
110
+ async def awrap_tool_call(self, request: ToolCallRequest, handler):
111
+ tc = request.tool_call
112
+ name = tc.get("name")
113
+ args = tc.get("args", {})
114
+ if not isinstance(args, dict):
115
+ return await handler(request)
116
+
117
+ # 1) 结构化路径工具:read/write/edit/ls/grep/glob/get_share_url
118
+ field = _PATH_TOOLS.get(name)
119
+ if field:
120
+ raw = args.get(field)
121
+ if isinstance(raw, str) and _is_host_absolute(raw):
122
+ if self._self_ws and _within_self_workspace(raw, self._self_ws):
123
+ # 自己工作目录内的绝对路径 → 改写为虚拟路径放行(零往返)
124
+ new_tc = dict(tc)
125
+ new_args = dict(args)
126
+ new_args[field] = _to_virtual(raw, self._self_ws)
127
+ new_tc["args"] = new_args
128
+ new_request = dataclasses.replace(request, tool_call=new_tc)
129
+ return await handler(new_request)
130
+ # 越界/跨用户宿主绝对路径 → 拦截
131
+ return ToolMessage(content=_DENIED_MSG, name=name,
132
+ tool_call_id=tc.get("id", ""), status="error")
133
+ return await handler(request)
134
+
135
+ # 2) execute(裸 shell):命令串里的宿主绝对路径无法安全改写,只能拦
136
+ if name == "execute":
137
+ command = args.get("command", "")
138
+ if isinstance(command, str) and _HOST_SANDBOX_RE.search(command):
139
+ return ToolMessage(content=_DENIED_MSG, name="execute",
140
+ tool_call_id=tc.get("id", ""), status="error")
141
+ return await handler(request)
142
+
143
+ return await handler(request)
@@ -228,8 +228,8 @@ class SensitiveGuardMiddleware(AgentMiddleware):
228
228
  state: Optional[DowngradeState] = None,
229
229
  # 应用层可覆盖检测提示词;未传(None)用 DEFAULT_DETECT_PROMPT
230
230
  detect_prompt: Optional[str] = None,
231
- # 命中敏感后的动作:"downgrade"=降级内部模型继续;"block"=直接阻断(不调任何模型)
232
- action: str = "downgrade",
231
+ # 命中敏感后的动作:"allow"=不检测放行;"downgrade"=降级内部模型继续;"block"=直接阻断(不调任何模型)
232
+ action: str = "allow",
233
233
  # 阻断模式下的异步提示回调(与 on_downgrade 区分文案);downgrade 模式不用
234
234
  on_block: Optional[Callable[[], Awaitable[None]]] = None,
235
235
  # 测试注入:绕过懒加载的真实 get_llm
@@ -241,7 +241,8 @@ class SensitiveGuardMiddleware(AgentMiddleware):
241
241
  self._internal_name = internal_model_name
242
242
  self._on_downgrade = on_downgrade
243
243
  self._on_block = on_block
244
- self._action = action if action in ("downgrade", "block") else "downgrade"
244
+ # 默认 allow(不检测):应用层未显式指定时按"放行"处理,避免误伤。
245
+ self._action = action if action in ("downgrade", "block", "allow") else "allow"
245
246
  self._enabled = enabled
246
247
  self._state = state or DowngradeState()
247
248
  self._detect_prompt = detect_prompt or DEFAULT_DETECT_PROMPT
@@ -349,8 +350,9 @@ class SensitiveGuardMiddleware(AgentMiddleware):
349
350
  request: ModelRequest[ContextT],
350
351
  handler: Callable[[ModelRequest[ContextT]], Awaitable[ModelResponse[ResponseT]]],
351
352
  ) -> ModelResponse[ResponseT]:
352
- # (a) 关闭 / 内部 tier:纯放行,不检测(避免内部模型检内部模型 + token)
353
- if not self._enabled or self._model_tier == "internal":
353
+ # (a) 关闭 / 内部 tier / allow 模式:纯放行,不检测。
354
+ # allow = 应用层完全关闭敏感检测(不调用 detector、不阻断、不降级),零开销。
355
+ if not self._enabled or self._model_tier == "internal" or self._action == "allow":
354
356
  return await handler(request)
355
357
 
356
358
  # (b) 本会话已命中敏感
@@ -133,7 +133,7 @@ class TeamConfig(BaseModel):
133
133
  sensitive_guard: bool = True # 是否启用敏感信息检测守卫
134
134
  internal_model_name: Optional[str] = None # 敏感降级目标内部模型名(应用层透传)
135
135
  sensitive_detect_prompt: Optional[str] = None # 敏感检测提示词(应用层覆盖)
136
- sensitive_action: str = "downgrade" # "downgrade"=降级继续;"block"=阻断
136
+ sensitive_action: str = "allow" # "allow"=不检测放行;"downgrade"=降级继续;"block"=阻断
137
137
 
138
138
  coordinator_prompt: str = ""
139
139
  coordinator_name: str = "项目经理"
@@ -361,7 +361,10 @@ class FileOperationsMixin:
361
361
  return ReadResult(error=f"File '{file_path}': unexpected server response: {detail}")
362
362
  if result.get("error"):
363
363
  err_msg = result['error']
364
- if 'not found' in err_msg:
364
+ if 'not found' in err_msg or 'outside the sandbox' in err_msg:
365
+ # not found 是 agent 正常试探;outside the sandbox 是安全守卫拦截
366
+ # agent 用了宿主绝对路径,属正常 tool-error(会自愈改用虚拟路径)。
367
+ # 降级为 warning,避免把正常工具错误刷成 ERROR 级。
365
368
  SYLogger.warning(f"[Sandbox] 异步读取文件未找到: {err_msg}")
366
369
  else:
367
370
  SYLogger.error(f"[Sandbox] 异步读取文件失败: {err_msg}")
@@ -53,9 +53,19 @@ class LLMLogger(AsyncCallbackHandler):
53
53
  self._log_result(result, i+1)
54
54
 
55
55
  async def on_llm_error(self, error: Exception, **kwargs: Any) -> None:
56
+ import asyncio
57
+ # GeneratorExit: 消费方提前关闭生成器(如 SSE 客户端断开)
56
58
  if isinstance(error, GeneratorExit):
57
59
  SYLogger.info("LLM生成器正常关闭")
58
60
  return
61
+ # CancelledError: LangGraph 的 AsyncBackgroundExecutor 在图执行结束/取消时,
62
+ # 用 task.cancel(sentinel) 取消正在运行的模型任务,sentinel 是裸 object(),
63
+ # str() 即 "<object object at 0x...>"。这不是真正的 LLM 调用失败,
64
+ # 降级为 INFO,避免污染 ERROR 日志(CancelledError 属 BaseException)。
65
+ if isinstance(error, asyncio.CancelledError):
66
+ SYLogger.info(
67
+ f"LLM调用被取消(流式任务取消): {str(error) or '(无消息)'}")
68
+ return
59
69
  SYLogger.error(f"LLM调用出错: {str(error)}")
60
70
 
61
71
  # ------------------------------
@@ -0,0 +1,169 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Token 计数与 max_tokens 动态调整工具函数
4
+
5
+ 统一供 LLMWithTokenTracking、LLMWithAutoTokenUsage、DeepAgent 等模块使用,
6
+ 避免同一逻辑分散在多处。
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import List, Optional
12
+
13
+ from langchain_core.messages import BaseMessage, AIMessage
14
+
15
+ # cl100k_base 对国产/第三方模型 tokenizer 存在系统性低估(尤其中文),
16
+ # 用作纯估算时乘以此系数修正,使估算值偏向保守(宁可高估 input,不可低估)。
17
+ _TIKTOKEN_SAFETY_FACTOR = 1.15
18
+ _FORMAT_OVERHEAD_PER_MSG = 4 # 每条消息的 <im_start>role/...<im_end>\n 等格式开销
19
+
20
+
21
+ def _count_text_tokens(content) -> int:
22
+ """对单条消息 content 估算 token 数(cl100k_base × 1.15 安全系数)。
23
+
24
+ content 可能是 str(纯文本)或 list(多模态 content block)。
25
+ """
26
+ if isinstance(content, str):
27
+ text = content
28
+ elif isinstance(content, list):
29
+ text = ""
30
+ for part in content:
31
+ if isinstance(part, str):
32
+ text += part
33
+ elif isinstance(part, dict):
34
+ text += str(part)
35
+ else:
36
+ text = str(content) if content is not None else ""
37
+
38
+ # 优先 tiktoken cl100k_base
39
+ try:
40
+ import tiktoken
41
+ enc = tiktoken.get_encoding("cl100k_base")
42
+ n = len(enc.encode(text))
43
+ return int(n * _TIKTOKEN_SAFETY_FACTOR)
44
+ except Exception:
45
+ pass
46
+
47
+ # 回退:字符估算(中文 1.5 chars/token,英文 3.5 chars/token)
48
+ non_ascii = sum(1 for c in text if ord(c) > 127)
49
+ ratio = non_ascii / max(len(text), 1)
50
+ chars_per_token = 1.5 if ratio > 0.3 else 3.5
51
+ return int(len(text) / chars_per_token)
52
+
53
+
54
+ def _usage_input_tokens(msg: BaseMessage) -> Optional[int]:
55
+ """从消息的 usage_metadata 提取 input_tokens(API 真实返回值)。
56
+
57
+ 仅 AIMessage 会携带 usage_metadata。返回 None 表示无锚点。
58
+ """
59
+ um = getattr(msg, "usage_metadata", None)
60
+ if not isinstance(um, dict):
61
+ return None
62
+ n = um.get("input_tokens")
63
+ return int(n) if isinstance(n, (int, float)) else None
64
+
65
+
66
+ def count_messages_tokens_accurate(messages: List[BaseMessage]) -> int:
67
+ """精确估算 messages 的 input token 数(hybrid 策略)。
68
+
69
+ 背景:原 ``count_messages_tokens`` 用 cl100k_base 对整段历史重新估算,
70
+ 对国产模型 tokenizer 系统性低估 ~22%(如 68609 真实 tokens 被估成 ~53K),
71
+ 导致 clamp 误判可用空间,max_tokens 放过大 → 400 报错。
72
+
73
+ 策略(真实锚点 + 增量估算):
74
+ 1. 倒序找最近一条带 ``usage_metadata.input_tokens`` 的 AIMessage,
75
+ 该值是模型上轮回复时 API 返回的真实 input token 数(精确,非估算)。
76
+ 2. 真实基数 = 该锚点 input_tokens;其后新增的消息用 cl100k×1.15 估算增量。
77
+ 3. 无锚点(首回合 / 历史被压缩)时,回退到整段 cl100k×1.15 估算。
78
+
79
+ 这样误差从「整段 22%」缩到「新增几十~几百 token 的几个百分点」,
80
+ 配合 clamp 的 0.90 安全系数 + buffer,几乎不会漏判超限。
81
+
82
+ Args:
83
+ messages: LangChain 消息列表。
84
+
85
+ Returns:
86
+ 估算的 input token 总数。
87
+ """
88
+ if not messages:
89
+ return 0
90
+
91
+ # 1) 找最近一个 usage 锚点
92
+ anchor_idx = -1
93
+ anchor_input = None
94
+ for i in range(len(messages) - 1, -1, -1):
95
+ msg = messages[i]
96
+ if isinstance(msg, AIMessage):
97
+ n = _usage_input_tokens(msg)
98
+ if n is not None:
99
+ anchor_idx = i
100
+ anchor_input = n
101
+ break
102
+
103
+ if anchor_idx >= 0:
104
+ # 2) 真实基数 + 其后新增消息的增量估算
105
+ delta_tokens = 0
106
+ for msg in messages[anchor_idx + 1:]:
107
+ delta_tokens += _count_text_tokens(getattr(msg, "content", "")) + _FORMAT_OVERHEAD_PER_MSG
108
+ return anchor_input + delta_tokens
109
+
110
+ # 3) 无锚点:整段 cl100k×1.15 估算
111
+ total = 0
112
+ for msg in messages:
113
+ total += _count_text_tokens(getattr(msg, "content", "")) + _FORMAT_OVERHEAD_PER_MSG
114
+ return total
115
+
116
+
117
+ def count_messages_tokens(messages: List[BaseMessage]) -> int:
118
+ """估算 messages 的 token 数(向后兼容入口)。
119
+
120
+ .. deprecated::
121
+ 内部已委托给 :func:`count_messages_tokens_accurate`(hybrid 精确估算)。
122
+ 新代码请直接使用 ``count_messages_tokens_accurate``。
123
+ """
124
+ return count_messages_tokens_accurate(messages)
125
+
126
+
127
+ def clamp_max_tokens(
128
+ model,
129
+ messages: List[BaseMessage],
130
+ *,
131
+ context_window: int,
132
+ max_output_tokens: int,
133
+ buffer: int = 8192,
134
+ min_output: int = 1024,
135
+ safety_factor: float = 0.90,
136
+ ) -> int:
137
+ """动态调整模型的 max_tokens,确保 input + max_output 不超过上下文窗口。
138
+
139
+ 每次调用前精确估算当前 input tokens,计算可用空间,
140
+ 将 model.max_tokens = min(max_output_tokens, effective_context - input - buffer),
141
+ 最低保底 min_output。
142
+
143
+ 三道防线(任一即可挡住超限,叠加更稳):
144
+ 1. **精确估算**:用 :func:`count_messages_tokens_accurate` 的 hybrid 策略
145
+ (真实 usage 锚点 + 增量 cl100k×1.15),把整段 22% 的低估误差降到 ~几个百分点。
146
+ 2. **安全系数**:context_window × 0.90 作为有效上限,吸收「配置值虚高 /
147
+ tokenizer 偏差 / 锚点缺失回退估算」等残余误差(默认 0.90)。
148
+ 3. **buffer**:再扣除 buffer(默认 8192)token 余量。
149
+
150
+ Args:
151
+ model: 拥有 ``max_tokens`` 属性的 ChatModel 实例。
152
+ messages: 即将发送给模型的消息列表。
153
+ context_window: 模型上下文窗口大小(来自 LLMConfig.maxTokens)。
154
+ max_output_tokens: 配置的最大输出 token 数(来自 LLMConfig.maxOutputTokens)。
155
+ buffer: 保留的余量 token 数,默认 8192。
156
+ min_output: 最小输出 token 数保底值,默认 1024。
157
+ safety_factor: 上下文窗口的有效系数,默认 0.90
158
+ (防止配置 maxTokens 大于模型真实窗口,如配 200000 实际 196608)。
159
+
160
+ Returns:
161
+ 调整后的 max_tokens 值。
162
+ """
163
+ # 有效上下文窗口 = 配置值 × safety_factor
164
+ effective_context = int(context_window * safety_factor)
165
+ input_est = count_messages_tokens_accurate(messages)
166
+ available = effective_context - input_est - buffer
167
+ dynamic_max = min(max_output_tokens, max(available, min_output))
168
+ model.max_tokens = dynamic_max
169
+ return dynamic_max
@@ -608,9 +608,18 @@ def setup_sandbox_handler(app: FastAPI, config: dict = None):
608
608
  def _read():
609
609
  if not os.path.isfile(file_path):
610
610
  if os.path.isabs(original_path) and os.path.isfile(original_path):
611
+ # 原始路径是宿主绝对路径且真实存在,但解析后落在用户工作目录外
612
+ # (典型成因:上下文里混入了别的用户的绝对路径,或 agent 自行拼接了
613
+ # /data/sycommon_sandbox/... 形式的宿主路径)。
614
+ # 提示用沙箱虚拟相对路径读,且**只透出 basename**——不回显完整
615
+ # 宿主绝对路径,避免把路径结构(含其他用户名)泄回 LLM/上下文。
616
+ SYLogger.info(
617
+ f"[Sandbox Server] 读取命中沙箱外路径: {original_path} "
618
+ f"(user={req.user_id})")
611
619
  return ReadResponse(
612
- error=f"File '{original_path}' exists but is outside sandbox. "
613
- f"Try reading from sandbox path: {os.path.basename(original_path)}",
620
+ error=f"File exists on host but is outside the sandbox workspace. "
621
+ f"Use a sandbox-relative path (e.g. /skills/...) instead of a "
622
+ f"host-absolute path; try reading: {os.path.basename(original_path)}",
614
623
  content=None
615
624
  )
616
625
  return ReadResponse(error=f"File '{file_path}' not found", content=None)
@@ -24,6 +24,73 @@ from langchain_core.outputs import ChatResult, ChatGeneration
24
24
  from sycommon.config.LLMConfig import LLMConfig
25
25
  from sycommon.llm.llm_with_token_tracking import LLMWithTokenTracking
26
26
  from sycommon.llm.usage_token import LLMWithAutoTokenUsage
27
+ from sycommon.llm.token_utils import (
28
+ count_messages_tokens_accurate,
29
+ count_messages_tokens,
30
+ clamp_max_tokens,
31
+ )
32
+
33
+
34
+ # ============== hybrid 精确估算单测(token_utils)==============
35
+
36
+
37
+ class TestHybridTokenEstimation:
38
+ """验证真实 usage 锚点 + 增量估算策略"""
39
+
40
+ def test_anchor_plus_delta(self):
41
+ """有 usage 锚点时:真实 input_tokens + 其后新增消息增量"""
42
+ # 锚点:上轮 AI 回复,API 返回真实 input_tokens=68609(报错场景复现)
43
+ messages = [
44
+ SystemMessage(content="你是数字员工"),
45
+ AIMessage(content="历史回复内容" * 100,
46
+ usage_metadata={"input_tokens": 68609, "output_tokens": 3000, "total_tokens": 71609}),
47
+ HumanMessage(content="请基于上面的内容帮我做数据分析报告"),
48
+ ]
49
+ est = count_messages_tokens_accurate(messages)
50
+ # 真实基数 68609 + 新增 HumanMessage 增量(几十~百 token)
51
+ assert est >= 68609
52
+ assert est < 69000 # 增量不会太离谱
53
+
54
+ def test_no_anchor_fallback_with_safety_factor(self):
55
+ """无锚点(首回合):整段 cl100k × 1.15 保守估算"""
56
+ messages = [HumanMessage(content="这是一段测试文本。" * 100)]
57
+ est = count_messages_tokens_accurate(messages)
58
+ # cl100k 算 "这是一段测试文本。"=8 tokens,×100=800,×1.15≈920 + 格式开销
59
+ assert est > 800 # 比 cl100k 裸值更保守
60
+
61
+ def test_legacy_alias_matches_accurate(self):
62
+ """count_messages_tokens(向后兼容)应等价于 accurate 版本"""
63
+ messages = [
64
+ AIMessage(content="x", usage_metadata={"input_tokens": 1000, "output_tokens": 0, "total_tokens": 1000}),
65
+ HumanMessage(content="y"),
66
+ ]
67
+ assert count_messages_tokens(messages) == count_messages_tokens_accurate(messages)
68
+
69
+ def test_empty_messages(self):
70
+ assert count_messages_tokens_accurate([]) == 0
71
+
72
+ def test_prevents_400_on_real_error_scenario(self):
73
+ """回归:复现线上 68609 真实 input 场景,clamp 后 input+output 不超真实窗口
74
+
75
+ 线上 bug:cl100k 把 68609 估成 ~53K,clamp 放过 128000 output,
76
+ 导致 128000+68609=196609 > 196608 → 400 报错。
77
+ """
78
+ class FakeModel:
79
+ model = "digital-worker-external"
80
+ max_tokens = 128000
81
+
82
+ messages = [
83
+ AIMessage(content="历史" * 5000,
84
+ usage_metadata={"input_tokens": 68609, "output_tokens": 3000, "total_tokens": 71609}),
85
+ HumanMessage(content="继续分析"),
86
+ ]
87
+ m = FakeModel()
88
+ dyn = clamp_max_tokens(m, messages,
89
+ context_window=200000, # 配置值虚高,真实 196608
90
+ max_output_tokens=128000)
91
+ # 真实 input 68609 + clamp 后的 output 必须 ≤ 真实窗口 196608
92
+ assert 68609 + dyn <= 196608, \
93
+ f"仍会 400: 68609(input) + {dyn}(output) = {68609 + dyn} > 196608"
27
94
 
28
95
 
29
96
  def _make_llm_config(max_tokens=196608, max_output=128000):
@@ -84,30 +151,32 @@ class TestLLMWithTokenTrackingClamp:
84
151
  assert llm.max_tokens == 128000
85
152
 
86
153
  def test_large_input_reduces_max_output(self):
87
- """input 大时,max_tokens 自动缩小"""
154
+ """input 大时,max_tokens 自动缩小(仍高于 1024 保底)"""
88
155
  llm = MockChatModel(max_tokens=128000)
89
156
  config = _make_llm_config(max_tokens=196608, max_output=128000)
90
157
  wrapper = LLMWithTokenTracking(llm=llm, llmConfig=config)
91
158
 
92
- # 模拟 ~100K 字符 ≈ ~50K tokens 的 input
159
+ # 100K 字符 ≈ cl100k 100K tokens × 1.15 ≈ 115K tokens 的 input
160
+ # ("这是一段测试文本。" 9字符=8tokens,近乎 1:1,并非 0.5:1)
93
161
  messages = _make_long_messages(100000)
94
162
  wrapper._clamp_max_tokens(messages)
95
163
 
96
- # available = 196608 - ~50K - 4096142K, min(128000, 142K) = 128000
97
- assert llm.max_tokens == 128000
164
+ # available = 176947 - ~115K - 819253K min(128000, 53K) 53K
165
+ assert llm.max_tokens < 128000
166
+ assert llm.max_tokens > 1024 # 至少保留 1024
98
167
 
99
168
  def test_near_limit_input_clamps_hard(self):
100
- """input 接近上限时,max_tokens 被大幅压缩"""
169
+ """input 接近上限时,max_tokens 被大幅压缩(但仍高于保底)"""
101
170
  llm = MockChatModel(max_tokens=128000)
102
171
  config = _make_llm_config(max_tokens=196608, max_output=128000)
103
172
  wrapper = LLMWithTokenTracking(llm=llm, llmConfig=config)
104
173
 
105
- # 模拟 ~160K 字符 ≈ ~80K tokens 的 input
106
- messages = _make_long_messages(160000)
174
+ # ~130K 字符 ≈ 150K tokens 的 input
175
+ messages = _make_long_messages(130000)
107
176
  wrapper._clamp_max_tokens(messages)
108
177
 
109
- # available = 196608 - ~80K - 4096112K, min(128000, 112K) = ~112K
110
- assert llm.max_tokens < 128000
178
+ # available 176947 - ~150K - 819218K
179
+ assert llm.max_tokens < 50000
111
180
  assert llm.max_tokens > 1024 # 至少保留 1024
112
181
 
113
182
  def test_extremely_large_input_floors_at_1024(self):
@@ -168,7 +237,8 @@ class TestLLMWithAutoTokenUsageClamp:
168
237
  config = _make_llm_config(max_tokens=196608, max_output=128000)
169
238
  wrapper = LLMWithAutoTokenUsage(llm=llm, langfuse=None, llmConfig=config, summary_prompt=None)
170
239
 
171
- messages = _make_long_messages(160000)
240
+ # ~130K 字符 ≈ 150K tokens 的 input,会被压到 5 万档
241
+ messages = _make_long_messages(130000)
172
242
  wrapper._clamp_max_tokens(messages)
173
243
 
174
244
  assert llm.max_tokens < 128000
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.7a15
3
+ Version: 0.2.7a17
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -149,6 +149,7 @@ src/sycommon/agent/acp/tool.py
149
149
  src/sycommon/agent/mcp/__init__.py
150
150
  src/sycommon/agent/mcp/models.py
151
151
  src/sycommon/agent/mcp/tool_loader.py
152
+ src/sycommon/agent/middleware/sandbox_path_guard.py
152
153
  src/sycommon/agent/middleware/sensitive_guard.py
153
154
  src/sycommon/agent/middleware/sitecustomize.py
154
155
  src/sycommon/agent/middleware/skill_api_whitelist.py
@@ -35,8 +35,9 @@ class _FakeRequest:
35
35
 
36
36
 
37
37
  def _mk_mw(detector_response: SensitiveCheck, model_tier="external",
38
- on_downgrade=None, state=None):
39
- """构造 middleware,detector 直接返回原始文本(_detect 自行解析 {…})。"""
38
+ on_downgrade=None, state=None, action="downgrade"):
39
+ """构造 middleware,detector 直接返回原始文本(_detect 自行解析 {…})。
40
+ 默认 action=downgrade(命中降级)以匹配多数测试断言。"""
40
41
  import json as _json
41
42
 
42
43
  def _to_text(resp):
@@ -55,6 +56,7 @@ def _mk_mw(detector_response: SensitiveCheck, model_tier="external",
55
56
  model_tier=model_tier,
56
57
  on_downgrade=on_downgrade,
57
58
  state=state,
59
+ action=action,
58
60
  _detector=_FakeDetector(),
59
61
  _internal_raw=_FakeModel(),
60
62
  )