sycommon-python-lib 0.2.7a44__tar.gz → 0.2.7a45__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 (338) hide show
  1. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/PKG-INFO +1 -1
  2. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/pyproject.toml +1 -1
  3. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/file_ops.py +4 -5
  4. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/http_sandbox_backend.py +152 -69
  5. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/minio_sync.py +71 -14
  6. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/sandbox.py +48 -18
  7. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/sandbox.py +1 -8
  8. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
  9. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/README.md +0 -0
  10. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/setup.cfg +0 -0
  11. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/__init__.py +0 -0
  12. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/cli.py +0 -0
  13. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/core/__init__.py +0 -0
  14. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/core/console.py +0 -0
  15. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/core/models.py +0 -0
  16. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/core/project.py +0 -0
  17. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/core/utils.py +0 -0
  18. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/__init__.py +0 -0
  19. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/README.md.tpl +0 -0
  20. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/__init__.py +0 -0
  21. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/__init__.py.tpl +0 -0
  22. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/main_agent.py.tpl +0 -0
  23. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/nodes/__init__.py.tpl +0 -0
  24. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/nodes/example_node.py.tpl +0 -0
  25. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/states/__init__.py.tpl +0 -0
  26. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/states/agent_state.py.tpl +0 -0
  27. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/api/__init__.py.tpl +0 -0
  28. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/api/query.py.tpl +0 -0
  29. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/api/sse/__init__.py.tpl +0 -0
  30. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/api/sse/agent.py.tpl +0 -0
  31. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/app.py.tpl +0 -0
  32. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/client/__init__.py.tpl +0 -0
  33. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/db/__init__.py.tpl +0 -0
  34. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/db/model/__init__.py.tpl +0 -0
  35. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/db/model/entity.py.tpl +0 -0
  36. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/db/service.py.tpl +0 -0
  37. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/model/__init__.py.tpl +0 -0
  38. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/model/parse.py.tpl +0 -0
  39. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/tools/__init__.py.tpl +0 -0
  40. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/tools/mq.py.tpl +0 -0
  41. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/.env.tpl +0 -0
  42. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/.gitignore.tpl +0 -0
  43. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/Dockerfile.tpl +0 -0
  44. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/README.md.tpl +0 -0
  45. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/__init__.py +0 -0
  46. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/app.py.tpl +0 -0
  47. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/app.yaml.tpl +0 -0
  48. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/client/FileServiceClient.py.tpl +0 -0
  49. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/client/__init__.py.tpl +0 -0
  50. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/model/__init__.py.tpl +0 -0
  51. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/model/file_info.py.tpl +0 -0
  52. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/requirements.txt.tpl +0 -0
  53. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/README.md.tpl +0 -0
  54. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/__init__.py +0 -0
  55. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/app.py.tpl +0 -0
  56. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/commands/__init__.py.tpl +0 -0
  57. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/commands/hello.py.tpl +0 -0
  58. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/pyproject.toml.tpl +0 -0
  59. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/tools/__init__.py.tpl +0 -0
  60. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/README.md.tpl +0 -0
  61. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/__init__.py +0 -0
  62. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/api/__init__.py.tpl +0 -0
  63. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/api/echo.py.tpl +0 -0
  64. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/api/sse/__init__.py.tpl +0 -0
  65. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/api/sse/echo.py.tpl +0 -0
  66. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/app.py.tpl +0 -0
  67. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/client/__init__.py.tpl +0 -0
  68. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/model/__init__.py.tpl +0 -0
  69. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/tools/__init__.py.tpl +0 -0
  70. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/tools/mq.py.tpl +0 -0
  71. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/nexus/__init__.py +0 -0
  72. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/__init__.py +0 -0
  73. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/__main__.py +0 -0
  74. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/__init__.py +0 -0
  75. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/config.py +0 -0
  76. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/executor.py +0 -0
  77. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/registry.py +0 -0
  78. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/server.py +0 -0
  79. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/agents/__init__.py +0 -0
  80. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/agents/factory.py +0 -0
  81. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/agents/prompts.py +0 -0
  82. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/__init__.py +0 -0
  83. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/browser.py +0 -0
  84. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/__init__.py +0 -0
  85. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/console.py +0 -0
  86. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/dom.py +0 -0
  87. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/network.py +0 -0
  88. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/page_errors.py +0 -0
  89. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/performance.py +0 -0
  90. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/screenshot.py +0 -0
  91. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/client.py +0 -0
  92. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/protocol.py +0 -0
  93. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/repl.py +0 -0
  94. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/cli.py +0 -0
  95. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/__init__.py +0 -0
  96. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/acp_cmd.py +0 -0
  97. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/cdp_cmd.py +0 -0
  98. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/chat_cmd.py +0 -0
  99. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/create_cmd.py +0 -0
  100. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/evaluate_cmd.py +0 -0
  101. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/init_cmd.py +0 -0
  102. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/memory_cmd.py +0 -0
  103. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/resume_cmd.py +0 -0
  104. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/rollback_cmd.py +0 -0
  105. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/run_cmd.py +0 -0
  106. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/core/__init__.py +0 -0
  107. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/core/backend.py +0 -0
  108. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/core/config.py +0 -0
  109. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/core/display.py +0 -0
  110. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/core/git_integration.py +0 -0
  111. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/core/llm.py +0 -0
  112. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/core/state.py +0 -0
  113. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/evaluate/__init__.py +0 -0
  114. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/evaluate/api_evaluator.py +0 -0
  115. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/__init__.py +0 -0
  116. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/compressor.py +0 -0
  117. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/full.py +0 -0
  118. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/hot.py +0 -0
  119. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/manager.py +0 -0
  120. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/warm.py +0 -0
  121. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/mode/__init__.py +0 -0
  122. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/mode/create.py +0 -0
  123. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/mode/optimize.py +0 -0
  124. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/models/__init__.py +0 -0
  125. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/models/config_models.py +0 -0
  126. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/__init__.py +0 -0
  127. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/baseline_tests.py +0 -0
  128. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/checkpoint.py +0 -0
  129. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/convergence.py +0 -0
  130. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/diagnosis.py +0 -0
  131. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/engine.py +0 -0
  132. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/environment.py +0 -0
  133. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/experience.py +0 -0
  134. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/harness_prompts.py +0 -0
  135. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/history.py +0 -0
  136. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/optimization_logger.py +0 -0
  137. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/pre_validation.py +0 -0
  138. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/reward.py +0 -0
  139. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/strategy_bandit.py +0 -0
  140. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/strategy_generator.py +0 -0
  141. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/strategy_prompts.py +0 -0
  142. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/simple_chat_agent.py +0 -0
  143. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycli/skills/__init__.py +0 -0
  144. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/__init__.py +0 -0
  145. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/__init__.py +0 -0
  146. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/__init__.py +0 -0
  147. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/client.py +0 -0
  148. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/fetch.py +0 -0
  149. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/ssh_init.py +0 -0
  150. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/tool.py +0 -0
  151. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/agent_manager.py +0 -0
  152. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/chat_events.py +0 -0
  153. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/deep_agent.py +0 -0
  154. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/mcp/__init__.py +0 -0
  155. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/mcp/models.py +0 -0
  156. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/mcp/tool_loader.py +0 -0
  157. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/sandbox_path_guard.py +0 -0
  158. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/sensitive_guard.py +0 -0
  159. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/sitecustomize.py +0 -0
  160. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/skill_api_whitelist.py +0 -0
  161. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/skill_wl_check.py +0 -0
  162. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/skill_write_guard.py +0 -0
  163. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/multi_agent_team.py +0 -0
  164. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/resume_compactor.py +0 -0
  165. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/__init__.py +0 -0
  166. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/consistent_hash.py +0 -0
  167. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
  168. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
  169. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/session.py +0 -0
  170. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/summarization_utils.py +0 -0
  171. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/__init__.py +0 -0
  172. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/ldap_service.py +0 -0
  173. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/oa_cache.py +0 -0
  174. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/oa_crypto.py +0 -0
  175. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/oa_service.py +0 -0
  176. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/wecom_ldap_service.py +0 -0
  177. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/ACPAgentConfig.py +0 -0
  178. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/Config.py +0 -0
  179. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/DatabaseConfig.py +0 -0
  180. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/ElasticsearchConfig.py +0 -0
  181. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/EmbeddingConfig.py +0 -0
  182. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/LLMConfig.py +0 -0
  183. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/LangfuseConfig.py +0 -0
  184. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/MQConfig.py +0 -0
  185. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/PgConfig.py +0 -0
  186. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/RedisConfig.py +0 -0
  187. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/RerankerConfig.py +0 -0
  188. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/SentryConfig.py +0 -0
  189. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/SkillApiWhitelistConfig.py +0 -0
  190. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/XxlJobConfig.py +0 -0
  191. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/__init__.py +0 -0
  192. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/config_change_notifier.py +0 -0
  193. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/async_base_db_service.py +0 -0
  194. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/async_database_service.py +0 -0
  195. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/base_db_service.py +0 -0
  196. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/database_service.py +0 -0
  197. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/elasticsearch_service.py +0 -0
  198. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/pg_checkpoint_service.py +0 -0
  199. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/redis_service.py +0 -0
  200. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/resilient_pg_saver.py +0 -0
  201. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/token_usage_db_service.py +0 -0
  202. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/health/__init__.py +0 -0
  203. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/health/health_check.py +0 -0
  204. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/health/metrics.py +0 -0
  205. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/health/ping.py +0 -0
  206. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/heartbeat_process/__init__.py +0 -0
  207. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
  208. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
  209. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
  210. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/__init__.py +0 -0
  211. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/embedding.py +0 -0
  212. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/get_llm.py +0 -0
  213. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/llm_logger.py +0 -0
  214. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/llm_tokens.py +0 -0
  215. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/llm_with_token_tracking.py +0 -0
  216. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
  217. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/output_fixing_runnable.py +0 -0
  218. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/struct_token.py +0 -0
  219. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/sy_langfuse.py +0 -0
  220. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
  221. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/tiktoken_cache/fb374d419588a4632f3f557e76b4b70aebbca790 +0 -0
  222. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/token_usage_es_service.py +0 -0
  223. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
  224. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/token_utils.py +0 -0
  225. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/usage_token.py +0 -0
  226. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/__init__.py +0 -0
  227. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/async_sql_logger.py +0 -0
  228. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/kafka_log.py +0 -0
  229. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/log_masker.py +0 -0
  230. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/logger_levels.py +0 -0
  231. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/logger_wrapper.py +0 -0
  232. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/process_logger.py +0 -0
  233. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/sql_logger.py +0 -0
  234. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/mcp_server/__init__.py +0 -0
  235. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/mcp_server/server.py +0 -0
  236. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/__init__.py +0 -0
  237. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/context.py +0 -0
  238. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/cors.py +0 -0
  239. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/docs.py +0 -0
  240. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/exception.py +0 -0
  241. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/middleware.py +0 -0
  242. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/monitor_memory.py +0 -0
  243. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/mq.py +0 -0
  244. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/timeout.py +0 -0
  245. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/token_tracking.py +0 -0
  246. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/tool_result_truncation.py +0 -0
  247. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/traceid.py +0 -0
  248. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/__init__.py +0 -0
  249. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/base_http.py +0 -0
  250. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/log.py +0 -0
  251. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/mcp_server_config.py +0 -0
  252. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/mqlistener_config.py +0 -0
  253. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/mqmsg_model.py +0 -0
  254. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/mqsend_config.py +0 -0
  255. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/sso_user.py +0 -0
  256. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/token_usage.py +0 -0
  257. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/token_usage_mysql.py +0 -0
  258. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/xxljob_handler_config.py +0 -0
  259. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/notice/__init__.py +0 -0
  260. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/notice/uvicorn_monitor.py +0 -0
  261. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/notice/wecom_message.py +0 -0
  262. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
  263. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
  264. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
  265. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
  266. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
  267. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
  268. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
  269. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
  270. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
  271. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/sentry/__init__.py +0 -0
  272. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/sentry/sy_sentry.py +0 -0
  273. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/services.py +0 -0
  274. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/sse/__init__.py +0 -0
  275. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/sse/event.py +0 -0
  276. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/sse/sse.py +0 -0
  277. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/__init__.py +0 -0
  278. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/example.py +0 -0
  279. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/example2.py +0 -0
  280. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/feign.py +0 -0
  281. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/feign_client.py +0 -0
  282. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_client_base.py +0 -0
  283. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_config_manager.py +0 -0
  284. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
  285. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_service.py +0 -0
  286. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
  287. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_service_registration.py +0 -0
  288. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/param.py +0 -0
  289. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/deep_agent_server.py +0 -0
  290. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_consistent_hash.py +0 -0
  291. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_consumer_loss_rootcause.py +0 -0
  292. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_consumer_recovery.py +0 -0
  293. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_deep_agent.py +0 -0
  294. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_dynamic_max_tokens.py +0 -0
  295. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_email.py +0 -0
  296. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_encoding_cache.py +0 -0
  297. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_fix_verification.py +0 -0
  298. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_mcp_server.py +0 -0
  299. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_minimax_reasoning.py +0 -0
  300. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_mq.py +0 -0
  301. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_oa_login.py +0 -0
  302. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_queue_priority_fallback.py +0 -0
  303. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_real_summarization.py +0 -0
  304. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_summarization_config.py +0 -0
  305. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_summarization_real.py +0 -0
  306. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_summary_leak_e2e.py +0 -0
  307. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_upgrade_aio_pika.py +0 -0
  308. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_upgrade_langgraph_stream.py +0 -0
  309. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_upgrade_verification.py +0 -0
  310. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/__init__.py +0 -0
  311. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/async_utils.py +0 -0
  312. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/docs.py +0 -0
  313. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/env.py +0 -0
  314. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/merge_headers.py +0 -0
  315. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/snowflake.py +0 -0
  316. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/syemail.py +0 -0
  317. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/timing.py +0 -0
  318. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/xxljob/__init__.py +0 -0
  319. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon/xxljob/xxljob_service.py +0 -0
  320. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/SOURCES.txt +0 -0
  321. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
  322. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
  323. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
  324. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
  325. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_acp_tool.py +0 -0
  326. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_asyncio_logging.py +0 -0
  327. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_config_change_notifier.py +0 -0
  328. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_hotreload_snapshot.py +0 -0
  329. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_llm_apikey_contextvar.py +0 -0
  330. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_log_masker.py +0 -0
  331. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_resilient_pg_saver.py +0 -0
  332. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_sandbox_path_guard.py +0 -0
  333. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_sensitive_guard.py +0 -0
  334. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_simple_chat_agent.py +0 -0
  335. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_skill_regex_upgrade.py +0 -0
  336. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_skill_write_guard.py +0 -0
  337. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/tests/test_sycli.py +0 -0
  338. {sycommon_python_lib-0.2.7a44 → sycommon_python_lib-0.2.7a45}/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.7a44
3
+ Version: 0.2.7a45
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.7a44"
3
+ version = "0.2.7a45"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -41,11 +41,10 @@ if TYPE_CHECKING:
41
41
  # 沙箱 API 路径前缀
42
42
  SANDBOX_API_PREFIX = "/v1/sandbox"
43
43
 
44
- # 下载/读取的文件大小预检上限(OOM 兜底,env 可调)。
45
- # adownload_files 整包读 + base64 解码,agent 调 download 工具读大文件会把全量拉进内存;
46
- # aread 有行数 limit 但无字节上限。下载/读取前先 astat size,超限返回 error 让 agent
47
- # 改用 head/grep/offset+limit 读。astat 异常 fail-open(warning 后继续,避免额外 RPC 失败阻断)。
48
- MAX_DOWNLOAD_BYTES = int(os.environ.get("SANDBOX_DOWNLOAD_MAX_BYTES", 100 * 1024 * 1024))
44
+ # aread 读取的文件大小预检上限(OOM 兜底,env 可调)。
45
+ # aread /v1/sandbox/read,服务端另有 500KiB 截断(_READ_MAX_OUTPUT_BYTES),客户端 10MB
46
+ # 是早死早超生的预检,防 agent 把大文件读进 LLM 上下文。astat 异常 fail-open。
47
+ # 注:文件搬运(下载/分享/同步)已全部改走流式 adownload_to_file,无大小闸。
49
48
  MAX_READ_BYTES = int(os.environ.get("SANDBOX_READ_MAX_BYTES", 10 * 1024 * 1024))
50
49
 
51
50
 
@@ -15,11 +15,48 @@ import sys
15
15
  import tempfile
16
16
  import threading
17
17
  import requests
18
+ from dataclasses import dataclass
18
19
  from pathlib import Path, PurePosixPath
19
20
  from typing import Optional, List
20
21
 
21
22
  import aiohttp
22
23
 
24
+
25
+ def _run_coro_sync(coro):
26
+ """在当前线程同步跑一个 coroutine(供同步方法调用异步实现)。
27
+
28
+ 已在事件循环里则新起线程跑(避免嵌套 loop);否则 new_event_loop 跑。
29
+ 注意:coro 必须是「在任意线程新 loop 里都能跑」的——不要捕获外层 loop。
30
+ """
31
+ def _run_in_fresh_loop(c):
32
+ loop = asyncio.new_event_loop()
33
+ try:
34
+ return loop.run_until_complete(c)
35
+ finally:
36
+ loop.close()
37
+
38
+ try:
39
+ asyncio.get_running_loop()
40
+ in_loop = True
41
+ except RuntimeError:
42
+ in_loop = False
43
+
44
+ if in_loop:
45
+ import concurrent.futures
46
+ with concurrent.futures.ThreadPoolExecutor(max_workers=1) as ex:
47
+ return ex.submit(_run_in_fresh_loop, coro).result()
48
+ return _run_in_fresh_loop(coro)
49
+
50
+
51
+ @dataclass
52
+ class FileDownloadResult:
53
+ """流式下载结果(adownload_to_file 返回)。不含 content bytes——文件已落盘到 dest。"""
54
+ path: str
55
+ dest: Optional[str] = None
56
+ size: int = 0
57
+ error: Optional[str] = None
58
+
59
+
23
60
  from sycommon.logging.kafka_log import SYLogger
24
61
  from sycommon.agent.sandbox.file_ops import FileOperationsMixin, SANDBOX_API_PREFIX
25
62
 
@@ -29,6 +66,9 @@ from deepagents.backends.protocol import (
29
66
  FileDownloadResponse,
30
67
  FileUploadResponse,
31
68
  )
69
+ # FileDownloadResponse: 框架兼容(deepagents SkillsMiddleware/MemoryMiddleware 内部调
70
+ # backend.adownload_files 批量下载 SKILL.md/memory,需此类型)。流式下载用 FileDownloadResult。
71
+
32
72
 
33
73
  # SSL 上下文
34
74
  try:
@@ -1174,72 +1214,107 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
1174
1214
  path=path, error=str(ex)))
1175
1215
  return results
1176
1216
 
1177
- def download_files(self, paths: List[str]) -> List[FileDownloadResponse]:
1178
- """下载多个文件"""
1179
- results = []
1180
- for path in paths:
1217
+ # 流式下载块大小(与服务端 _STREAM_CHUNK 对齐)。客户端按此尺寸从 HTTP 响应流读块、
1218
+ # 写盘,内存峰值 ≈ 单块,与文件总大小无关。替代旧整包 download_files(base64 全量进内存)。
1219
+ _STREAM_CHUNK = int(os.environ.get("SANDBOX_STREAM_CHUNK", 1024 * 1024))
1220
+
1221
+ async def _download_stream_to_file(self, path: str, dest: str, *, timeout: int = None) -> "FileDownloadResult":
1222
+ """流式下载单个沙箱文件到本地 dest(内部实现,含 failover)。
1223
+
1224
+ 打 POST /v1/sandbox/download/stream,按 _STREAM_CHUNK 流式写盘,不进进程大内存。
1225
+ 失败时(瞬时网络抖动)原地重试一次,再切实例一次,策略对齐 _post_async_with_failover。
1226
+ """
1227
+ headers = self._build_headers()
1228
+ http_timeout = (timeout or self._timeout) + 30
1229
+ timeout_obj = aiohttp.ClientTimeout(total=http_timeout)
1230
+
1231
+ async def _do(base_url: str) -> "FileDownloadResult":
1232
+ session = await self._get_async_session()
1233
+ u = f"{base_url}{SANDBOX_API_PREFIX}/download/stream"
1234
+ async with session.post(u, json={"path": path, "user_id": self._user_id},
1235
+ headers=headers, timeout=timeout_obj) as resp:
1236
+ if resp.status >= 400:
1237
+ text = await resp.text()
1238
+ return FileDownloadResult(
1239
+ path=path, error=f"HTTP {resp.status}: {text[:200]}")
1240
+ with open(dest, "wb") as f:
1241
+ async for chunk in resp.content.iter_chunked(self._STREAM_CHUNK):
1242
+ f.write(chunk)
1243
+ return FileDownloadResult(path=path, dest=dest,
1244
+ size=os.path.getsize(dest))
1245
+
1246
+ last_exc: Optional[Exception] = None
1247
+ for attempt in range(2):
1181
1248
  try:
1182
- result = self._post_sync(
1183
- f"{SANDBOX_API_PREFIX}/download",
1184
- {"path": path, "user_id": self._user_id}
1185
- )
1186
- if result.get("error"):
1187
- results.append(FileDownloadResponse(
1188
- path=path,
1189
- error=result["error"]
1190
- ))
1191
- else:
1192
- content = base64.b64decode(result["content"])
1193
- results.append(FileDownloadResponse(
1194
- path=path, content=content))
1195
- except Exception as e:
1196
- results.append(FileDownloadResponse(path=path, error=str(e)))
1197
- return results
1249
+ return await _do(self._base_url)
1250
+ except (aiohttp.ClientError, asyncio.TimeoutError, OSError) as e:
1251
+ last_exc = e
1252
+ SYLogger.warning(
1253
+ f"[Sandbox] 流式下载失败 (尝试 {attempt+1}/2): "
1254
+ f"{self._base_url} path={path} - {e}")
1255
+ if attempt == 0:
1256
+ await asyncio.sleep(1)
1257
+ switched = await asyncio.to_thread(self._refresh_from_nacos_and_switch_sync)
1258
+ if switched:
1259
+ try:
1260
+ return await _do(self._base_url)
1261
+ except (aiohttp.ClientError, asyncio.TimeoutError, OSError) as e:
1262
+ last_exc = e
1263
+ SYLogger.warning(f"[Sandbox] 切实例后流式下载仍失败: {self._base_url} - {e}")
1264
+ try:
1265
+ os.unlink(dest)
1266
+ except OSError:
1267
+ pass
1268
+ return FileDownloadResult(path=path, error=f"流式下载失败: {last_exc}")
1198
1269
 
1199
- async def adownload_files(self, paths: List[str], *, timeout: int = None) -> List[FileDownloadResponse]:
1200
- """异步下载多个文件(真正的异步实现)
1270
+ async def adownload_to_file(self, path: str, dest: str, *, timeout: int = None) -> "FileDownloadResult":
1271
+ """流式下载沙箱文件到本地 dest 路径(推荐用法,内存峰值≈单块)。
1272
+
1273
+ Args:
1274
+ path: 沙箱内文件路径
1275
+ dest: 本地目标文件路径(调用方负责清理;建议用 tempfile)
1276
+ timeout: 超时秒数
1201
1277
 
1202
- 🔑 OOM 兜底:每个文件下载前先 astat 拿 size(只查 size 不读内容),
1203
- MAX_DOWNLOAD_BYTES 直接返回 error,避免整包读 + base64 解码把全量拉进内存。
1204
- astat 异常 fail-open(warning 后继续下载)。
1278
+ Returns:
1279
+ FileDownloadResult(path, dest, size, error)。error None 即失败。
1205
1280
  """
1206
- from sycommon.agent.sandbox.file_ops import MAX_DOWNLOAD_BYTES
1207
- results = []
1208
- for path in paths:
1281
+ return await self._download_stream_to_file(path, dest, timeout=timeout)
1282
+
1283
+ # ---- 框架兼容:deepagents SkillsMiddleware/MemoryMiddleware 内部调
1284
+ # backend.adownload_files(paths) 批量下载 SKILL.md/memory(第三方代码,无法改)。
1285
+ # 这里保留 adownload_files/download_files 签名,内部走流式下载到临时文件再读 bytes,
1286
+ # 内存安全。业务代码(get_share_url/minio_sync 等)应优先用 adownload_to_file 不读回。
1287
+ async def adownload_files(self, paths: List[str], *, timeout: int = None) -> List[FileDownloadResponse]:
1288
+ """批量下载(框架兼容)。内部流式落临时文件再读 bytes。"""
1289
+ results: List[FileDownloadResponse] = []
1290
+ for p in paths:
1291
+ import tempfile as _tf
1292
+ with _tf.NamedTemporaryFile(delete=False) as _tmp:
1293
+ tmp_path = _tmp.name
1209
1294
  try:
1210
- # 大小预检:超限直接拒绝,不下载
1211
- try:
1212
- st = await self.astat(path=path)
1213
- if st and not getattr(st, "error", None) and getattr(st, "exists", False):
1214
- fsize = getattr(st, "size", 0) or 0
1215
- if fsize > MAX_DOWNLOAD_BYTES:
1216
- cap_mb = MAX_DOWNLOAD_BYTES // (1024 * 1024)
1217
- SYLogger.warning(f"[Sandbox] 文件过大拒绝下载: {path}, size={fsize}")
1218
- results.append(FileDownloadResponse(
1219
- path=path,
1220
- error=f"file too large ({fsize // (1024*1024)}MB > {cap_mb}MB)"))
1221
- continue
1222
- except Exception as se:
1223
- SYLogger.warning(f"[Sandbox] astat 预检失败(继续下载): {se}")
1224
-
1225
- result = await self._post_async_with_failover(
1226
- f"{SANDBOX_API_PREFIX}/download",
1227
- {"path": path, "user_id": self._user_id},
1228
- timeout=timeout
1229
- )
1230
- if result.get("error"):
1231
- results.append(FileDownloadResponse(
1232
- path=path,
1233
- error=result["error"]
1234
- ))
1295
+ r = await self.adownload_to_file(p, tmp_path, timeout=timeout)
1296
+ if r.error:
1297
+ results.append(FileDownloadResponse(path=p, error=r.error))
1235
1298
  else:
1236
- content = base64.b64decode(result["content"])
1237
- results.append(FileDownloadResponse(
1238
- path=path, content=content))
1299
+ with open(tmp_path, "rb") as _f:
1300
+ results.append(FileDownloadResponse(path=p, content=_f.read()))
1239
1301
  except Exception as e:
1240
- results.append(FileDownloadResponse(path=path, error=str(e)))
1302
+ results.append(FileDownloadResponse(path=p, error=str(e)))
1303
+ finally:
1304
+ try:
1305
+ os.unlink(tmp_path)
1306
+ except OSError:
1307
+ pass
1241
1308
  return results
1242
1309
 
1310
+ def download_files(self, paths: List[str]) -> List[FileDownloadResponse]:
1311
+ """批量下载(同步包装,框架兼容)。"""
1312
+ return _run_coro_sync(self.adownload_files(paths))
1313
+
1314
+ def download_to_file(self, path: str, dest: str, *, timeout: int = None) -> "FileDownloadResult":
1315
+ """流式下载(同步包装)。在线程池独立 loop 里跑 adownload_to_file。"""
1316
+ return _run_coro_sync(self.adownload_to_file(path, dest, timeout=timeout))
1317
+
1243
1318
  # ============== 目录同步 ==============
1244
1319
 
1245
1320
  def _sync_sync(self) -> dict:
@@ -1552,18 +1627,26 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
1552
1627
  continue
1553
1628
  file_path = file_info["path"]
1554
1629
  try:
1555
- download_result = self._post_sync(
1556
- f"{SANDBOX_API_PREFIX}/download",
1557
- {"path": file_path, "user_id": self._user_id}
1558
- )
1559
- if download_result.get("error"):
1560
- failed_count += 1
1561
- errors.append(
1562
- {"path": file_path, "error": download_result["error"]})
1563
- else:
1564
- content = base64.b64decode(download_result["content"])
1565
- files_to_sync.append((file_path, content))
1566
- success_count += 1
1630
+ # 流式下载到临时文件再读 bytes(旧实现走整包 /download base64 全量进内存)。
1631
+ # 同步上下文:在线程池里跑 adownload_to_file。文件通常为技能/memory/历史小文件,
1632
+ # 落盘读回可接受;大文件也不爆内存。
1633
+ import tempfile as _tf
1634
+ with _tf.NamedTemporaryFile(delete=False) as _tmp:
1635
+ tmp_path = _tmp.name
1636
+ try:
1637
+ r = _run_coro_sync(self.adownload_to_file(file_path, tmp_path))
1638
+ if r.error:
1639
+ failed_count += 1
1640
+ errors.append({"path": file_path, "error": r.error})
1641
+ else:
1642
+ with open(tmp_path, "rb") as _f:
1643
+ files_to_sync.append((file_path, _f.read()))
1644
+ success_count += 1
1645
+ finally:
1646
+ try:
1647
+ os.unlink(tmp_path)
1648
+ except OSError:
1649
+ pass
1567
1650
  except Exception as e:
1568
1651
  failed_count += 1
1569
1652
  errors.append({"path": file_path, "error": str(e)})
@@ -196,6 +196,44 @@ class MinioSyncService(metaclass=SingletonMeta):
196
196
  SYLogger.error(f"[MinIO] Upload failed: {object_key}, error={e}")
197
197
  return False
198
198
 
199
+ def upload_stream(self, object_key: str, file_obj, length: int,
200
+ content_type: str = "application/octet-stream") -> bool:
201
+ """从 file-like 对象流式分片上传(大文件专用,内存峰值≈5MB)。
202
+
203
+ MinIO put_object(length=size, part_size=0) 自动按 5MB 分片读 file_obj,
204
+ 不一次性 read 全文件。已验证 50/100/200MB 上传内存峰值恒定 5MB。
205
+
206
+ Args:
207
+ object_key: MinIO 对象 key
208
+ file_obj: 有 read() 的二进制文件对象(如 open(path,'rb'))
209
+ length: 文件总字节数(必传,决定分片数)
210
+ content_type: MIME
211
+ """
212
+ if not self._client:
213
+ return False
214
+ try:
215
+ self._client.put_object(
216
+ bucket_name=self._bucket,
217
+ object_name=object_key,
218
+ data=file_obj,
219
+ length=length,
220
+ content_type=content_type,
221
+ # part_size=0 → minio 按 length 自动算 5MB 分片
222
+ )
223
+ SYLogger.info(
224
+ f"[MinIO] Stream upload success: {object_key}, size={length}")
225
+ return True
226
+ except Exception as e:
227
+ SYLogger.error(f"[MinIO] Stream upload failed: {object_key}, error={e}")
228
+ return False
229
+
230
+ async def aupload_stream(self, object_key: str, file_obj, length: int,
231
+ content_type: str = "application/octet-stream") -> bool:
232
+ """异步流式分片上传"""
233
+ return await asyncio.to_thread(
234
+ self.upload_stream, object_key, file_obj, length, content_type)
235
+
236
+
199
237
  async def aupload_bytes(self, object_key: str, content: bytes,
200
238
  content_type: str = "application/octet-stream") -> bool:
201
239
  """异步上传文件到 MinIO"""
@@ -606,30 +644,49 @@ class MinioSyncService(metaclass=SingletonMeta):
606
644
 
607
645
  async def _sync_one(self, sandbox_backend, fp: str,
608
646
  existing_objects: dict, prefix: str) -> bool:
609
- """同步单个文件:下载 + 上传,成功返回 True"""
647
+ """同步单个文件:流式下载到临时文件 + 流式上传 MinIO,成功返回 True
648
+
649
+ 内存峰值≈5MB(沙箱流式落盘 + MinIO 5MB 分片),与文件大小无关。
650
+ 替代旧实现(adownload_files 整包读 + upload_bytes 全量进内存)。
651
+ """
652
+ import tempfile as _tf
653
+ tmp_path = None
610
654
  try:
611
- results = await sandbox_backend.adownload_files([f"/{fp}"])
612
- if not results or results[0].error or not results[0].content:
613
- error = results[0].error if results else "unknown"
614
- SYLogger.warning(f"[MinIO] 下载沙箱文件失败: {fp}, error={error}")
655
+ # MinIO 已有且 size 相同时,用 astat 的 size 先判跳过(省一次下载)
656
+ st = await sandbox_backend.astat(path=f"/{fp}")
657
+ if not st or getattr(st, "error", None) or not getattr(st, "exists", False):
658
+ SYLogger.warning(f"[MinIO] astat 沙箱文件失败/不存在: {fp}")
615
659
  return False
616
-
617
- content = results[0].content
618
-
619
- # 如果 MinIO 已有且 size 相同,跳过
620
- if fp in existing_objects and existing_objects[fp].size == len(content):
660
+ fsize = getattr(st, "size", 0) or 0
661
+ if fp in existing_objects and existing_objects[fp].size == fsize:
621
662
  return False
622
663
 
623
664
  mime_type, _ = mimetypes.guess_type(fp)
624
665
  object_key = f"{prefix}{fp}"
625
666
 
626
- return await self.aupload_bytes(
627
- object_key, content,
628
- content_type=mime_type or "application/octet-stream",
629
- )
667
+ # 流式下载到临时文件
668
+ with _tf.NamedTemporaryFile(delete=False) as tmp:
669
+ tmp_path = tmp.name
670
+ r = await sandbox_backend.adownload_to_file(f"/{fp}", tmp_path)
671
+ if r.error or r.size == 0:
672
+ SYLogger.warning(f"[MinIO] 流式下载沙箱文件失败: {fp}, error={r.error}")
673
+ return False
674
+ # 流式分片上传 MinIO(open 后由 minio 内部 5MB 分片读,不进大内存)
675
+ with open(tmp_path, "rb") as f:
676
+ return await self.aupload_stream(
677
+ object_key, f, r.size,
678
+ content_type=mime_type or "application/octet-stream",
679
+ )
630
680
  except Exception as e:
631
681
  SYLogger.warning(f"[MinIO] 同步文件异常: {fp}, error={e}")
632
682
  return False
683
+ finally:
684
+ if tmp_path:
685
+ try:
686
+ os.unlink(tmp_path)
687
+ except OSError:
688
+ pass
689
+
633
690
 
634
691
  # ============== 用户上传文件直推(fire-and-forget 后台)==============
635
692
  # 用户刚传上来的文件优先落 MinIO:不等会话结束扫描,免得沙箱中途崩溃丢文件。
@@ -33,14 +33,14 @@ import shlex
33
33
  import threading
34
34
  from datetime import datetime
35
35
  from fastapi import FastAPI, APIRouter, Request, Header
36
- from fastapi.responses import StreamingResponse
36
+ from fastapi.responses import StreamingResponse, JSONResponse
37
37
  from typing import Dict
38
38
 
39
39
  from sycommon.logging.kafka_log import SYLogger
40
40
  from sycommon.models.sandbox import (
41
41
  ExecuteRequest, ExecuteResponse,
42
42
  UploadRequest, UploadResponse,
43
- DownloadRequest, DownloadResponse,
43
+ DownloadRequest,
44
44
  DeleteRequest, DeleteResponse,
45
45
  FileInfo, LsRequest, LsResponse,
46
46
  TreeNode, TreeRequest, TreeResponse,
@@ -1238,30 +1238,60 @@ def setup_sandbox_handler(app: FastAPI, config: dict = None):
1238
1238
 
1239
1239
  return await asyncio.to_thread(_batch)
1240
1240
 
1241
- @sandbox_router.post("/download", response_model=DownloadResponse)
1242
- async def download_file(req: DownloadRequest):
1243
- """下载文件"""
1241
+ # 流式下载块大小。服务端按此大小读文件块吐给客户端,客户端同尺寸写盘,
1242
+ # 双方内存峰值恒定 块大小,与文件总大小无关(GB 级文件也不爆)。
1243
+ # 替代旧整包 /download(os.ReadFile + base64 全量进内存)。
1244
+ _STREAM_CHUNK = int(os.environ.get("SANDBOX_STREAM_CHUNK", 1024 * 1024))
1245
+
1246
+ @sandbox_router.post("/download/stream")
1247
+ async def download_stream(req: DownloadRequest):
1248
+ """流式下载文件(替代旧整包 /download)。
1249
+
1250
+ 返回 StreamingResponse,按 _STREAM_CHUNK 块吐原始字节(不 base64)。
1251
+ 内存峰值 ≈ 单块,支持任意大小文件。错误用 HTTP 状态码 + JSON body 表达:
1252
+ 400 路径非法 / 404 文件不存在 / 500 服务端异常。
1253
+ 鉴权与其它接口一致(客户端带 X-Sandbox-Token,本服务端内网信任不校验)。
1254
+ """
1244
1255
  workspace = await aget_user_workspace(req.user_id)
1245
1256
  try:
1246
1257
  file_path = resolve_sandbox_path(req.path, workspace)
1247
1258
  except ValueError as e:
1248
- return DownloadResponse(path=req.path, error=str(e))
1259
+ SYLogger.warning(f"[Sandbox Server] download/stream 路径非法: {e}")
1260
+ return JSONResponse(status_code=400, content={"error": str(e)})
1249
1261
 
1250
- def _download():
1262
+ # 预检:文件存在性 + 拿 size(流式吐需要 Content-Length)
1263
+ def _check():
1251
1264
  if not os.path.isfile(file_path):
1252
- return DownloadResponse(path=file_path, error="file_not_found")
1253
- with open(file_path, 'rb') as f:
1254
- content = f.read()
1255
- return DownloadResponse(
1256
- path=file_path,
1257
- content=base64.b64encode(content).decode(),
1258
- error=None
1259
- )
1260
-
1265
+ return None, "file_not_found"
1266
+ return os.path.getsize(file_path), None
1261
1267
  try:
1262
- return await asyncio.to_thread(_download)
1268
+ size, err = await asyncio.to_thread(_check)
1263
1269
  except Exception as e:
1264
- return DownloadResponse(path=file_path, error=str(e))
1270
+ SYLogger.error(f"[Sandbox Server] download/stream stat 异常: {e}")
1271
+ return JSONResponse(status_code=500, content={"error": str(e)})
1272
+ if err:
1273
+ return JSONResponse(status_code=404, content={"error": err})
1274
+
1275
+ SYLogger.info(
1276
+ f"[Sandbox Server] download/stream: {file_path} (user={req.user_id}, size={size})")
1277
+
1278
+ async def _gen():
1279
+ # 文件 IO 在线程池跑,避免阻塞事件循环。一次只持有一块在内存。
1280
+ loop = asyncio.get_event_loop()
1281
+ f = await loop.run_in_executor(None, open, file_path, "rb")
1282
+ try:
1283
+ while True:
1284
+ chunk = await loop.run_in_executor(None, f.read, _STREAM_CHUNK)
1285
+ if not chunk:
1286
+ break
1287
+ yield chunk
1288
+ finally:
1289
+ await loop.run_in_executor(None, f.close)
1290
+
1291
+ headers = {"Content-Length": str(size)}
1292
+ return StreamingResponse(
1293
+ _gen(), media_type="application/octet-stream", headers=headers)
1294
+
1265
1295
 
1266
1296
  @sandbox_router.post("/tree", response_model=TreeResponse)
1267
1297
  async def tree_dir(req: TreeRequest):
@@ -40,18 +40,11 @@ class UploadResponse(BaseModel):
40
40
 
41
41
 
42
42
  class DownloadRequest(BaseModel):
43
- """下载文件请求"""
43
+ """下载文件请求(/v1/sandbox/download/stream 流式接口共用)"""
44
44
  path: str
45
45
  user_id: str
46
46
 
47
47
 
48
- class DownloadResponse(BaseModel):
49
- """下载文件响应"""
50
- path: str
51
- content: Optional[str] = None # base64 encoded
52
- error: Optional[str] = None
53
-
54
-
55
48
  class FileInfo(BaseModel):
56
49
  """文件信息"""
57
50
  path: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.7a44
3
+ Version: 0.2.7a45
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown