sycommon-python-lib 0.2.5a28__tar.gz → 0.2.5a29__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.5a28 → sycommon_python_lib-0.2.5a29}/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/pyproject.toml +1 -1
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/deep_agent.py +42 -1
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -69
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/llm_with_token_tracking.py +8 -55
- sycommon_python_lib-0.2.5a29/src/sycommon/llm/token_utils.py +96 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/usage_token.py +8 -46
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -70
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon_python_lib.egg-info/SOURCES.txt +1 -1
- sycommon_python_lib-0.2.5a28/src/sycommon/synacos/dns_cache.py +0 -67
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/README.md +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/setup.cfg +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/core/console.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/core/models.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/core/project.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/core/utils.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/agent/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/agent/main_agent.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/agent/nodes/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/agent/nodes/example_node.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/agent/states/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/agent/states/agent_state.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/api/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/api/query.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/api/sse/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/api/sse/agent.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/db/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/db/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/db/model/entity.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/db/service.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/model/parse.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/agent/tools/mq.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/.env.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/.gitignore.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/Dockerfile.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/app.yaml.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/client/FileServiceClient.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/model/file_info.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/base/requirements.txt.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/cli/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/cli/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/cli/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/cli/commands/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/cli/commands/hello.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/cli/pyproject.toml.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/cli/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/README.md.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/api/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/api/echo.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/api/sse/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/api/sse/echo.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/app.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/client/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/model/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/tools/__init__.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/web/tools/mq.py.tpl +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/nexus/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/__main__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/agents/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/agents/factory.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/agents/prompts.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/browser.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/capabilities/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/capabilities/console.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/capabilities/dom.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/capabilities/network.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/capabilities/page_errors.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/capabilities/performance.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/capabilities/screenshot.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/client.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/protocol.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cdp/repl.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/cli.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/cdp_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/chat_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/create_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/evaluate_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/init_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/memory_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/resume_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/rollback_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/commands/run_cmd.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/core/backend.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/core/config.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/core/display.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/core/git_integration.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/core/llm.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/core/state.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/evaluate/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/evaluate/api_evaluator.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/memory/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/memory/compressor.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/memory/full.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/memory/hot.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/memory/manager.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/memory/warm.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/mode/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/mode/create.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/mode/optimize.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/models/config_models.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/baseline_tests.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/checkpoint.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/convergence.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/diagnosis.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/engine.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/environment.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/experience.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/harness_prompts.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/history.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/optimization_logger.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/pre_validation.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/reward.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/strategy_bandit.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/strategy_generator.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/rl/strategy_prompts.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycli/skills/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/agent_manager.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/chat_events.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/mcp/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/mcp/models.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/mcp/tool_loader.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/multi_agent_team.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/sandbox/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/sandbox/file_ops.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/sandbox/http_sandbox_backend.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/sandbox/minio_sync.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/sandbox/session.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/summarization_utils.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/auth/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/auth/ldap_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/auth/oa_cache.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/auth/oa_crypto.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/auth/oa_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/auth/wecom_ldap_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/ElasticsearchConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/LangfuseConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/PgConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/RedisConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/SentryConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/XxlJobConfig.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/database/async_base_db_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/database/async_database_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/database/elasticsearch_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/database/pg_checkpoint_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/database/redis_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/database/token_usage_db_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/heartbeat_process/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/embedding.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/get_llm.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/llm_logger.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/llm_tokens.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/output_fixing_runnable.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/struct_token.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/sy_langfuse.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/tiktoken_cache/fb374d419588a4632f3f557e76b4b70aebbca790 +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/token_usage_es_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/logging/async_sql_logger.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/logging/kafka_log.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/logging/logger_levels.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/logging/process_logger.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/mcp_server/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/mcp_server/server.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/context.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/sandbox.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/token_tracking.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/tool_result_truncation.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/middleware/traceid.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/mcp_server_config.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/sandbox.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/token_usage.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/token_usage_mysql.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/models/xxljob_handler_config.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/notice/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/notice/uvicorn_monitor.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/notice/wecom_message.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/sentry/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/sentry/sy_sentry.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/services.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/feign.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/feign_client.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/nacos_client_base.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/nacos_config_manager.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/nacos_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/nacos_service_registration.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/deep_agent_server.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_consumer_recovery.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_deep_agent.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_dynamic_max_tokens.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_email.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_encoding_cache.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_mcp_server.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_minimax_reasoning.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_mq.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_oa_login.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_real_summarization.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_summarization_config.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tests/test_summarization_real.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tools/async_utils.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tools/env.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tools/merge_headers.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tools/snowflake.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tools/syemail.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/xxljob/__init__.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/xxljob/xxljob_service.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/tests/test_asyncio_logging.py +0 -0
- {sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/tests/test_sycli.py +0 -0
{sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/agent/deep_agent.py
RENAMED
|
@@ -153,6 +153,44 @@ def _patch_agent_streaming(agent):
|
|
|
153
153
|
_handle_model_output = _hmo_cell.cell_contents
|
|
154
154
|
_name = _name_cell.cell_contents if _name_cell is not None else None
|
|
155
155
|
|
|
156
|
+
def _clamp_max_tokens_for_model(model_, messages):
|
|
157
|
+
"""在 raw_model 上执行 _clamp_max_tokens 逻辑。
|
|
158
|
+
|
|
159
|
+
由于 create_deep_agent 提取了 raw_model(绕过了 LLMWithTokenTracking 包装),
|
|
160
|
+
原本在 LLMWithTokenTracking._agenerate 中自动执行的 _clamp_max_tokens 被跳过,
|
|
161
|
+
导致 max_tokens 不随 input tokens 动态调整,当 input + max_output > context_window
|
|
162
|
+
时触发 400 错误。此函数补上这一逻辑。
|
|
163
|
+
|
|
164
|
+
注意:_get_bound_model 返回的可能是 _ChatModelBinding(RunnableBindingBase 子类),
|
|
165
|
+
需要通过 .bound 取到真正的 ChatOpenAI,否则 max_tokens 只设在 wrapper 上不生效。
|
|
166
|
+
"""
|
|
167
|
+
from sycommon.config.LLMConfig import LLMConfig
|
|
168
|
+
from sycommon.config.Config import Config
|
|
169
|
+
from sycommon.llm.token_utils import clamp_max_tokens
|
|
170
|
+
try:
|
|
171
|
+
# 解包 binding wrapper,取到真正的 ChatModel
|
|
172
|
+
raw_model = getattr(model_, 'bound', model_)
|
|
173
|
+
llm_config = Config().get_llm_config(getattr(raw_model, 'model', None))
|
|
174
|
+
if not llm_config:
|
|
175
|
+
return
|
|
176
|
+
llm_cfg = LLMConfig(**llm_config)
|
|
177
|
+
max_tokens_limit = getattr(llm_cfg, 'maxTokens', None)
|
|
178
|
+
if not max_tokens_limit:
|
|
179
|
+
return
|
|
180
|
+
max_output = getattr(raw_model, 'max_tokens', None)
|
|
181
|
+
if not max_output:
|
|
182
|
+
return
|
|
183
|
+
dynamic_max = clamp_max_tokens(
|
|
184
|
+
raw_model, messages,
|
|
185
|
+
context_window=max_tokens_limit,
|
|
186
|
+
max_output_tokens=max_output,
|
|
187
|
+
)
|
|
188
|
+
SYLogger.debug(
|
|
189
|
+
f"[StreamingPatch] clamp max_tokens: "
|
|
190
|
+
f"context={max_tokens_limit}, max_output={max_output} → {dynamic_max}")
|
|
191
|
+
except Exception as e:
|
|
192
|
+
SYLogger.warning(f"[StreamingPatch] clamp max_tokens failed: {e}")
|
|
193
|
+
|
|
156
194
|
async def _patched_execute_model_async(request):
|
|
157
195
|
"""替代 factory._execute_model_async: 用 astream + config 实现流式回调。"""
|
|
158
196
|
from langchain.agents.middleware.types import ModelResponse
|
|
@@ -162,6 +200,9 @@ def _patch_agent_streaming(agent):
|
|
|
162
200
|
if request.system_message:
|
|
163
201
|
messages = [request.system_message, *messages]
|
|
164
202
|
|
|
203
|
+
# 动态调整 max_tokens,防止 input + max_output 超过上下文窗口
|
|
204
|
+
_clamp_max_tokens_for_model(model_, messages)
|
|
205
|
+
|
|
165
206
|
# 从 ContextVar 读取 LangGraph 注入的 config(含 StreamMessagesHandler)
|
|
166
207
|
config = var_child_runnable_config.get()
|
|
167
208
|
|
|
@@ -278,7 +319,7 @@ class AgentConfig(BaseModel):
|
|
|
278
319
|
debug: bool = False
|
|
279
320
|
|
|
280
321
|
# Rubric 评分配置
|
|
281
|
-
rubric_max_iterations: int =
|
|
322
|
+
rubric_max_iterations: int = 0 # rubric 评估最大迭代次数(0 = 不启用,默认关闭)
|
|
282
323
|
|
|
283
324
|
class Config:
|
|
284
325
|
arbitrary_types_allowed = True
|
|
@@ -30,7 +30,6 @@ from sycommon.heartbeat_process.heartbeat_config import (
|
|
|
30
30
|
RabbitMQMonitorConfig,
|
|
31
31
|
LogConfig
|
|
32
32
|
)
|
|
33
|
-
from sycommon.synacos.dns_cache import NacosDnsCache
|
|
34
33
|
|
|
35
34
|
|
|
36
35
|
def _init_process_logger(log_config: Optional[LogConfig] = None):
|
|
@@ -115,10 +114,6 @@ class HeartbeatProcessWorker:
|
|
|
115
114
|
self._nacos_heartbeat_thread: Optional[threading.Thread] = None
|
|
116
115
|
self._nacos_alert_sent = False
|
|
117
116
|
self._nacos_disconnect_count = 0
|
|
118
|
-
# DNS 缓存状态
|
|
119
|
-
self._dns_cache = NacosDnsCache.get_instance()
|
|
120
|
-
self._using_cached_ip: bool = False
|
|
121
|
-
self._original_server_list = None
|
|
122
117
|
|
|
123
118
|
# RabbitMQ 监控状态
|
|
124
119
|
self._rabbitmq_alert_sent = False
|
|
@@ -226,10 +221,6 @@ class HeartbeatProcessWorker:
|
|
|
226
221
|
f"Nacos 心跳成功,连续成功: {consecutive_success}次"
|
|
227
222
|
)
|
|
228
223
|
|
|
229
|
-
# DNS 缓存:连续成功 3 次后,解析域名并缓存 IP
|
|
230
|
-
if consecutive_success >= 3 and not self._using_cached_ip:
|
|
231
|
-
self._apply_dns_cache()
|
|
232
|
-
|
|
233
224
|
# 恢复通知
|
|
234
225
|
if self._nacos_alert_sent and consecutive_success >= 1:
|
|
235
226
|
self._nacos_alert_sent = False
|
|
@@ -242,9 +233,6 @@ class HeartbeatProcessWorker:
|
|
|
242
233
|
else:
|
|
243
234
|
consecutive_success = 0
|
|
244
235
|
consecutive_fail += 1
|
|
245
|
-
# DNS 缓存:失败时清除缓存并恢复域名
|
|
246
|
-
if self._using_cached_ip:
|
|
247
|
-
self._revert_dns_cache()
|
|
248
236
|
logger.warning(
|
|
249
237
|
f"Nacos 心跳失败,连续失败: {consecutive_fail}次"
|
|
250
238
|
)
|
|
@@ -253,9 +241,6 @@ class HeartbeatProcessWorker:
|
|
|
253
241
|
except Exception as e:
|
|
254
242
|
consecutive_success = 0
|
|
255
243
|
consecutive_fail += 1
|
|
256
|
-
# DNS 缓存:异常时清除缓存并恢复域名
|
|
257
|
-
if self._using_cached_ip:
|
|
258
|
-
self._revert_dns_cache()
|
|
259
244
|
logger.error(f"Nacos 心跳异常: {e}")
|
|
260
245
|
self._handle_nacos_failure(consecutive_fail)
|
|
261
246
|
|
|
@@ -355,60 +340,6 @@ class HeartbeatProcessWorker:
|
|
|
355
340
|
except Exception as e:
|
|
356
341
|
logger.error(f"发送 Nacos 告警失败: {e}")
|
|
357
342
|
|
|
358
|
-
# ── DNS 缓存方法 ─────────────────────────────────────
|
|
359
|
-
|
|
360
|
-
def _apply_dns_cache(self):
|
|
361
|
-
"""连续成功 3 次后,将 Nacos 服务端域名解析为 IP 并替换 server_list。"""
|
|
362
|
-
if self.nacos_client is None:
|
|
363
|
-
return
|
|
364
|
-
|
|
365
|
-
# 备份原始 server_list
|
|
366
|
-
self._original_server_list = list(self.nacos_client.server_list)
|
|
367
|
-
|
|
368
|
-
new_server_list = []
|
|
369
|
-
changed = False
|
|
370
|
-
for host, port in self.nacos_client.server_list:
|
|
371
|
-
if NacosDnsCache.is_ip(host):
|
|
372
|
-
new_server_list.append((host, port))
|
|
373
|
-
continue
|
|
374
|
-
ip = self._dns_cache.resolve(host)
|
|
375
|
-
if ip:
|
|
376
|
-
self._dns_cache.cache_ip(host, ip)
|
|
377
|
-
new_server_list.append((ip, port))
|
|
378
|
-
changed = True
|
|
379
|
-
logger.info(f"DNS 缓存 - {host} -> {ip}")
|
|
380
|
-
else:
|
|
381
|
-
logger.warning(f"DNS 解析失败,保持域名: {host}")
|
|
382
|
-
new_server_list.append((host, port))
|
|
383
|
-
|
|
384
|
-
if changed:
|
|
385
|
-
with self.nacos_client.server_list_lock:
|
|
386
|
-
self.nacos_client.server_list = new_server_list
|
|
387
|
-
self.nacos_client.current_server = new_server_list[0]
|
|
388
|
-
self.nacos_client.server_offset = 0
|
|
389
|
-
self._using_cached_ip = True
|
|
390
|
-
logger.info(f"DNS 缓存已生效, server_list={new_server_list}")
|
|
391
|
-
|
|
392
|
-
def _revert_dns_cache(self):
|
|
393
|
-
"""心跳失败时,恢复原始域名地址,清除 DNS 缓存。"""
|
|
394
|
-
if self._original_server_list is None:
|
|
395
|
-
return
|
|
396
|
-
|
|
397
|
-
if self.nacos_client is None:
|
|
398
|
-
return
|
|
399
|
-
|
|
400
|
-
# 清除 DNS 缓存条目
|
|
401
|
-
for host, _ in self._original_server_list:
|
|
402
|
-
self._dns_cache.invalidate(host)
|
|
403
|
-
|
|
404
|
-
# 恢复原始 server_list
|
|
405
|
-
with self.nacos_client.server_list_lock:
|
|
406
|
-
self.nacos_client.server_list = list(self._original_server_list)
|
|
407
|
-
self.nacos_client.current_server = self._original_server_list[0]
|
|
408
|
-
self.nacos_client.server_offset = 0
|
|
409
|
-
self._using_cached_ip = False
|
|
410
|
-
logger.info(f"DNS 缓存已清除, 恢复域名: {self._original_server_list}")
|
|
411
|
-
|
|
412
343
|
def _run_rabbitmq_monitor(self):
|
|
413
344
|
"""运行 RabbitMQ 连接监控(asyncio 事件循环)
|
|
414
345
|
|
|
@@ -11,6 +11,7 @@ from langchain_core.language_models import BaseChatModel
|
|
|
11
11
|
from pydantic import BaseModel, Field
|
|
12
12
|
|
|
13
13
|
from sycommon.config.LLMConfig import LLMConfig
|
|
14
|
+
from sycommon.llm.token_utils import clamp_max_tokens, count_messages_tokens
|
|
14
15
|
from sycommon.llm.token_usage_mysql_service import TokenUsageMySQLService
|
|
15
16
|
from sycommon.tools.merge_headers import get_header_value
|
|
16
17
|
|
|
@@ -109,64 +110,16 @@ class LLMWithTokenTracking(BaseChatModel):
|
|
|
109
110
|
return
|
|
110
111
|
|
|
111
112
|
try:
|
|
112
|
-
|
|
113
|
+
clamp_max_tokens(
|
|
114
|
+
self.llm, messages,
|
|
115
|
+
context_window=self.llmConfig.maxTokens,
|
|
116
|
+
max_output_tokens=max_output,
|
|
117
|
+
)
|
|
113
118
|
except Exception:
|
|
114
119
|
return
|
|
115
120
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
dynamic_max = min(max_output, max(available, 1024))
|
|
119
|
-
self.llm.max_tokens = dynamic_max
|
|
120
|
-
|
|
121
|
-
@staticmethod
|
|
122
|
-
def _count_tokens(messages) -> int:
|
|
123
|
-
"""精确计算 messages 的 token 数
|
|
124
|
-
|
|
125
|
-
优先使用 tiktoken(OpenAI 兼容模型),否则回退到字符估算。
|
|
126
|
-
中文等非 ASCII 文本 chars_per_token 约 1.0-1.5,比英文 2.0-4.0 更密集。
|
|
127
|
-
"""
|
|
128
|
-
total_chars = 0
|
|
129
|
-
for msg in messages:
|
|
130
|
-
content = getattr(msg, 'content', '')
|
|
131
|
-
if isinstance(content, str):
|
|
132
|
-
total_chars += len(content)
|
|
133
|
-
elif isinstance(content, list):
|
|
134
|
-
for part in content:
|
|
135
|
-
if isinstance(part, str):
|
|
136
|
-
total_chars += len(part)
|
|
137
|
-
elif isinstance(part, dict):
|
|
138
|
-
total_chars += len(str(part))
|
|
139
|
-
|
|
140
|
-
# 检查是否有高比例非 ASCII(中文/日文等)
|
|
141
|
-
sample = str(total_chars)
|
|
142
|
-
non_ascii = sum(1 for c in sample if ord(c) > 127)
|
|
143
|
-
ratio = non_ascii / max(len(sample), 1)
|
|
144
|
-
|
|
145
|
-
# 中文等语言 chars_per_token 约 1.5,英文约 4.0
|
|
146
|
-
chars_per_token = 1.5 if ratio > 0.3 else 3.5
|
|
147
|
-
|
|
148
|
-
# 尝试 tiktoken 精确计数
|
|
149
|
-
try:
|
|
150
|
-
import tiktoken
|
|
151
|
-
enc = tiktoken.get_encoding("cl100k_base")
|
|
152
|
-
token_count = 0
|
|
153
|
-
for msg in messages:
|
|
154
|
-
content = getattr(msg, 'content', '')
|
|
155
|
-
if isinstance(content, str):
|
|
156
|
-
token_count += len(enc.encode(content))
|
|
157
|
-
elif isinstance(content, list):
|
|
158
|
-
for part in content:
|
|
159
|
-
if isinstance(part, str):
|
|
160
|
-
token_count += len(enc.encode(part))
|
|
161
|
-
elif isinstance(part, dict):
|
|
162
|
-
token_count += len(enc.encode(str(part)))
|
|
163
|
-
# 加上消息格式开销(role、separator 等)
|
|
164
|
-
return token_count + len(messages) * 4
|
|
165
|
-
except Exception:
|
|
166
|
-
pass
|
|
167
|
-
|
|
168
|
-
# 回退:字符估算 + 每条消息 4 token 格式开销
|
|
169
|
-
return int(total_chars / chars_per_token) + len(messages) * 4
|
|
121
|
+
# 统一使用 token_utils.count_messages_tokens,保留静态方法作为兼容别名
|
|
122
|
+
_count_tokens = staticmethod(count_messages_tokens)
|
|
170
123
|
|
|
171
124
|
def _generate(self, messages, stop=None, run_manager=None, **kwargs):
|
|
172
125
|
"""
|
|
@@ -0,0 +1,96 @@
|
|
|
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
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def count_messages_tokens(messages: List[BaseMessage]) -> int:
|
|
17
|
+
"""精确计算 messages 的 token 数。
|
|
18
|
+
|
|
19
|
+
优先使用 tiktoken(cl100k_base 编码),否则回退到字符估算。
|
|
20
|
+
中文等非 ASCII 文本 chars_per_token 约 1.0-1.5,比英文 2.0-4.0 更密集。
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
messages: LangChain 消息列表。
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
估算的 token 总数(含每条消息 4 token 格式开销)。
|
|
27
|
+
"""
|
|
28
|
+
total_chars = 0
|
|
29
|
+
for msg in messages:
|
|
30
|
+
content = getattr(msg, 'content', '')
|
|
31
|
+
if isinstance(content, str):
|
|
32
|
+
total_chars += len(content)
|
|
33
|
+
elif isinstance(content, list):
|
|
34
|
+
for part in content:
|
|
35
|
+
if isinstance(part, str):
|
|
36
|
+
total_chars += len(part)
|
|
37
|
+
elif isinstance(part, dict):
|
|
38
|
+
total_chars += len(str(part))
|
|
39
|
+
|
|
40
|
+
# 尝试 tiktoken 精确计数
|
|
41
|
+
try:
|
|
42
|
+
import tiktoken
|
|
43
|
+
enc = tiktoken.get_encoding("cl100k_base")
|
|
44
|
+
token_count = 0
|
|
45
|
+
for msg in messages:
|
|
46
|
+
content = getattr(msg, 'content', '')
|
|
47
|
+
if isinstance(content, str):
|
|
48
|
+
token_count += len(enc.encode(content))
|
|
49
|
+
elif isinstance(content, list):
|
|
50
|
+
for part in content:
|
|
51
|
+
if isinstance(part, str):
|
|
52
|
+
token_count += len(enc.encode(part))
|
|
53
|
+
elif isinstance(part, dict):
|
|
54
|
+
token_count += len(enc.encode(str(part)))
|
|
55
|
+
return token_count + len(messages) * 4
|
|
56
|
+
except Exception:
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
# 回退:字符估算(中文 1.5 chars/token,英文 3.5 chars/token)
|
|
60
|
+
non_ascii = sum(1 for c in str(total_chars) if ord(c) > 127)
|
|
61
|
+
ratio = non_ascii / max(len(str(total_chars)), 1)
|
|
62
|
+
chars_per_token = 1.5 if ratio > 0.3 else 3.5
|
|
63
|
+
return int(total_chars / chars_per_token) + len(messages) * 4
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def clamp_max_tokens(
|
|
67
|
+
model,
|
|
68
|
+
messages: List[BaseMessage],
|
|
69
|
+
*,
|
|
70
|
+
context_window: int,
|
|
71
|
+
max_output_tokens: int,
|
|
72
|
+
buffer: int = 8192,
|
|
73
|
+
min_output: int = 1024,
|
|
74
|
+
) -> int:
|
|
75
|
+
"""动态调整模型的 max_tokens,确保 input + max_output 不超过上下文窗口。
|
|
76
|
+
|
|
77
|
+
每次调用前根据当前 input tokens 精确计算可用空间,
|
|
78
|
+
将 model.max_tokens = min(max_output_tokens, context_window - input - buffer),
|
|
79
|
+
最低保底 min_output。
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
model: 拥有 ``max_tokens`` 属性的 ChatModel 实例。
|
|
83
|
+
messages: 即将发送给模型的消息列表。
|
|
84
|
+
context_window: 模型上下文窗口大小(来自 LLMConfig.maxTokens)。
|
|
85
|
+
max_output_tokens: 配置的最大输出 token 数(来自 LLMConfig.maxOutputTokens)。
|
|
86
|
+
buffer: 保留的余量 token 数,默认 8192。
|
|
87
|
+
min_output: 最小输出 token 数保底值,默认 1024。
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
调整后的 max_tokens 值。
|
|
91
|
+
"""
|
|
92
|
+
input_est = count_messages_tokens(messages)
|
|
93
|
+
available = context_window - input_est - buffer
|
|
94
|
+
dynamic_max = min(max_output_tokens, max(available, min_output))
|
|
95
|
+
model.max_tokens = dynamic_max
|
|
96
|
+
return dynamic_max
|
{sycommon_python_lib-0.2.5a28 → sycommon_python_lib-0.2.5a29}/src/sycommon/llm/usage_token.py
RENAMED
|
@@ -21,6 +21,7 @@ from sycommon.config.LLMConfig import LLMConfig
|
|
|
21
21
|
from sycommon.llm.struct_token import StructuredRunnableWithToken
|
|
22
22
|
from sycommon.llm.output_fixing_runnable import OutputFixingRunnable
|
|
23
23
|
from sycommon.llm.native_with_fallback_runnable import NativeWithFallbackRunnable
|
|
24
|
+
from sycommon.llm.token_utils import clamp_max_tokens, count_messages_tokens
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class LLMWithAutoTokenUsage(BaseChatModel):
|
|
@@ -175,55 +176,16 @@ class LLMWithAutoTokenUsage(BaseChatModel):
|
|
|
175
176
|
return
|
|
176
177
|
|
|
177
178
|
try:
|
|
178
|
-
|
|
179
|
+
clamp_max_tokens(
|
|
180
|
+
self.llm, messages,
|
|
181
|
+
context_window=self.llmConfig.maxTokens,
|
|
182
|
+
max_output_tokens=max_output,
|
|
183
|
+
)
|
|
179
184
|
except Exception:
|
|
180
185
|
return
|
|
181
186
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
dynamic_max = min(max_output, max(available, 1024))
|
|
185
|
-
self.llm.max_tokens = dynamic_max
|
|
186
|
-
|
|
187
|
-
@staticmethod
|
|
188
|
-
def _count_tokens(messages) -> int:
|
|
189
|
-
"""精确计算 messages 的 token 数"""
|
|
190
|
-
total_chars = 0
|
|
191
|
-
for msg in messages:
|
|
192
|
-
content = getattr(msg, 'content', '')
|
|
193
|
-
if isinstance(content, str):
|
|
194
|
-
total_chars += len(content)
|
|
195
|
-
elif isinstance(content, list):
|
|
196
|
-
for part in content:
|
|
197
|
-
if isinstance(part, str):
|
|
198
|
-
total_chars += len(part)
|
|
199
|
-
elif isinstance(part, dict):
|
|
200
|
-
total_chars += len(str(part))
|
|
201
|
-
|
|
202
|
-
# 尝试 tiktoken 精确计数
|
|
203
|
-
try:
|
|
204
|
-
import tiktoken
|
|
205
|
-
enc = tiktoken.get_encoding("cl100k_base")
|
|
206
|
-
token_count = 0
|
|
207
|
-
for msg in messages:
|
|
208
|
-
content = getattr(msg, 'content', '')
|
|
209
|
-
if isinstance(content, str):
|
|
210
|
-
token_count += len(enc.encode(content))
|
|
211
|
-
elif isinstance(content, list):
|
|
212
|
-
for part in content:
|
|
213
|
-
if isinstance(part, str):
|
|
214
|
-
token_count += len(enc.encode(part))
|
|
215
|
-
elif isinstance(part, dict):
|
|
216
|
-
token_count += len(enc.encode(str(part)))
|
|
217
|
-
return token_count + len(messages) * 4
|
|
218
|
-
except Exception:
|
|
219
|
-
pass
|
|
220
|
-
|
|
221
|
-
# 回退:字符估算(中文 1.5,英文 3.5)
|
|
222
|
-
sample = str(total_chars)
|
|
223
|
-
non_ascii = sum(1 for c in sample if ord(c) > 127)
|
|
224
|
-
ratio = non_ascii / max(len(sample), 1)
|
|
225
|
-
chars_per_token = 1.5 if ratio > 0.3 else 3.5
|
|
226
|
-
return int(total_chars / chars_per_token) + len(messages) * 4
|
|
187
|
+
# 统一使用 token_utils.count_messages_tokens,保留静态方法作为兼容别名
|
|
188
|
+
_count_tokens = staticmethod(count_messages_tokens)
|
|
227
189
|
|
|
228
190
|
# ========== 实现BaseChatModel抽象方法 ==========
|
|
229
191
|
def _generate(self, messages, stop=None, run_manager=None, **kwargs):
|
|
@@ -2,7 +2,6 @@ import asyncio
|
|
|
2
2
|
import threading
|
|
3
3
|
import time
|
|
4
4
|
from sycommon.logging.kafka_log import SYLogger
|
|
5
|
-
from sycommon.synacos.dns_cache import NacosDnsCache
|
|
6
5
|
from sycommon.synacos.nacos_client_base import NacosClientBase
|
|
7
6
|
from sycommon.synacos.nacos_service_registration import NacosServiceRegistration
|
|
8
7
|
|
|
@@ -63,10 +62,6 @@ class NacosHeartbeatManager:
|
|
|
63
62
|
self._alert_sent: bool = False
|
|
64
63
|
self._disconnect_count: int = 0
|
|
65
64
|
self._alert_fail_count: int = 0
|
|
66
|
-
# DNS 缓存状态
|
|
67
|
-
self._dns_cache = NacosDnsCache.get_instance()
|
|
68
|
-
self._using_cached_ip: bool = False
|
|
69
|
-
self._original_server_list = None # 备份原始 (domain, port) 列表
|
|
70
65
|
|
|
71
66
|
def start_heartbeat(self):
|
|
72
67
|
"""启动心跳线程(确保单例)"""
|
|
@@ -122,9 +117,6 @@ class NacosHeartbeatManager:
|
|
|
122
117
|
SYLogger.info(
|
|
123
118
|
f"nacos:心跳发送成功 - 间隔: {self.heartbeat_interval}秒, 连续成功: {consecutive_success}次"
|
|
124
119
|
)
|
|
125
|
-
# DNS 缓存:连续成功 3 次后,解析域名并缓存 IP
|
|
126
|
-
if consecutive_success >= 3 and not self._using_cached_ip:
|
|
127
|
-
self._apply_dns_cache()
|
|
128
120
|
# 恢复后发送通知(心跳成功一次即恢复)
|
|
129
121
|
if self._alert_sent and consecutive_success >= 1:
|
|
130
122
|
SYLogger.info(f"nacos:检测恢复状态 - _alert_sent={self._alert_sent}, consecutive_success={consecutive_success}")
|
|
@@ -142,9 +134,6 @@ class NacosHeartbeatManager:
|
|
|
142
134
|
consecutive_success = 0 # 失败时重置连续成功计数
|
|
143
135
|
consecutive_fail += 1
|
|
144
136
|
self._heartbeat_fail_count += 1
|
|
145
|
-
# DNS 缓存:失败时清除缓存并恢复域名
|
|
146
|
-
if self._using_cached_ip:
|
|
147
|
-
self._revert_dns_cache()
|
|
148
137
|
SYLogger.warning(
|
|
149
138
|
f"nacos:心跳发送失败 - 连续失败: {consecutive_fail}次"
|
|
150
139
|
)
|
|
@@ -175,9 +164,6 @@ class NacosHeartbeatManager:
|
|
|
175
164
|
consecutive_fail += 1
|
|
176
165
|
consecutive_success = 0 # 异常时重置连续成功计数
|
|
177
166
|
self._heartbeat_fail_count += 1
|
|
178
|
-
# DNS 缓存:异常时清除缓存并恢复域名
|
|
179
|
-
if self._using_cached_ip:
|
|
180
|
-
self._revert_dns_cache()
|
|
181
167
|
SYLogger.error(
|
|
182
168
|
f"nacos:心跳异常: {str(e)}, 连续失败: {consecutive_fail}次")
|
|
183
169
|
|
|
@@ -257,59 +243,3 @@ class NacosHeartbeatManager:
|
|
|
257
243
|
else:
|
|
258
244
|
SYLogger.warning(f"nacos:心跳发送失败,Nacos返回: {result}")
|
|
259
245
|
return False
|
|
260
|
-
|
|
261
|
-
# ── DNS 缓存方法 ─────────────────────────────────────
|
|
262
|
-
|
|
263
|
-
def _apply_dns_cache(self):
|
|
264
|
-
"""连续成功 3 次后,将 Nacos 服务端域名解析为 IP 并替换 server_list。"""
|
|
265
|
-
nacos_client = self.client_base.nacos_client
|
|
266
|
-
if nacos_client is None:
|
|
267
|
-
return
|
|
268
|
-
|
|
269
|
-
# 备份原始 server_list
|
|
270
|
-
self._original_server_list = list(nacos_client.server_list)
|
|
271
|
-
|
|
272
|
-
new_server_list = []
|
|
273
|
-
changed = False
|
|
274
|
-
for host, port in nacos_client.server_list:
|
|
275
|
-
if NacosDnsCache.is_ip(host):
|
|
276
|
-
new_server_list.append((host, port))
|
|
277
|
-
continue
|
|
278
|
-
ip = self._dns_cache.resolve(host)
|
|
279
|
-
if ip:
|
|
280
|
-
self._dns_cache.cache_ip(host, ip)
|
|
281
|
-
new_server_list.append((ip, port))
|
|
282
|
-
changed = True
|
|
283
|
-
SYLogger.info(f"nacos:DNS 缓存 - {host} -> {ip}")
|
|
284
|
-
else:
|
|
285
|
-
SYLogger.warning(f"nacos:DNS 解析失败,保持域名: {host}")
|
|
286
|
-
new_server_list.append((host, port))
|
|
287
|
-
|
|
288
|
-
if changed:
|
|
289
|
-
with nacos_client.server_list_lock:
|
|
290
|
-
nacos_client.server_list = new_server_list
|
|
291
|
-
nacos_client.current_server = new_server_list[0]
|
|
292
|
-
nacos_client.server_offset = 0
|
|
293
|
-
self._using_cached_ip = True
|
|
294
|
-
SYLogger.info(f"nacos:DNS 缓存已生效, server_list={new_server_list}")
|
|
295
|
-
|
|
296
|
-
def _revert_dns_cache(self):
|
|
297
|
-
"""心跳失败时,恢复原始域名地址,清除 DNS 缓存。"""
|
|
298
|
-
if self._original_server_list is None:
|
|
299
|
-
return
|
|
300
|
-
|
|
301
|
-
nacos_client = self.client_base.nacos_client
|
|
302
|
-
if nacos_client is None:
|
|
303
|
-
return
|
|
304
|
-
|
|
305
|
-
# 清除 DNS 缓存条目
|
|
306
|
-
for host, _ in self._original_server_list:
|
|
307
|
-
self._dns_cache.invalidate(host)
|
|
308
|
-
|
|
309
|
-
# 恢复原始 server_list
|
|
310
|
-
with nacos_client.server_list_lock:
|
|
311
|
-
nacos_client.server_list = list(self._original_server_list)
|
|
312
|
-
nacos_client.current_server = self._original_server_list[0]
|
|
313
|
-
nacos_client.server_offset = 0
|
|
314
|
-
self._using_cached_ip = False
|
|
315
|
-
SYLogger.info(f"nacos:DNS 缓存已清除, 恢复域名: {self._original_server_list}")
|
|
@@ -191,6 +191,7 @@ src/sycommon/llm/struct_token.py
|
|
|
191
191
|
src/sycommon/llm/sy_langfuse.py
|
|
192
192
|
src/sycommon/llm/token_usage_es_service.py
|
|
193
193
|
src/sycommon/llm/token_usage_mysql_service.py
|
|
194
|
+
src/sycommon/llm/token_utils.py
|
|
194
195
|
src/sycommon/llm/usage_token.py
|
|
195
196
|
src/sycommon/llm/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4
|
|
196
197
|
src/sycommon/llm/tiktoken_cache/fb374d419588a4632f3f557e76b4b70aebbca790
|
|
@@ -246,7 +247,6 @@ src/sycommon/sse/__init__.py
|
|
|
246
247
|
src/sycommon/sse/event.py
|
|
247
248
|
src/sycommon/sse/sse.py
|
|
248
249
|
src/sycommon/synacos/__init__.py
|
|
249
|
-
src/sycommon/synacos/dns_cache.py
|
|
250
250
|
src/sycommon/synacos/example.py
|
|
251
251
|
src/sycommon/synacos/example2.py
|
|
252
252
|
src/sycommon/synacos/feign.py
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"""Nacos 服务端地址 DNS 缓存模块。
|
|
2
|
-
|
|
3
|
-
心跳连续成功 3 次后缓存域名解析结果,避免后续每次心跳都做 DNS 解析。
|
|
4
|
-
心跳失败时清除缓存,重新走域名解析,再次连续成功 3 次后重新缓存。
|
|
5
|
-
"""
|
|
6
|
-
import socket
|
|
7
|
-
import threading
|
|
8
|
-
from typing import Dict, Optional
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class NacosDnsCache:
|
|
12
|
-
"""线程安全的 Nacos 服务端地址 DNS 缓存(单例)。"""
|
|
13
|
-
|
|
14
|
-
_instance = None
|
|
15
|
-
_init_lock = threading.Lock()
|
|
16
|
-
|
|
17
|
-
def __init__(self):
|
|
18
|
-
self._cache: Dict[str, str] = {} # domain -> resolved IP
|
|
19
|
-
self._lock = threading.Lock()
|
|
20
|
-
|
|
21
|
-
@classmethod
|
|
22
|
-
def get_instance(cls) -> "NacosDnsCache":
|
|
23
|
-
if cls._instance is None:
|
|
24
|
-
with cls._init_lock:
|
|
25
|
-
if cls._instance is None:
|
|
26
|
-
cls._instance = cls()
|
|
27
|
-
return cls._instance
|
|
28
|
-
|
|
29
|
-
# ── 公共方法 ──────────────────────────────────────────
|
|
30
|
-
|
|
31
|
-
def resolve(self, hostname: str) -> Optional[str]:
|
|
32
|
-
"""将域名解析为 IP 地址,失败返回 None。已为 IP 的直接返回。"""
|
|
33
|
-
if self.is_ip(hostname):
|
|
34
|
-
return hostname
|
|
35
|
-
try:
|
|
36
|
-
return socket.gethostbyname(hostname)
|
|
37
|
-
except (socket.gaierror, socket.herror, OSError):
|
|
38
|
-
return None
|
|
39
|
-
|
|
40
|
-
def cache_ip(self, domain: str, ip: str):
|
|
41
|
-
"""显式缓存 domain -> IP 映射。"""
|
|
42
|
-
with self._lock:
|
|
43
|
-
self._cache[domain] = ip
|
|
44
|
-
|
|
45
|
-
def get_cached(self, domain: str) -> Optional[str]:
|
|
46
|
-
"""返回缓存的 IP,无缓存返回 None。"""
|
|
47
|
-
with self._lock:
|
|
48
|
-
return self._cache.get(domain)
|
|
49
|
-
|
|
50
|
-
def invalidate(self, domain: str):
|
|
51
|
-
"""删除指定域名的缓存条目。"""
|
|
52
|
-
with self._lock:
|
|
53
|
-
self._cache.pop(domain, None)
|
|
54
|
-
|
|
55
|
-
def clear(self):
|
|
56
|
-
"""清空所有缓存。"""
|
|
57
|
-
with self._lock:
|
|
58
|
-
self._cache.clear()
|
|
59
|
-
|
|
60
|
-
@staticmethod
|
|
61
|
-
def is_ip(addr: str) -> bool:
|
|
62
|
-
"""判断 addr 是否已是 IP 地址(IPv4),跳过解析。"""
|
|
63
|
-
try:
|
|
64
|
-
socket.inet_aton(addr)
|
|
65
|
-
return True
|
|
66
|
-
except (socket.error, OSError):
|
|
67
|
-
return False
|
|
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.5a28 → sycommon_python_lib-0.2.5a29}/src/command/templates/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|