sycommon-python-lib 0.2.0b28__tar.gz → 0.2.0b30__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.0b28 → sycommon_python_lib-0.2.0b30}/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/pyproject.toml +1 -1
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +32 -9
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/llm_with_token_tracking.py +9 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/native_smart_retry_runnable.py +17 -9
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/smart_retry_runnable.py +15 -8
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/usage_token.py +20 -5
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_service.py +34 -14
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/nacos_service.py +31 -12
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/README.md +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/setup.cfg +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/core/console.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/core/models.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/core/project.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/core/utils.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/templates/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/templates/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/templates/base/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/templates/web/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/01_basic_agent.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/02_tool_agent.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/03_structured_output.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/04_memory_agent.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/05_streaming.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/06_multi_agent.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/07_skills_agent.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/08_middleware.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/09_interrupt.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/10_custom_llm.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/11_complex_workflow.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/12_batch_processing.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/01_basic_monitoring.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/02_permission_control.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/03_tool_skill_filter.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/04_caching_retry.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/05_sanitization.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/06_tracking.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/07_advanced.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/08_progressive_skills.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/middleware/override_examples.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/examples/virtual_employee_demo.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/exports.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/get_agent.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/skills/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/skills/examples/faq_handler/scripts/search.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/skills/exports.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/virtual_employee.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/ElasticsearchConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/LangfuseConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/RedisConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/SentryConfig.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/database/async_base_db_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/database/async_database_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/database/elasticsearch_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/database/redis_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/database/token_usage_db_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/heartbeat_process/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/embedding.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/get_llm.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/llm_logger.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/llm_tokens.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/struct_token.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/sy_langfuse.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/token_usage_es_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/async_sql_logger.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/kafka_log.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/logger_levels.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/process_logger.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/context.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/traceid.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/token_usage.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/token_usage_mysql.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/notice/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/notice/uvicorn_monitor.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/sentry/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/sentry/sy_sentry.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/services.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/feign.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/feign_client.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/nacos_client_base.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/nacos_config_manager.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/nacos_service_registration.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tests/test_email.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tests/test_mq.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/async_utils.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/env.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/merge_headers.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/snowflake.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/syemail.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon_python_lib.egg-info/SOURCES.txt +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
- {sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
|
@@ -16,7 +16,6 @@ import atexit
|
|
|
16
16
|
import multiprocessing
|
|
17
17
|
import os
|
|
18
18
|
from multiprocessing import Process, Event
|
|
19
|
-
from multiprocessing.context import ForkContext
|
|
20
19
|
from multiprocessing.synchronize import Event as EventType
|
|
21
20
|
from typing import Optional
|
|
22
21
|
|
|
@@ -104,8 +103,11 @@ class HeartbeatProcessManager:
|
|
|
104
103
|
优先级:
|
|
105
104
|
1. 环境变量 HEARTBEAT_PROCESS_MODE
|
|
106
105
|
2. 代码设置 enable_process_mode()
|
|
106
|
+
3. 操作系统检测(Windows 默认禁用)
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
默认:
|
|
109
|
+
- Windows: 禁用进程模式(spawn 模式有限制)
|
|
110
|
+
- macOS/Linux: 启用进程模式
|
|
109
111
|
"""
|
|
110
112
|
# 环境变量优先
|
|
111
113
|
env_mode = os.getenv('HEARTBEAT_PROCESS_MODE', '').lower()
|
|
@@ -114,7 +116,14 @@ class HeartbeatProcessManager:
|
|
|
114
116
|
if env_mode in ('true', '1', 'yes'):
|
|
115
117
|
return True
|
|
116
118
|
|
|
117
|
-
#
|
|
119
|
+
# Windows 默认禁用进程模式(spawn 模式需要 if __name__ == '__main__' 保护)
|
|
120
|
+
# Windows 使用 spawn 模式启动子进程,要求主模块必须有 if __name__ == '__main__': 保护。
|
|
121
|
+
# 但用户的 app.py 在模块顶层调用了 Services.plugins(),导致子进程启动时重新执行这些代码。
|
|
122
|
+
import platform
|
|
123
|
+
if platform.system() == 'Windows':
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
# macOS/Linux 默认启用进程模式
|
|
118
127
|
return True
|
|
119
128
|
|
|
120
129
|
@classmethod
|
|
@@ -208,16 +217,24 @@ class HeartbeatProcessManager:
|
|
|
208
217
|
worker.run()
|
|
209
218
|
|
|
210
219
|
@classmethod
|
|
211
|
-
def stop(cls, timeout: float = 10.0) -> None:
|
|
220
|
+
def stop(cls, timeout: float = 10.0, from_signal_handler: bool = False) -> None:
|
|
212
221
|
"""停止心跳进程
|
|
213
222
|
|
|
214
223
|
Args:
|
|
215
224
|
timeout: 等待进程退出的超时时间(秒)
|
|
225
|
+
from_signal_handler: 是否从信号处理函数中调用(信号处理函数中不能使用 Loguru)
|
|
216
226
|
"""
|
|
217
227
|
if not cls._is_running or cls._process is None:
|
|
218
228
|
return
|
|
219
229
|
|
|
220
|
-
|
|
230
|
+
def _log(msg: str):
|
|
231
|
+
"""信号处理函数中使用 print,其他情况使用 logger"""
|
|
232
|
+
if from_signal_handler:
|
|
233
|
+
print(f"[HeartbeatProcessManager] {msg}")
|
|
234
|
+
else:
|
|
235
|
+
logger.info(msg)
|
|
236
|
+
|
|
237
|
+
_log("正在停止心跳进程...")
|
|
221
238
|
|
|
222
239
|
try:
|
|
223
240
|
# 设置停止信号
|
|
@@ -228,17 +245,23 @@ class HeartbeatProcessManager:
|
|
|
228
245
|
cls._process.join(timeout=timeout)
|
|
229
246
|
|
|
230
247
|
if cls._process.is_alive():
|
|
231
|
-
|
|
248
|
+
_log("心跳进程未能在超时时间内退出,强制终止")
|
|
232
249
|
cls._process.terminate()
|
|
233
250
|
cls._process.join(timeout=2.0)
|
|
234
251
|
|
|
235
252
|
if cls._process.is_alive():
|
|
236
|
-
|
|
253
|
+
if from_signal_handler:
|
|
254
|
+
print("[HeartbeatProcessManager] 心跳进程强制终止失败")
|
|
255
|
+
else:
|
|
256
|
+
logger.error("心跳进程强制终止失败")
|
|
237
257
|
|
|
238
|
-
|
|
258
|
+
_log("心跳进程已停止")
|
|
239
259
|
|
|
240
260
|
except Exception as e:
|
|
241
|
-
|
|
261
|
+
if from_signal_handler:
|
|
262
|
+
print(f"[HeartbeatProcessManager] 停止心跳进程异常: {e}")
|
|
263
|
+
else:
|
|
264
|
+
logger.error(f"停止心跳进程异常: {e}")
|
|
242
265
|
finally:
|
|
243
266
|
cls._cleanup()
|
|
244
267
|
|
|
@@ -200,6 +200,15 @@ class LLMWithTokenTracking(BaseChatModel):
|
|
|
200
200
|
def _llm_type(self) -> str:
|
|
201
201
|
return self.llm._llm_type
|
|
202
202
|
|
|
203
|
+
def _stream(self, messages, stop=None, run_manager=None, **kwargs):
|
|
204
|
+
"""流式生成 - 委托给底层 LLM"""
|
|
205
|
+
yield from self.llm._stream(messages, stop=stop, run_manager=run_manager, **kwargs)
|
|
206
|
+
|
|
207
|
+
async def _astream(self, messages, stop=None, run_manager=None, **kwargs):
|
|
208
|
+
"""异步流式生成 - 委托给底层 LLM"""
|
|
209
|
+
async for chunk in self.llm._astream(messages, stop=stop, run_manager=run_manager, **kwargs):
|
|
210
|
+
yield chunk
|
|
211
|
+
|
|
203
212
|
def __getattr__(self, name):
|
|
204
213
|
"""代理所有其他属性到原始 llm(如 model_name, max_tokens, with_structured_output 等)"""
|
|
205
214
|
try:
|
|
@@ -46,8 +46,9 @@ class NativeSmartRetryRunnable(Runnable):
|
|
|
46
46
|
def _process_content(self, content: str) -> str:
|
|
47
47
|
"""处理内容(移除代码块标记、规范化 JSON)"""
|
|
48
48
|
content = content.strip("```json").strip("```").strip()
|
|
49
|
-
content = content.replace("None", "null").replace(
|
|
50
|
-
|
|
49
|
+
content = content.replace("None", "null").replace(
|
|
50
|
+
"none", "null").replace("NONE", "null")
|
|
51
|
+
content = content.replace("'", '"')
|
|
51
52
|
return content
|
|
52
53
|
|
|
53
54
|
def _try_parse_result(self, result: Any) -> BaseModel:
|
|
@@ -77,7 +78,8 @@ class NativeSmartRetryRunnable(Runnable):
|
|
|
77
78
|
|
|
78
79
|
def invoke(self, input: Any, config: Optional[RunnableConfig] = None) -> BaseModel:
|
|
79
80
|
"""同步调用(带智能修正重试)"""
|
|
80
|
-
messages = input if isinstance(
|
|
81
|
+
messages = input if isinstance(
|
|
82
|
+
input, list) else input.get("messages", [])
|
|
81
83
|
last_error = None
|
|
82
84
|
last_result = None
|
|
83
85
|
result = None
|
|
@@ -94,7 +96,8 @@ class NativeSmartRetryRunnable(Runnable):
|
|
|
94
96
|
SYLogger.info(f"[原生智能修正] 第 {attempt} 次尝试,错误: {last_error}")
|
|
95
97
|
|
|
96
98
|
# 构建修正请求
|
|
97
|
-
parser = PydanticOutputParser(
|
|
99
|
+
parser = PydanticOutputParser(
|
|
100
|
+
pydantic_object=self.output_model)
|
|
98
101
|
correction_input = {
|
|
99
102
|
"messages": messages,
|
|
100
103
|
"error_message": str(last_error),
|
|
@@ -103,7 +106,8 @@ class NativeSmartRetryRunnable(Runnable):
|
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
correction_chain = self.correction_prompt | self.llm
|
|
106
|
-
raw_response = correction_chain.invoke(
|
|
109
|
+
raw_response = correction_chain.invoke(
|
|
110
|
+
correction_input, config=config)
|
|
107
111
|
content = self._extract_content(raw_response)
|
|
108
112
|
|
|
109
113
|
# 尝试从修正后的响应中提取结构化数据
|
|
@@ -117,13 +121,15 @@ class NativeSmartRetryRunnable(Runnable):
|
|
|
117
121
|
SYLogger.warning(f"[原生智能修正] 第 {attempt + 1} 次失败: {e}")
|
|
118
122
|
|
|
119
123
|
if attempt == self.max_retries - 1:
|
|
120
|
-
raise ValueError(
|
|
124
|
+
raise ValueError(
|
|
125
|
+
f"经过 {self.max_retries} 次尝试仍无法获取有效结果: {last_error}") from last_error
|
|
121
126
|
|
|
122
127
|
raise ValueError("未知错误")
|
|
123
128
|
|
|
124
129
|
async def ainvoke(self, input: Any, config: Optional[RunnableConfig] = None) -> BaseModel:
|
|
125
130
|
"""异步调用(带智能修正重试)"""
|
|
126
|
-
messages = input if isinstance(
|
|
131
|
+
messages = input if isinstance(
|
|
132
|
+
input, list) else input.get("messages", [])
|
|
127
133
|
last_error = None
|
|
128
134
|
last_result = None
|
|
129
135
|
result = None
|
|
@@ -140,7 +146,8 @@ class NativeSmartRetryRunnable(Runnable):
|
|
|
140
146
|
SYLogger.info(f"[原生智能修正] 第 {attempt} 次尝试,错误: {last_error}")
|
|
141
147
|
|
|
142
148
|
# 构建修正请求
|
|
143
|
-
parser = PydanticOutputParser(
|
|
149
|
+
parser = PydanticOutputParser(
|
|
150
|
+
pydantic_object=self.output_model)
|
|
144
151
|
correction_input = {
|
|
145
152
|
"messages": messages,
|
|
146
153
|
"error_message": str(last_error),
|
|
@@ -163,6 +170,7 @@ class NativeSmartRetryRunnable(Runnable):
|
|
|
163
170
|
SYLogger.warning(f"[原生智能修正] 第 {attempt + 1} 次失败: {e}")
|
|
164
171
|
|
|
165
172
|
if attempt == self.max_retries - 1:
|
|
166
|
-
raise ValueError(
|
|
173
|
+
raise ValueError(
|
|
174
|
+
f"经过 {self.max_retries} 次尝试仍无法获取有效结果: {last_error}") from last_error
|
|
167
175
|
|
|
168
176
|
raise ValueError("未知错误")
|
|
@@ -49,13 +49,15 @@ class SmartRetryRunnable(Runnable):
|
|
|
49
49
|
def _process_content(self, content: str) -> str:
|
|
50
50
|
"""处理内容(移除代码块标记、规范化 JSON)"""
|
|
51
51
|
content = content.strip("```json").strip("```").strip()
|
|
52
|
-
content = content.replace("None", "null").replace(
|
|
53
|
-
|
|
52
|
+
content = content.replace("None", "null").replace(
|
|
53
|
+
"none", "null").replace("NONE", "null")
|
|
54
|
+
content = content.replace("'", '"')
|
|
54
55
|
return content
|
|
55
56
|
|
|
56
57
|
def invoke(self, input: Any, config: Optional[RunnableConfig] = None) -> BaseModel:
|
|
57
58
|
"""同步调用(带智能修正重试)"""
|
|
58
|
-
messages = input.get("messages", []) if isinstance(
|
|
59
|
+
messages = input.get("messages", []) if isinstance(
|
|
60
|
+
input, dict) else input
|
|
59
61
|
last_error = None
|
|
60
62
|
last_content = None
|
|
61
63
|
|
|
@@ -64,7 +66,8 @@ class SmartRetryRunnable(Runnable):
|
|
|
64
66
|
# 第一次尝试或修正后的尝试
|
|
65
67
|
if attempt == 0:
|
|
66
68
|
# 使用 process_chain(包含 base_chain + 处理步骤)
|
|
67
|
-
raw_response = self.process_chain.invoke(
|
|
69
|
+
raw_response = self.process_chain.invoke(
|
|
70
|
+
input, config=config)
|
|
68
71
|
content = self._extract_content(raw_response)
|
|
69
72
|
processed_content = self._process_content(content)
|
|
70
73
|
else:
|
|
@@ -80,7 +83,8 @@ class SmartRetryRunnable(Runnable):
|
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
correction_chain = self.correction_prompt | self.llm
|
|
83
|
-
raw_response = correction_chain.invoke(
|
|
86
|
+
raw_response = correction_chain.invoke(
|
|
87
|
+
correction_input, config=config)
|
|
84
88
|
content = self._extract_content(raw_response)
|
|
85
89
|
processed_content = self._process_content(content)
|
|
86
90
|
|
|
@@ -98,13 +102,15 @@ class SmartRetryRunnable(Runnable):
|
|
|
98
102
|
|
|
99
103
|
if attempt == self.max_retries - 1:
|
|
100
104
|
# 达到最大重试次数,抛出异常
|
|
101
|
-
raise ValueError(
|
|
105
|
+
raise ValueError(
|
|
106
|
+
f"经过 {self.max_retries} 次尝试仍无法解析: {last_error}") from last_error
|
|
102
107
|
|
|
103
108
|
raise ValueError("未知错误")
|
|
104
109
|
|
|
105
110
|
async def ainvoke(self, input: Any, config: Optional[RunnableConfig] = None) -> BaseModel:
|
|
106
111
|
"""异步调用(带智能修正重试)"""
|
|
107
|
-
messages = input.get("messages", []) if isinstance(
|
|
112
|
+
messages = input.get("messages", []) if isinstance(
|
|
113
|
+
input, dict) else input
|
|
108
114
|
last_error = None
|
|
109
115
|
last_content = None
|
|
110
116
|
|
|
@@ -147,6 +153,7 @@ class SmartRetryRunnable(Runnable):
|
|
|
147
153
|
|
|
148
154
|
if attempt == self.max_retries - 1:
|
|
149
155
|
# 达到最大重试次数,抛出异常
|
|
150
|
-
raise ValueError(
|
|
156
|
+
raise ValueError(
|
|
157
|
+
f"经过 {self.max_retries} 次尝试仍无法解析: {last_error}") from last_error
|
|
151
158
|
|
|
152
159
|
raise ValueError("未知错误")
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/usage_token.py
RENAMED
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
LLM Token 统计和结构化输出模块
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from typing import Type, List, Optional, Callable
|
|
6
|
+
from typing import Type, List, Optional, Callable, Iterator, AsyncIterator
|
|
7
7
|
from langfuse import Langfuse
|
|
8
8
|
from langchain_core.language_models import BaseChatModel
|
|
9
9
|
from langchain_core.runnables import Runnable, RunnableLambda
|
|
10
10
|
from langchain_core.output_parsers import PydanticOutputParser
|
|
11
11
|
from langchain_core.messages import HumanMessage
|
|
12
12
|
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
13
|
+
from langchain_core.outputs import ChatGenerationChunk
|
|
13
14
|
from pydantic import BaseModel, ValidationError, Field
|
|
14
15
|
|
|
15
16
|
from sycommon.config.LLMConfig import LLMConfig
|
|
@@ -90,7 +91,8 @@ class LLMWithAutoTokenUsage(BaseChatModel):
|
|
|
90
91
|
上一次输出:
|
|
91
92
|
{previous_output}
|
|
92
93
|
|
|
93
|
-
|
|
94
|
+
输出格式,请严格按照以下JSON格式输出,不要输出任何多余内容,不要省略任何字段:
|
|
95
|
+
{format_instructions}
|
|
94
96
|
""")
|
|
95
97
|
])
|
|
96
98
|
|
|
@@ -145,14 +147,14 @@ class LLMWithAutoTokenUsage(BaseChatModel):
|
|
|
145
147
|
HumanMessage(content=f"""
|
|
146
148
|
请提取信息并遵循以下规则:
|
|
147
149
|
1. 准确率要求:{accuracy_instructions.strip()}
|
|
148
|
-
2.
|
|
150
|
+
2. 输出格式,请严格按照以下JSON格式输出,不要输出任何多余内容,不要省略任何字段:{parser.get_format_instructions()}
|
|
149
151
|
""")
|
|
150
152
|
])
|
|
151
153
|
else:
|
|
152
154
|
prompt = override_prompt or ChatPromptTemplate.from_messages([
|
|
153
155
|
MessagesPlaceholder(variable_name="messages"),
|
|
154
156
|
HumanMessage(content=f"""
|
|
155
|
-
|
|
157
|
+
输出格式,请严格按照以下JSON格式输出,不要输出任何多余内容,不要省略任何字段:{parser.get_format_instructions()}
|
|
156
158
|
""")
|
|
157
159
|
])
|
|
158
160
|
|
|
@@ -168,7 +170,7 @@ class LLMWithAutoTokenUsage(BaseChatModel):
|
|
|
168
170
|
上一次输出:
|
|
169
171
|
{previous_output}
|
|
170
172
|
|
|
171
|
-
|
|
173
|
+
输出格式,请严格按照以下JSON格式输出,不要输出任何多余内容,不要省略任何字段:
|
|
172
174
|
{format_instructions}
|
|
173
175
|
""")
|
|
174
176
|
])
|
|
@@ -229,6 +231,19 @@ class LLMWithAutoTokenUsage(BaseChatModel):
|
|
|
229
231
|
def _generate(self, messages, stop=None, run_manager=None, **kwargs):
|
|
230
232
|
return self.llm._generate(messages, stop=stop, run_manager=run_manager, **kwargs)
|
|
231
233
|
|
|
234
|
+
async def _agenerate(self, messages, stop=None, run_manager=None, **kwargs):
|
|
235
|
+
"""异步生成 - 委托给底层 LLM"""
|
|
236
|
+
return await self.llm._agenerate(messages, stop=stop, run_manager=run_manager, **kwargs)
|
|
237
|
+
|
|
238
|
+
def _stream(self, messages, stop=None, run_manager=None, **kwargs):
|
|
239
|
+
"""流式生成 - 委托给底层 LLM"""
|
|
240
|
+
yield from self.llm._stream(messages, stop=stop, run_manager=run_manager, **kwargs)
|
|
241
|
+
|
|
242
|
+
async def _astream(self, messages, stop=None, run_manager=None, **kwargs):
|
|
243
|
+
"""异步流式生成 - 委托给底层 LLM"""
|
|
244
|
+
async for chunk in self.llm._astream(messages, stop=stop, run_manager=run_manager, **kwargs):
|
|
245
|
+
yield chunk
|
|
246
|
+
|
|
232
247
|
@property
|
|
233
248
|
def _llm_type(self) -> str:
|
|
234
249
|
return self.llm._llm_type
|
|
@@ -65,9 +65,14 @@ class RabbitMQService(RabbitMQConnectionMonitor, RabbitMQProducerManager, Rabbit
|
|
|
65
65
|
优先级:
|
|
66
66
|
1. 环境变量 HEARTBEAT_PROCESS_MODE
|
|
67
67
|
2. 配置项 useProcessMode
|
|
68
|
+
3. 操作系统检测(Windows 默认禁用)
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
默认:
|
|
71
|
+
- Windows: 禁用进程模式(spawn 模式有限制)
|
|
72
|
+
- macOS/Linux: 启用进程模式
|
|
70
73
|
"""
|
|
74
|
+
import platform
|
|
75
|
+
|
|
71
76
|
env_mode = os.getenv('HEARTBEAT_PROCESS_MODE', '').lower()
|
|
72
77
|
if env_mode in ('false', '0', 'no'):
|
|
73
78
|
cls._use_process_mode = False
|
|
@@ -75,13 +80,21 @@ class RabbitMQService(RabbitMQConnectionMonitor, RabbitMQProducerManager, Rabbit
|
|
|
75
80
|
elif env_mode in ('true', '1', 'yes'):
|
|
76
81
|
cls._use_process_mode = True
|
|
77
82
|
else:
|
|
78
|
-
#
|
|
79
|
-
config_value = config.get('useProcessMode'
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
# 从配置读取
|
|
84
|
+
config_value = config.get('useProcessMode')
|
|
85
|
+
if config_value is not None:
|
|
86
|
+
# 处理字符串配置
|
|
87
|
+
if isinstance(config_value, str):
|
|
88
|
+
cls._use_process_mode = config_value.lower() not in ('false', '0', 'no')
|
|
89
|
+
else:
|
|
90
|
+
cls._use_process_mode = bool(config_value)
|
|
83
91
|
else:
|
|
84
|
-
|
|
92
|
+
# 默认:Windows 禁用进程模式,其他系统启用
|
|
93
|
+
if platform.system() == 'Windows':
|
|
94
|
+
cls._use_process_mode = False
|
|
95
|
+
logger.info("RabbitMQ: Windows 系统默认禁用进程模式,使用 asyncio 模式")
|
|
96
|
+
else:
|
|
97
|
+
cls._use_process_mode = True
|
|
85
98
|
|
|
86
99
|
if cls._use_process_mode:
|
|
87
100
|
logger.info("RabbitMQ: 启用进程模式,连接监控将在独立进程中运行")
|
|
@@ -116,9 +129,12 @@ class RabbitMQService(RabbitMQConnectionMonitor, RabbitMQProducerManager, Rabbit
|
|
|
116
129
|
|
|
117
130
|
# 环境变量明确启用
|
|
118
131
|
if env_enabled in ('true', '1', 'yes') or env_pool_size:
|
|
119
|
-
pool_size = int(
|
|
120
|
-
|
|
121
|
-
|
|
132
|
+
pool_size = int(
|
|
133
|
+
env_pool_size) if env_pool_size.isdigit() else 0
|
|
134
|
+
ProcessPoolConsumerManager.configure(
|
|
135
|
+
enabled=True, pool_size=pool_size)
|
|
136
|
+
logger.info(
|
|
137
|
+
f"RabbitMQ: 环境变量配置消费者进程池,大小: {ProcessPoolConsumerManager.get_pool_size()}")
|
|
122
138
|
return
|
|
123
139
|
|
|
124
140
|
# 从配置文件读取
|
|
@@ -133,12 +149,15 @@ class RabbitMQService(RabbitMQConnectionMonitor, RabbitMQProducerManager, Rabbit
|
|
|
133
149
|
pool_enabled = bool(config_enabled)
|
|
134
150
|
|
|
135
151
|
pool_size = int(config_pool_size) if config_pool_size else 0
|
|
136
|
-
ProcessPoolConsumerManager.configure(
|
|
152
|
+
ProcessPoolConsumerManager.configure(
|
|
153
|
+
enabled=pool_enabled, pool_size=pool_size)
|
|
137
154
|
logger.info(f"RabbitMQ: 配置文件设置消费者进程池,启用: {pool_enabled}")
|
|
138
155
|
else:
|
|
139
156
|
# 使用默认配置(禁用)
|
|
140
|
-
ProcessPoolConsumerManager.configure(
|
|
141
|
-
|
|
157
|
+
ProcessPoolConsumerManager.configure(
|
|
158
|
+
enabled=False, pool_size=0)
|
|
159
|
+
logger.info(
|
|
160
|
+
"RabbitMQ: 消费者进程池默认禁用,如需启用请设置 MQ_PROCESS_POOL_ENABLED=true")
|
|
142
161
|
|
|
143
162
|
except Exception as e:
|
|
144
163
|
logger.warning(f"RabbitMQ: 配置消费者进程池失败: {e},使用默认配置")
|
|
@@ -169,7 +188,8 @@ class RabbitMQService(RabbitMQConnectionMonitor, RabbitMQProducerManager, Rabbit
|
|
|
169
188
|
|
|
170
189
|
# 启动心跳进程(仅 RabbitMQ 监控)
|
|
171
190
|
HeartbeatProcessManager.enable_process_mode(True)
|
|
172
|
-
success = HeartbeatProcessManager.start(
|
|
191
|
+
success = HeartbeatProcessManager.start(
|
|
192
|
+
rabbitmq_config=rabbitmq_config)
|
|
173
193
|
|
|
174
194
|
if success:
|
|
175
195
|
cls._heartbeat_process_started = True
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/nacos_service.py
RENAMED
|
@@ -84,9 +84,14 @@ class NacosService(metaclass=SingletonMeta):
|
|
|
84
84
|
优先级:
|
|
85
85
|
1. 环境变量 HEARTBEAT_PROCESS_MODE
|
|
86
86
|
2. 配置项 useProcessMode
|
|
87
|
+
3. 操作系统检测(Windows 默认禁用)
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
默认:
|
|
90
|
+
- Windows: 禁用进程模式(spawn 模式有限制)
|
|
91
|
+
- macOS/Linux: 启用进程模式
|
|
89
92
|
"""
|
|
93
|
+
import platform
|
|
94
|
+
|
|
90
95
|
env_mode = os.getenv('HEARTBEAT_PROCESS_MODE', '').lower()
|
|
91
96
|
if env_mode in ('false', '0', 'no'):
|
|
92
97
|
self._use_process_mode = False
|
|
@@ -94,13 +99,21 @@ class NacosService(metaclass=SingletonMeta):
|
|
|
94
99
|
elif env_mode in ('true', '1', 'yes'):
|
|
95
100
|
self._use_process_mode = True
|
|
96
101
|
else:
|
|
97
|
-
#
|
|
98
|
-
config_value = self.nacos_config.get('useProcessMode'
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
+
# 从配置读取
|
|
103
|
+
config_value = self.nacos_config.get('useProcessMode')
|
|
104
|
+
if config_value is not None:
|
|
105
|
+
# 处理字符串配置
|
|
106
|
+
if isinstance(config_value, str):
|
|
107
|
+
self._use_process_mode = config_value.lower() not in ('false', '0', 'no')
|
|
108
|
+
else:
|
|
109
|
+
self._use_process_mode = bool(config_value)
|
|
102
110
|
else:
|
|
103
|
-
|
|
111
|
+
# 默认:Windows 禁用进程模式,其他系统启用
|
|
112
|
+
if platform.system() == 'Windows':
|
|
113
|
+
self._use_process_mode = False
|
|
114
|
+
SYLogger.info("nacos:Windows 系统默认禁用进程模式,使用线程模式")
|
|
115
|
+
else:
|
|
116
|
+
self._use_process_mode = True
|
|
104
117
|
|
|
105
118
|
if self._use_process_mode:
|
|
106
119
|
SYLogger.info("nacos:启用进程模式,心跳将在独立进程中运行")
|
|
@@ -231,17 +244,23 @@ class NacosService(metaclass=SingletonMeta):
|
|
|
231
244
|
return config_ip
|
|
232
245
|
|
|
233
246
|
def handle_signal(self, signum, frame):
|
|
234
|
-
"""处理退出信号(保持原有逻辑)
|
|
235
|
-
|
|
247
|
+
"""处理退出信号(保持原有逻辑)
|
|
248
|
+
|
|
249
|
+
注意:信号处理函数中不能使用 Loguru(会导致死锁),
|
|
250
|
+
使用 print 代替日志输出。
|
|
251
|
+
"""
|
|
252
|
+
# 信号处理函数中不能使用 Loguru,会导致死锁
|
|
253
|
+
print(f"[NacosService] 收到信号 {signum},正在关闭服务...")
|
|
236
254
|
|
|
237
255
|
# 停止心跳进程
|
|
238
256
|
if self._heartbeat_process_started:
|
|
239
257
|
try:
|
|
240
258
|
from sycommon.heartbeat_process import HeartbeatProcessManager
|
|
241
|
-
|
|
242
|
-
|
|
259
|
+
# 从信号处理函数中调用,使用 print 替代 logger 避免死锁
|
|
260
|
+
HeartbeatProcessManager.stop(from_signal_handler=True)
|
|
261
|
+
print("[NacosService] 心跳进程已停止")
|
|
243
262
|
except Exception as e:
|
|
244
|
-
|
|
263
|
+
print(f"[NacosService] 停止心跳进程异常: {e}")
|
|
245
264
|
|
|
246
265
|
self.registration.deregister_service()
|
|
247
266
|
sys.exit(0)
|
|
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.0b28 → sycommon_python_lib-0.2.0b30}/src/command/templates/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/templates/base/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/command/templates/web/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/get_agent.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/skills/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/skills/exports.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/agent/virtual_employee.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/DatabaseConfig.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/EmbeddingConfig.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/LLMConfig.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/LangfuseConfig.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/MQConfig.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/RedisConfig.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/RerankerConfig.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/SentryConfig.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/config/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/database/redis_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/health/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/health/health_check.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/health/metrics.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
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/llm_logger.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/llm_tokens.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/struct_token.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/llm/sy_langfuse.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/kafka_log.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/logger_levels.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/logger_wrapper.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/process_logger.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/logging/sql_logger.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/context.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/cors.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/docs.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/exception.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/timeout.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/middleware/traceid.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/base_http.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/mqmsg_model.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/mqsend_config.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/sso_user.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/models/token_usage.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/notice/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/notice/uvicorn_monitor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/rabbitmq/rabbitmq_pool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/sentry/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/sentry/sy_sentry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/example.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/example2.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/synacos/feign_client.py
RENAMED
|
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.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tests/test_email.py
RENAMED
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/__init__.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/async_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/merge_headers.py
RENAMED
|
File without changes
|
{sycommon_python_lib-0.2.0b28 → sycommon_python_lib-0.2.0b30}/src/sycommon/tools/snowflake.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
|