sycommon-python-lib 0.2.7a43__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.
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/pyproject.toml +1 -1
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/file_ops.py +4 -5
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/http_sandbox_backend.py +152 -69
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/minio_sync.py +71 -14
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/sandbox.py +48 -18
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/traceid.py +84 -45
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/sandbox.py +1 -8
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/README.md +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/setup.cfg +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/core/console.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/core/models.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/core/project.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/core/utils.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/main_agent.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/nodes/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/nodes/example_node.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/states/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/agent/states/agent_state.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/api/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/api/query.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/api/sse/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/api/sse/agent.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/db/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/db/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/db/model/entity.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/db/service.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/model/parse.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/agent/tools/mq.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/.env.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/.gitignore.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/Dockerfile.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/app.yaml.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/client/FileServiceClient.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/model/file_info.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/base/requirements.txt.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/commands/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/commands/hello.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/pyproject.toml.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/cli/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/api/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/api/echo.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/api/sse/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/api/sse/echo.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/command/templates/web/tools/mq.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/nexus/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/__main__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/executor.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/registry.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/acp/server.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/agents/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/agents/factory.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/agents/prompts.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/browser.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/console.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/dom.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/network.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/page_errors.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/performance.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/capabilities/screenshot.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/client.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/protocol.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cdp/repl.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/cli.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/acp_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/cdp_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/chat_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/create_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/evaluate_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/init_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/memory_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/resume_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/rollback_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/commands/run_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/core/backend.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/core/config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/core/display.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/core/git_integration.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/core/llm.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/core/state.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/evaluate/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/evaluate/api_evaluator.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/compressor.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/full.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/hot.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/manager.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/memory/warm.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/mode/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/mode/create.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/mode/optimize.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/models/config_models.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/baseline_tests.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/checkpoint.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/convergence.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/diagnosis.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/engine.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/environment.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/experience.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/harness_prompts.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/history.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/optimization_logger.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/pre_validation.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/reward.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/strategy_bandit.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/strategy_generator.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/rl/strategy_prompts.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/simple_chat_agent.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycli/skills/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/client.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/fetch.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/ssh_init.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/acp/tool.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/agent_manager.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/chat_events.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/deep_agent.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/mcp/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/mcp/models.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/mcp/tool_loader.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/sandbox_path_guard.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/sensitive_guard.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/sitecustomize.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/skill_api_whitelist.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/skill_wl_check.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/middleware/skill_write_guard.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/multi_agent_team.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/resume_compactor.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/consistent_hash.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/session.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/summarization_utils.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/ldap_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/oa_cache.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/oa_crypto.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/oa_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/auth/wecom_ldap_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/ACPAgentConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/ElasticsearchConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/LangfuseConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/PgConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/RedisConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/SentryConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/SkillApiWhitelistConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/XxlJobConfig.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/config/config_change_notifier.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/async_base_db_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/async_database_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/elasticsearch_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/pg_checkpoint_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/redis_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/resilient_pg_saver.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/database/token_usage_db_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/heartbeat_process/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/embedding.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/get_llm.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/llm_logger.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/llm_tokens.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/llm_with_token_tracking.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/output_fixing_runnable.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/struct_token.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/sy_langfuse.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/tiktoken_cache/fb374d419588a4632f3f557e76b4b70aebbca790 +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/token_usage_es_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/token_utils.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/llm/usage_token.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/async_sql_logger.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/kafka_log.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/log_masker.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/logger_levels.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/process_logger.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/mcp_server/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/mcp_server/server.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/context.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/token_tracking.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/tool_result_truncation.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/mcp_server_config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/token_usage.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/token_usage_mysql.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/models/xxljob_handler_config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/notice/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/notice/uvicorn_monitor.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/notice/wecom_message.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/sentry/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/sentry/sy_sentry.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/services.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/feign.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/feign_client.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_client_base.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_config_manager.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/nacos_service_registration.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/deep_agent_server.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_consistent_hash.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_consumer_loss_rootcause.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_consumer_recovery.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_deep_agent.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_dynamic_max_tokens.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_email.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_encoding_cache.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_fix_verification.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_mcp_server.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_minimax_reasoning.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_mq.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_oa_login.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_queue_priority_fallback.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_real_summarization.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_summarization_config.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_summarization_real.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_summary_leak_e2e.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_upgrade_aio_pika.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_upgrade_langgraph_stream.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tests/test_upgrade_verification.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/async_utils.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/env.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/merge_headers.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/snowflake.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/syemail.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/xxljob/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/xxljob/xxljob_service.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/SOURCES.txt +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_acp_tool.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_asyncio_logging.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_config_change_notifier.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_hotreload_snapshot.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_llm_apikey_contextvar.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_log_masker.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_resilient_pg_saver.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_sandbox_path_guard.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_sensitive_guard.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_simple_chat_agent.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_skill_regex_upgrade.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_skill_write_guard.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_sycli.py +0 -0
- {sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/tests/test_sync_skills_to_sandbox.py +0 -0
{sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/agent/sandbox/file_ops.py
RENAMED
|
@@ -41,11 +41,10 @@ if TYPE_CHECKING:
|
|
|
41
41
|
# 沙箱 API 路径前缀
|
|
42
42
|
SANDBOX_API_PREFIX = "/v1/sandbox"
|
|
43
43
|
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
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
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
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
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
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
|
|
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
|
-
|
|
1203
|
-
|
|
1204
|
-
astat 异常 fail-open(warning 后继续下载)。
|
|
1278
|
+
Returns:
|
|
1279
|
+
FileDownloadResult(path, dest, size, error)。error 非 None 即失败。
|
|
1205
1280
|
"""
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
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
|
-
|
|
1212
|
-
|
|
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
|
-
|
|
1237
|
-
|
|
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=
|
|
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
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
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
|
-
"""
|
|
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
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
SYLogger.warning(f"[MinIO]
|
|
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
|
-
|
|
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
|
-
|
|
627
|
-
|
|
628
|
-
|
|
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:不等会话结束扫描,免得沙箱中途崩溃丢文件。
|
{sycommon_python_lib-0.2.7a43 → sycommon_python_lib-0.2.7a45}/src/sycommon/middleware/sandbox.py
RENAMED
|
@@ -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,
|
|
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
|
-
|
|
1242
|
-
|
|
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
|
-
|
|
1259
|
+
SYLogger.warning(f"[Sandbox Server] download/stream 路径非法: {e}")
|
|
1260
|
+
return JSONResponse(status_code=400, content={"error": str(e)})
|
|
1249
1261
|
|
|
1250
|
-
|
|
1262
|
+
# 预检:文件存在性 + 拿 size(流式吐需要 Content-Length)
|
|
1263
|
+
def _check():
|
|
1251
1264
|
if not os.path.isfile(file_path):
|
|
1252
|
-
return
|
|
1253
|
-
|
|
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
|
-
|
|
1268
|
+
size, err = await asyncio.to_thread(_check)
|
|
1263
1269
|
except Exception as e:
|
|
1264
|
-
|
|
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):
|