sycommon-python-lib 0.2.7a1__tar.gz → 0.2.7a2__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.7a1 → sycommon_python_lib-0.2.7a2}/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/pyproject.toml +1 -1
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/database/pg_checkpoint_service.py +18 -4
- sycommon_python_lib-0.2.7a2/src/sycommon/database/resilient_pg_saver.py +159 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon_python_lib.egg-info/SOURCES.txt +2 -0
- sycommon_python_lib-0.2.7a2/tests/test_resilient_pg_saver.py +259 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/README.md +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/setup.cfg +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/core/console.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/core/models.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/core/project.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/core/utils.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/agent/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/agent/main_agent.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/agent/nodes/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/agent/nodes/example_node.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/agent/states/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/agent/states/agent_state.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/api/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/api/query.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/api/sse/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/api/sse/agent.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/db/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/db/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/db/model/entity.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/db/service.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/model/parse.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/tools/mq.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/.env.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/.gitignore.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/Dockerfile.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/app.yaml.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/client/FileServiceClient.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/model/file_info.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/requirements.txt.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/commands/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/commands/hello.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/pyproject.toml.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/api/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/api/echo.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/api/sse/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/api/sse/echo.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/tools/mq.py.tpl +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/nexus/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/__main__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/acp/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/acp/config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/acp/executor.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/acp/registry.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/acp/server.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/agents/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/agents/factory.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/agents/prompts.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/browser.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/capabilities/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/capabilities/console.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/capabilities/dom.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/capabilities/network.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/capabilities/page_errors.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/capabilities/performance.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/capabilities/screenshot.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/client.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/protocol.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cdp/repl.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/cli.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/acp_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/cdp_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/chat_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/create_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/evaluate_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/init_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/memory_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/resume_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/rollback_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/commands/run_cmd.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/core/backend.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/core/config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/core/display.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/core/git_integration.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/core/llm.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/core/state.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/evaluate/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/evaluate/api_evaluator.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/memory/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/memory/compressor.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/memory/full.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/memory/hot.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/memory/manager.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/memory/warm.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/mode/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/mode/create.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/mode/optimize.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/models/config_models.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/baseline_tests.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/checkpoint.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/convergence.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/diagnosis.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/engine.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/environment.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/experience.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/harness_prompts.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/history.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/optimization_logger.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/pre_validation.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/reward.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/strategy_bandit.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/strategy_generator.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/rl/strategy_prompts.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/simple_chat_agent.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycli/skills/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/acp/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/acp/client.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/acp/fetch.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/acp/ssh_init.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/acp/tool.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/agent_manager.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/chat_events.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/deep_agent.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/mcp/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/mcp/models.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/mcp/tool_loader.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/multi_agent_team.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/sandbox/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/sandbox/consistent_hash.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/sandbox/file_ops.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/sandbox/http_sandbox_backend.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/sandbox/minio_sync.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/sandbox/session.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/agent/summarization_utils.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/auth/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/auth/ldap_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/auth/oa_cache.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/auth/oa_crypto.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/auth/oa_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/auth/wecom_ldap_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/ACPAgentConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/ElasticsearchConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/LangfuseConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/PgConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/RedisConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/SentryConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/XxlJobConfig.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/config/config_change_notifier.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/database/async_base_db_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/database/async_database_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/database/elasticsearch_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/database/redis_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/database/token_usage_db_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/heartbeat_process/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/embedding.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/get_llm.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/llm_logger.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/llm_tokens.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/llm_with_token_tracking.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/output_fixing_runnable.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/struct_token.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/sy_langfuse.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/tiktoken_cache/fb374d419588a4632f3f557e76b4b70aebbca790 +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/token_usage_es_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/token_utils.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/llm/usage_token.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/logging/async_sql_logger.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/logging/kafka_log.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/logging/log_masker.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/logging/logger_levels.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/logging/process_logger.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/mcp_server/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/mcp_server/server.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/context.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/sandbox.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/token_tracking.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/tool_result_truncation.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/middleware/traceid.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/mcp_server_config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/sandbox.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/token_usage.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/token_usage_mysql.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/models/xxljob_handler_config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/notice/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/notice/uvicorn_monitor.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/notice/wecom_message.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/sentry/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/sentry/sy_sentry.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/services.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/feign.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/feign_client.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/nacos_client_base.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/nacos_config_manager.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/nacos_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/nacos_service_registration.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/deep_agent_server.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_consistent_hash.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_consumer_loss_rootcause.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_consumer_recovery.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_deep_agent.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_dynamic_max_tokens.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_email.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_encoding_cache.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_fix_verification.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_mcp_server.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_minimax_reasoning.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_mq.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_oa_login.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_queue_priority_fallback.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_real_summarization.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_summarization_config.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_summarization_real.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tests/test_summary_leak_e2e.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tools/async_utils.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tools/env.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tools/merge_headers.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tools/snowflake.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tools/syemail.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/xxljob/__init__.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon/xxljob/xxljob_service.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/tests/test_acp_tool.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/tests/test_asyncio_logging.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/tests/test_config_change_notifier.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/tests/test_hotreload_snapshot.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/tests/test_log_masker.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/tests/test_simple_chat_agent.py +0 -0
- {sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/tests/test_sycli.py +0 -0
|
@@ -73,7 +73,6 @@ class PgCheckpointService(metaclass=SingletonMeta):
|
|
|
73
73
|
cls._config = PgConfig.from_dict(config)
|
|
74
74
|
|
|
75
75
|
from psycopg_pool import AsyncConnectionPool
|
|
76
|
-
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
|
77
76
|
|
|
78
77
|
conn_string = cls._config.dsn
|
|
79
78
|
|
|
@@ -95,7 +94,14 @@ class PgCheckpointService(metaclass=SingletonMeta):
|
|
|
95
94
|
|
|
96
95
|
await cls._pool.open()
|
|
97
96
|
|
|
98
|
-
|
|
97
|
+
# 🔑 使用自愈型 ResilientPostgresSaver 包装类(而非直接 AsyncPostgresSaver)
|
|
98
|
+
# 关键:reload() 会 close 旧池并新建池,但旧 agent 持有的 checkpointer
|
|
99
|
+
# 对象不会自动更换。ResilientPostgresSaver 的 .conn 动态读取 _pool,
|
|
100
|
+
# 池被关闭时自动重建重试,避免 PoolClosed 异常透传到上层。
|
|
101
|
+
# 复用已有包装实例(isinstance 守卫):reload 时只换池,不换 checkpointer 对象。
|
|
102
|
+
from sycommon.database.resilient_pg_saver import ResilientPostgresSaver
|
|
103
|
+
if not isinstance(cls._checkpointer, ResilientPostgresSaver):
|
|
104
|
+
cls._checkpointer = ResilientPostgresSaver()
|
|
99
105
|
await cls._checkpointer.setup()
|
|
100
106
|
|
|
101
107
|
cls._initialized = True
|
|
@@ -151,8 +157,10 @@ class PgCheckpointService(metaclass=SingletonMeta):
|
|
|
151
157
|
except Exception as e:
|
|
152
158
|
logging.error(f"关闭 PgCheckpointService 连接池失败: {e}")
|
|
153
159
|
finally:
|
|
160
|
+
# 🔑 只清 _pool,保留 _checkpointer(ResilientPostgresSaver 包装对象)。
|
|
161
|
+
# reload() 重建后,包装对象的 .conn 动态读取新 _pool;
|
|
162
|
+
# 旧 agent 持有的包装引用无需更换即可继续工作。
|
|
154
163
|
cls._pool = None
|
|
155
|
-
cls._checkpointer = None
|
|
156
164
|
cls._initialized = False
|
|
157
165
|
|
|
158
166
|
@classmethod
|
|
@@ -164,6 +172,8 @@ class PgCheckpointService(metaclass=SingletonMeta):
|
|
|
164
172
|
"""
|
|
165
173
|
if not cls._initialized:
|
|
166
174
|
return
|
|
175
|
+
old_pool = cls._pool
|
|
176
|
+
old_pool_id = id(old_pool)
|
|
167
177
|
try:
|
|
168
178
|
await cls.close()
|
|
169
179
|
except Exception as e:
|
|
@@ -173,5 +183,9 @@ class PgCheckpointService(metaclass=SingletonMeta):
|
|
|
173
183
|
cls._initialized = False
|
|
174
184
|
try:
|
|
175
185
|
await cls.setup()
|
|
186
|
+
new_pool_id = id(cls._pool) if cls._pool else None
|
|
187
|
+
logging.info(
|
|
188
|
+
f"PgCheckpointService reload 完成: old_pool_id={old_pool_id} "
|
|
189
|
+
f"-> new_pool_id={new_pool_id}, initialized={cls._initialized}")
|
|
176
190
|
except Exception as e:
|
|
177
|
-
logging.error(f"PgCheckpointService reload 重建失败: {e}", exc_info=True)
|
|
191
|
+
logging.error(f"PgCheckpointService reload 重建失败: {e}", exc_info=True)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""自愈型 PostgreSQL Checkpoint Saver
|
|
2
|
+
|
|
3
|
+
解决 ``psycopg_pool.PoolClosed: the pool 'pool-1' is already closed`` 问题。
|
|
4
|
+
|
|
5
|
+
根因:``PgCheckpointService.reload()`` 在 Nacos 配置热更新时会
|
|
6
|
+
``close()`` 旧连接池(``_pool=None``)再 ``setup()`` 新建一个全新的
|
|
7
|
+
``AsyncConnectionPool``。但此前创建的 agent(缓存在内存 sessions 中)已经
|
|
8
|
+
捕获了旧的 ``AsyncPostgresSaver`` 对象,其 ``.conn`` 指向已关闭的旧池。
|
|
9
|
+
LangGraph ``Pregel`` 永久持有该 checkpointer 引用,下次 ``aget_tuple`` 即
|
|
10
|
+
抛 ``PoolClosed``。
|
|
11
|
+
|
|
12
|
+
本类把"checkpointer 对象"与"连接池"解耦:对象只有一个(永久存活),
|
|
13
|
+
``.conn`` 每次调用时动态读 ``PgCheckpointService._pool``;reload 只换池、
|
|
14
|
+
不换对象。即便池处于被关闭的瞬态,热路径方法捕获 ``PoolClosed`` 后触发
|
|
15
|
+
``_ensure_pool_alive`` 重建并精确重试一次,对上层透明。
|
|
16
|
+
|
|
17
|
+
已对照 langgraph-checkpoint-postgres 3.1.0 源码验证:
|
|
18
|
+
- ``AsyncPostgresSaver.__init__``(aio.py:57)执行 ``self.conn = conn``,
|
|
19
|
+
用 property + no-op setter 吸收,构造可存活。
|
|
20
|
+
- ``self.conn`` 在 aio.py 中仅 ``_cursor``(aio.py:374)一处方法内读取,
|
|
21
|
+
所有热路径方法都只经由 ``self._cursor()`` 取池,无构造期缓存。
|
|
22
|
+
"""
|
|
23
|
+
import asyncio
|
|
24
|
+
|
|
25
|
+
from psycopg_pool import PoolClosed
|
|
26
|
+
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
|
27
|
+
|
|
28
|
+
from sycommon.logging.kafka_log import SYLogger
|
|
29
|
+
|
|
30
|
+
# 自愈并发去重锁(模块级单例)。reload 跑在 Services 主 loop 上,多个并发
|
|
31
|
+
# aget_tuple 同时撞上已关闭池时,只允许一个真正执行重建,其余进锁后双重
|
|
32
|
+
# 检查发现池已恢复即直接返回。
|
|
33
|
+
_heal_lock = asyncio.Lock()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ResilientPostgresSaver(AsyncPostgresSaver):
|
|
37
|
+
"""跟随 ``PgCheckpointService._pool`` 的自愈型 checkpointer。
|
|
38
|
+
|
|
39
|
+
- 永久存活,跨 reload 不重建(见 ``PgCheckpointService.setup`` 的
|
|
40
|
+
``isinstance`` 守卫)。
|
|
41
|
+
- ``conn`` property 动态返回当前活跃池;池被关闭时热路径方法自动重建。
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def __init__(self) -> None:
|
|
45
|
+
# 父类 __init__ 会执行 self.conn = conn;property + no-op setter
|
|
46
|
+
# 吸收该赋值。传 conn=None/pipe=None 避开父类 "pool + pipe 不能同时
|
|
47
|
+
# 非空" 的 guard(aio.py:52)。self.lock/self.loop 由父类设置,跨
|
|
48
|
+
# reload 安全(主 loop 不变)。
|
|
49
|
+
super().__init__(conn=None, pipe=None)
|
|
50
|
+
|
|
51
|
+
# ------------------------------------------------------------------ conn
|
|
52
|
+
@property
|
|
53
|
+
def conn(self): # type: ignore[override]
|
|
54
|
+
"""动态返回当前活跃连接池。
|
|
55
|
+
|
|
56
|
+
池不存在或已关闭时 raise ``PoolClosed``,保持与底层一致的失败语义,
|
|
57
|
+
交由热路径方法的 try/except 捕获后自愈。
|
|
58
|
+
"""
|
|
59
|
+
from sycommon.database.pg_checkpoint_service import PgCheckpointService
|
|
60
|
+
pool = PgCheckpointService._pool
|
|
61
|
+
if pool is None or getattr(pool, "closed", True):
|
|
62
|
+
raise PoolClosed(
|
|
63
|
+
f"the pool {getattr(pool, 'name', 'pool-1')!r} is already closed "
|
|
64
|
+
f"(or not initialized)"
|
|
65
|
+
)
|
|
66
|
+
return pool
|
|
67
|
+
|
|
68
|
+
@conn.setter
|
|
69
|
+
def conn(self, value): # noqa: D401
|
|
70
|
+
"""no-op:吸收父类 ``__init__`` 的 ``self.conn = conn`` 赋值。
|
|
71
|
+
|
|
72
|
+
实际连接池永远通过 getter 动态从 ``PgCheckpointService`` 读取,
|
|
73
|
+
不缓存任何传入值。
|
|
74
|
+
"""
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
# ------------------------------------------------------------- 自愈核心
|
|
78
|
+
async def _ensure_pool_alive(self) -> None:
|
|
79
|
+
"""若连接池已关闭/未初始化,触发一次重建(并发去重)。
|
|
80
|
+
|
|
81
|
+
双重检查:进锁后再查一次池状态,避免多个并发调用重复 reload。
|
|
82
|
+
"""
|
|
83
|
+
from sycommon.database.pg_checkpoint_service import PgCheckpointService
|
|
84
|
+
|
|
85
|
+
# 锁外快查:池可用就直接返回,绝大多数请求走这条快路径
|
|
86
|
+
pool = PgCheckpointService._pool
|
|
87
|
+
if pool is not None and not getattr(pool, "closed", True):
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
async with _heal_lock:
|
|
91
|
+
# 锁内再次检查:可能已有并发协程完成了重建
|
|
92
|
+
pool = PgCheckpointService._pool
|
|
93
|
+
if pool is not None and not getattr(pool, "closed", True):
|
|
94
|
+
return
|
|
95
|
+
old_pool_id = id(pool)
|
|
96
|
+
SYLogger.info(
|
|
97
|
+
f"[ResilientPgSaver] pool closed, triggering self-heal "
|
|
98
|
+
f"(old_pool_id={old_pool_id})")
|
|
99
|
+
try:
|
|
100
|
+
await PgCheckpointService.reload()
|
|
101
|
+
except Exception as e:
|
|
102
|
+
SYLogger.error(
|
|
103
|
+
f"[ResilientPgSaver] self-heal reload 失败: {e}",
|
|
104
|
+
exc_info=True)
|
|
105
|
+
raise
|
|
106
|
+
new_pool = PgCheckpointService._pool
|
|
107
|
+
SYLogger.info(
|
|
108
|
+
f"[ResilientPgSaver] self-heal 完成 "
|
|
109
|
+
f"(old_pool_id={old_pool_id} -> new_pool_id={id(new_pool)})")
|
|
110
|
+
|
|
111
|
+
# ----------------------------------------------------- 热路径方法重试
|
|
112
|
+
# 统一模式:捕获 PoolClosed -> 自愈 -> 精确一次重试。
|
|
113
|
+
# PoolClosed 实际只在打开 cursor(首次从池里取连接)时出现,重试是安全的。
|
|
114
|
+
async def aget_tuple(self, config):
|
|
115
|
+
try:
|
|
116
|
+
return await super().aget_tuple(config)
|
|
117
|
+
except PoolClosed:
|
|
118
|
+
await self._ensure_pool_alive()
|
|
119
|
+
return await super().aget_tuple(config)
|
|
120
|
+
|
|
121
|
+
async def aput(self, config, checkpoint, metadata, new_versions):
|
|
122
|
+
try:
|
|
123
|
+
return await super().aput(config, checkpoint, metadata, new_versions)
|
|
124
|
+
except PoolClosed:
|
|
125
|
+
await self._ensure_pool_alive()
|
|
126
|
+
return await super().aput(config, checkpoint, metadata, new_versions)
|
|
127
|
+
|
|
128
|
+
async def aput_writes(self, config, writes, task_id, task_path=""):
|
|
129
|
+
try:
|
|
130
|
+
return await super().aput_writes(config, writes, task_id, task_path)
|
|
131
|
+
except PoolClosed:
|
|
132
|
+
await self._ensure_pool_alive()
|
|
133
|
+
return await super().aput_writes(config, writes, task_id, task_path)
|
|
134
|
+
|
|
135
|
+
async def adelete_thread(self, thread_id):
|
|
136
|
+
try:
|
|
137
|
+
return await super().adelete_thread(thread_id)
|
|
138
|
+
except PoolClosed:
|
|
139
|
+
await self._ensure_pool_alive()
|
|
140
|
+
return await super().adelete_thread(thread_id)
|
|
141
|
+
|
|
142
|
+
async def alist(self, config, *, filter=None, before=None, limit=None):
|
|
143
|
+
"""异步生成器:首条 PoolClosed 自愈后重新遍历整条流。
|
|
144
|
+
|
|
145
|
+
PoolClosed 只在 cursor 打开(首次取连接)时出现,因此重建后重头
|
|
146
|
+
遍历是安全且语义正确的契约(不会漏放或重放 checkpoint tuple)。
|
|
147
|
+
"""
|
|
148
|
+
try:
|
|
149
|
+
async for item in super().alist(
|
|
150
|
+
config, filter=filter, before=before, limit=limit
|
|
151
|
+
):
|
|
152
|
+
yield item
|
|
153
|
+
return
|
|
154
|
+
except PoolClosed:
|
|
155
|
+
await self._ensure_pool_alive()
|
|
156
|
+
async for item in super().alist(
|
|
157
|
+
config, filter=filter, before=before, limit=limit
|
|
158
|
+
):
|
|
159
|
+
yield item
|
|
@@ -185,6 +185,7 @@ src/sycommon/database/database_service.py
|
|
|
185
185
|
src/sycommon/database/elasticsearch_service.py
|
|
186
186
|
src/sycommon/database/pg_checkpoint_service.py
|
|
187
187
|
src/sycommon/database/redis_service.py
|
|
188
|
+
src/sycommon/database/resilient_pg_saver.py
|
|
188
189
|
src/sycommon/database/token_usage_db_service.py
|
|
189
190
|
src/sycommon/health/__init__.py
|
|
190
191
|
src/sycommon/health/health_check.py
|
|
@@ -313,5 +314,6 @@ tests/test_asyncio_logging.py
|
|
|
313
314
|
tests/test_config_change_notifier.py
|
|
314
315
|
tests/test_hotreload_snapshot.py
|
|
315
316
|
tests/test_log_masker.py
|
|
317
|
+
tests/test_resilient_pg_saver.py
|
|
316
318
|
tests/test_simple_chat_agent.py
|
|
317
319
|
tests/test_sycli.py
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""ResilientPostgresSaver 自愈型 checkpointer 单元测试
|
|
3
|
+
|
|
4
|
+
不依赖真实 PostgreSQL / Nacos / Kafka,也不依赖 pytest-asyncio:
|
|
5
|
+
异步用例统一在 ``asyncio.run(...)`` 中执行(与本仓 test_asyncio_logging.py 一致)。
|
|
6
|
+
|
|
7
|
+
验证:
|
|
8
|
+
- 动态 ``conn`` property:池可用时返回,池关闭时抛 ``PoolClosed``。
|
|
9
|
+
- ``aget_tuple`` 等热路径方法捕获 ``PoolClosed`` 后触发 ``_ensure_pool_alive``
|
|
10
|
+
自愈并精确重试一次成功。
|
|
11
|
+
- ``_ensure_pool_alive`` 快路径(池可用时不 reload)与去重(并发只 reload 一次)。
|
|
12
|
+
- 包装类仍是 ``BaseCheckpointSaver``(``ensure_valid_checkpointer`` 要求)。
|
|
13
|
+
"""
|
|
14
|
+
import asyncio
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
from psycopg_pool import PoolClosed
|
|
18
|
+
|
|
19
|
+
from sycommon.database import pg_checkpoint_service as pcs_mod
|
|
20
|
+
from sycommon.database.pg_checkpoint_service import PgCheckpointService
|
|
21
|
+
from sycommon.database import resilient_pg_saver as resilient_pg_saver_module
|
|
22
|
+
from sycommon.database.resilient_pg_saver import ResilientPostgresSaver
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _FakePool:
|
|
26
|
+
"""模拟 AsyncConnectionPool,仅暴露 conn getter 用到的属性。"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, *, closed=False, name="pool-1"):
|
|
29
|
+
self.closed = closed
|
|
30
|
+
self.name = name
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.fixture(autouse=True)
|
|
34
|
+
def _isolate_pg_singleton():
|
|
35
|
+
"""每个用例前后保存/恢复 PgCheckpointService 单例状态,避免互相污染。"""
|
|
36
|
+
saved = {
|
|
37
|
+
attr: getattr(PgCheckpointService, attr)
|
|
38
|
+
for attr in ("_pool", "_checkpointer", "_initialized",
|
|
39
|
+
"_setup_attempts", "_config")
|
|
40
|
+
}
|
|
41
|
+
PgCheckpointService._pool = None
|
|
42
|
+
yield
|
|
43
|
+
for k, v in saved.items():
|
|
44
|
+
setattr(PgCheckpointService, k, v)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _make_saver():
|
|
48
|
+
"""构造 ResilientPostgresSaver(父类 __init__ 调 get_running_loop,需在 loop 内)。"""
|
|
49
|
+
async def _build():
|
|
50
|
+
return ResilientPostgresSaver()
|
|
51
|
+
return asyncio.run(_build())
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_is_base_checkpoint_saver():
|
|
55
|
+
saver = _make_saver()
|
|
56
|
+
from langgraph.checkpoint.base import BaseCheckpointSaver
|
|
57
|
+
assert isinstance(saver, BaseCheckpointSaver)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_conn_getter_returns_live_pool():
|
|
61
|
+
saver = _make_saver()
|
|
62
|
+
pool = _FakePool(closed=False)
|
|
63
|
+
PgCheckpointService._pool = pool
|
|
64
|
+
assert saver.conn is pool
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_conn_getter_raises_on_closed_pool():
|
|
68
|
+
saver = _make_saver()
|
|
69
|
+
PgCheckpointService._pool = _FakePool(closed=True)
|
|
70
|
+
with pytest.raises(PoolClosed):
|
|
71
|
+
saver.conn
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_conn_getter_raises_when_pool_none():
|
|
75
|
+
saver = _make_saver()
|
|
76
|
+
PgCheckpointService._pool = None
|
|
77
|
+
with pytest.raises(PoolClosed):
|
|
78
|
+
saver.conn
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_constructor_survives_parent_conn_assignment():
|
|
82
|
+
"""父类 __init__ 会执行 self.conn = conn;no-op setter 必须吸收它。"""
|
|
83
|
+
saver = _make_saver() # 不应抛异常
|
|
84
|
+
PgCheckpointService._pool = _FakePool(closed=False)
|
|
85
|
+
assert saver.conn is PgCheckpointService._pool # getter 仍动态
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_ensure_pool_alive_fast_path_skips_reload():
|
|
89
|
+
"""池可用时不调 reload(绝大多数请求走这条快路径)。"""
|
|
90
|
+
saver = _make_saver()
|
|
91
|
+
PgCheckpointService._pool = _FakePool(closed=False)
|
|
92
|
+
calls = {"n": 0}
|
|
93
|
+
|
|
94
|
+
async def fake_reload():
|
|
95
|
+
calls["n"] += 1
|
|
96
|
+
|
|
97
|
+
PgCheckpointService.reload = classmethod(lambda cls: fake_reload())
|
|
98
|
+
asyncio.run(saver._ensure_pool_alive())
|
|
99
|
+
assert calls["n"] == 0
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_ensure_pool_alive_triggers_reload_on_closed():
|
|
103
|
+
saver = _make_saver()
|
|
104
|
+
PgCheckpointService._pool = _FakePool(closed=True)
|
|
105
|
+
calls = {"n": 0}
|
|
106
|
+
|
|
107
|
+
async def fake_reload():
|
|
108
|
+
calls["n"] += 1
|
|
109
|
+
PgCheckpointService._pool = _FakePool(closed=False)
|
|
110
|
+
|
|
111
|
+
PgCheckpointService.reload = classmethod(lambda cls: fake_reload())
|
|
112
|
+
asyncio.run(saver._ensure_pool_alive())
|
|
113
|
+
assert calls["n"] == 1
|
|
114
|
+
assert not PgCheckpointService._pool.closed
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_ensure_pool_alive_dedups_concurrent_reload():
|
|
118
|
+
"""多个并发调用同时撞上已关闭池时,reload 只执行一次。"""
|
|
119
|
+
saver = _make_saver()
|
|
120
|
+
PgCheckpointService._pool = _FakePool(closed=True)
|
|
121
|
+
calls = {"n": 0}
|
|
122
|
+
|
|
123
|
+
async def fake_reload():
|
|
124
|
+
calls["n"] += 1
|
|
125
|
+
await asyncio.sleep(0.02) # 模拟重建耗时
|
|
126
|
+
PgCheckpointService._pool = _FakePool(closed=False)
|
|
127
|
+
|
|
128
|
+
PgCheckpointService.reload = classmethod(lambda cls: fake_reload())
|
|
129
|
+
|
|
130
|
+
async def main():
|
|
131
|
+
await asyncio.gather(*(saver._ensure_pool_alive() for _ in range(5)))
|
|
132
|
+
|
|
133
|
+
asyncio.run(main())
|
|
134
|
+
assert calls["n"] == 1
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_aget_tuple_self_heals_after_pool_closed():
|
|
138
|
+
"""aget_tuple 第一次因 PoolClosed 失败 -> 自愈 -> 重试成功。"""
|
|
139
|
+
saver = _make_saver()
|
|
140
|
+
PgCheckpointService._pool = _FakePool(closed=True)
|
|
141
|
+
reload_calls = {"n": 0}
|
|
142
|
+
|
|
143
|
+
async def fake_reload():
|
|
144
|
+
reload_calls["n"] += 1
|
|
145
|
+
PgCheckpointService._pool = _FakePool(closed=False)
|
|
146
|
+
|
|
147
|
+
PgCheckpointService.reload = classmethod(lambda cls: fake_reload())
|
|
148
|
+
|
|
149
|
+
sentinel = object()
|
|
150
|
+
super_calls = {"n": 0}
|
|
151
|
+
orig = resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple
|
|
152
|
+
|
|
153
|
+
async def patched(self, config):
|
|
154
|
+
super_calls["n"] += 1
|
|
155
|
+
if super_calls["n"] == 1:
|
|
156
|
+
raise PoolClosed("the pool 'pool-1' is already closed")
|
|
157
|
+
return sentinel
|
|
158
|
+
|
|
159
|
+
async def main():
|
|
160
|
+
try:
|
|
161
|
+
resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple = patched
|
|
162
|
+
return await saver.aget_tuple({"configurable": {"thread_id": "t1"}})
|
|
163
|
+
finally:
|
|
164
|
+
resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple = orig
|
|
165
|
+
|
|
166
|
+
result = asyncio.run(main())
|
|
167
|
+
assert result is sentinel
|
|
168
|
+
assert super_calls["n"] == 2 # 一次失败 + 一次重试
|
|
169
|
+
assert reload_calls["n"] == 1
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def test_aget_tuple_no_heal_when_pool_healthy():
|
|
173
|
+
"""池健康时正常返回,不触发自愈。"""
|
|
174
|
+
saver = _make_saver()
|
|
175
|
+
PgCheckpointService._pool = _FakePool(closed=False)
|
|
176
|
+
reload_calls = {"n": 0}
|
|
177
|
+
|
|
178
|
+
async def fake_reload():
|
|
179
|
+
reload_calls["n"] += 1
|
|
180
|
+
|
|
181
|
+
PgCheckpointService.reload = classmethod(lambda cls: fake_reload())
|
|
182
|
+
|
|
183
|
+
sentinel = object()
|
|
184
|
+
orig = resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple
|
|
185
|
+
|
|
186
|
+
async def patched(self, config):
|
|
187
|
+
return sentinel
|
|
188
|
+
|
|
189
|
+
async def main():
|
|
190
|
+
try:
|
|
191
|
+
resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple = patched
|
|
192
|
+
return await saver.aget_tuple({"configurable": {"thread_id": "t2"}})
|
|
193
|
+
finally:
|
|
194
|
+
resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple = orig
|
|
195
|
+
|
|
196
|
+
result = asyncio.run(main())
|
|
197
|
+
assert result is sentinel
|
|
198
|
+
assert reload_calls["n"] == 0
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def test_aget_tuple_re_raises_non_poolclosed_error():
|
|
202
|
+
"""非 PoolClosed 异常不应被吞掉重试。"""
|
|
203
|
+
saver = _make_saver()
|
|
204
|
+
PgCheckpointService._pool = _FakePool(closed=False)
|
|
205
|
+
reload_calls = {"n": 0}
|
|
206
|
+
|
|
207
|
+
async def fake_reload():
|
|
208
|
+
reload_calls["n"] += 1
|
|
209
|
+
|
|
210
|
+
PgCheckpointService.reload = classmethod(lambda cls: fake_reload())
|
|
211
|
+
|
|
212
|
+
orig = resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple
|
|
213
|
+
|
|
214
|
+
async def patched(self, config):
|
|
215
|
+
raise ValueError("some other db error")
|
|
216
|
+
|
|
217
|
+
async def main():
|
|
218
|
+
try:
|
|
219
|
+
resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple = patched
|
|
220
|
+
await saver.aget_tuple({"configurable": {"thread_id": "t3"}})
|
|
221
|
+
finally:
|
|
222
|
+
resilient_pg_saver_module.AsyncPostgresSaver.aget_tuple = orig
|
|
223
|
+
|
|
224
|
+
with pytest.raises(ValueError):
|
|
225
|
+
asyncio.run(main())
|
|
226
|
+
assert reload_calls["n"] == 0
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def test_alist_self_heals_after_pool_closed():
|
|
230
|
+
"""async generator 首条 PoolClosed 后自愈并重放整条流。"""
|
|
231
|
+
saver = _make_saver()
|
|
232
|
+
PgCheckpointService._pool = _FakePool(closed=True)
|
|
233
|
+
reload_calls = {"n": 0}
|
|
234
|
+
|
|
235
|
+
async def fake_reload():
|
|
236
|
+
reload_calls["n"] += 1
|
|
237
|
+
PgCheckpointService._pool = _FakePool(closed=False)
|
|
238
|
+
|
|
239
|
+
PgCheckpointService.reload = classmethod(lambda cls: fake_reload())
|
|
240
|
+
|
|
241
|
+
orig_alist = resilient_pg_saver_module.AsyncPostgresSaver.alist
|
|
242
|
+
|
|
243
|
+
async def patched_alist(self, config, *, filter=None, before=None, limit=None):
|
|
244
|
+
if PgCheckpointService._pool.closed:
|
|
245
|
+
raise PoolClosed("the pool 'pool-1' is already closed")
|
|
246
|
+
yield "row-a"
|
|
247
|
+
yield "row-b"
|
|
248
|
+
|
|
249
|
+
async def main():
|
|
250
|
+
try:
|
|
251
|
+
resilient_pg_saver_module.AsyncPostgresSaver.alist = patched_alist
|
|
252
|
+
return [x async for x in saver.alist(
|
|
253
|
+
{"configurable": {"thread_id": "t4"}})]
|
|
254
|
+
finally:
|
|
255
|
+
resilient_pg_saver_module.AsyncPostgresSaver.alist = orig_alist
|
|
256
|
+
|
|
257
|
+
items = asyncio.run(main())
|
|
258
|
+
assert items == ["row-a", "row-b"]
|
|
259
|
+
assert reload_calls["n"] == 1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/agent/app.py.tpl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/.env.tpl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/README.md.tpl
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/app.py.tpl
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/base/app.yaml.tpl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/README.md.tpl
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/cli/app.py.tpl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/README.md.tpl
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.7a1 → sycommon_python_lib-0.2.7a2}/src/command/templates/web/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|