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