sycommon-python-lib 0.2.1b3__tar.gz → 0.2.1b4__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.1b3 → sycommon_python_lib-0.2.1b4}/PKG-INFO +3 -1
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/pyproject.toml +3 -1
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/file_ops.py +8 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/http_sandbox_backend.py +76 -28
- sycommon_python_lib-0.2.1b4/src/sycommon/config/XxlJobConfig.py +17 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/kafka_log.py +1 -1
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/sandbox.py +24 -5
- sycommon_python_lib-0.2.1b4/src/sycommon/models/xxljob_handler_config.py +11 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/services.py +21 -3
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_service.py +4 -2
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/env.py +2 -2
- sycommon_python_lib-0.2.1b4/src/sycommon/xxljob/__init__.py +3 -0
- sycommon_python_lib-0.2.1b4/src/sycommon/xxljob/xxljob_service.py +196 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/PKG-INFO +3 -1
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/SOURCES.txt +4 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/requires.txt +2 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/README.md +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/setup.cfg +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/console.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/models.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/project.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/utils.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/templates/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/templates/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/templates/base/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/templates/web/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/agent_manager.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/chat_events.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/deep_agent.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/multi_agent_team.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/session.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/auth/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/auth/ldap_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/ElasticsearchConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/LangfuseConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/RedisConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/SentryConfig.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/async_base_db_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/async_database_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/elasticsearch_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/redis_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/token_usage_db_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/heartbeat_process/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/embedding.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/get_llm.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/llm_logger.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/llm_tokens.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/llm_with_token_tracking.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/output_fixing_runnable.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/struct_token.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/sy_langfuse.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/token_usage_es_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/usage_token.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/async_sql_logger.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/logger_levels.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/process_logger.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/background_execution.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/context.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/traceid.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/sandbox.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/token_usage.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/token_usage_mysql.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/notice/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/notice/uvicorn_monitor.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sentry/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sentry/sy_sentry.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/feign.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/feign_client.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_client_base.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_config_manager.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_service_registration.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tests/deep_agent_server.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tests/test_deep_agent.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tests/test_email.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tests/test_mq.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/async_utils.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/merge_headers.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/snowflake.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/syemail.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sycommon-python-lib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1b4
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -19,11 +19,13 @@ Requires-Dist: langchain-core>=1.2.20
|
|
|
19
19
|
Requires-Dist: langchain-openai>=1.1.11
|
|
20
20
|
Requires-Dist: langfuse>=4.0.1
|
|
21
21
|
Requires-Dist: langgraph>=1.1.3
|
|
22
|
+
Requires-Dist: langgraph-checkpoint-redis>=0.4.0
|
|
22
23
|
Requires-Dist: ldap3>=2.9.1
|
|
23
24
|
Requires-Dist: loguru>=0.7.3
|
|
24
25
|
Requires-Dist: mysql-connector-python>=9.6.0
|
|
25
26
|
Requires-Dist: nacos-sdk-python<3.0,>=2.0.9
|
|
26
27
|
Requires-Dist: psutil>=7.2.2
|
|
28
|
+
Requires-Dist: pyxxl>=0.4.6
|
|
27
29
|
Requires-Dist: pydantic>=2.12.5
|
|
28
30
|
Requires-Dist: python-dotenv>=1.2.2
|
|
29
31
|
Requires-Dist: python-multipart>=0.0.22
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sycommon-python-lib"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.1b4"
|
|
4
4
|
description = "Add your description here"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -20,11 +20,13 @@ dependencies = [
|
|
|
20
20
|
"langchain-openai>=1.1.11",
|
|
21
21
|
"langfuse>=4.0.1",
|
|
22
22
|
"langgraph>=1.1.3",
|
|
23
|
+
"langgraph-checkpoint-redis>=0.4.0",
|
|
23
24
|
"ldap3>=2.9.1",
|
|
24
25
|
"loguru>=0.7.3",
|
|
25
26
|
"mysql-connector-python>=9.6.0",
|
|
26
27
|
"nacos-sdk-python>=2.0.9,<3.0",
|
|
27
28
|
"psutil>=7.2.2",
|
|
29
|
+
"pyxxl>=0.4.6",
|
|
28
30
|
"pydantic>=2.12.5",
|
|
29
31
|
"python-dotenv>=1.2.2",
|
|
30
32
|
"python-multipart>=0.0.22",
|
{sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/file_ops.py
RENAMED
|
@@ -140,15 +140,19 @@ class FileOperationsMixin:
|
|
|
140
140
|
"""列出目录内容"""
|
|
141
141
|
try:
|
|
142
142
|
self._ensure_synced_sync()
|
|
143
|
+
print(f"[Sandbox-DEBUG] ls() called with path={repr(path)}, user_id={repr(self.user_id)}", flush=True)
|
|
143
144
|
SYLogger.info(f"[Sandbox] 列出目录: {path}")
|
|
144
145
|
result = self._post_sync(f"{SANDBOX_API_PREFIX}/ls", {
|
|
145
146
|
"path": path,
|
|
146
147
|
"user_id": self.user_id
|
|
147
148
|
})
|
|
149
|
+
print(f"[Sandbox-DEBUG] ls() raw result type={type(result).__name__}, repr={repr(result)[:500]}", flush=True)
|
|
148
150
|
entries = [FileInfo(**item) for item in result]
|
|
151
|
+
print(f"[Sandbox-DEBUG] ls() parsed entries={len(entries)}", flush=True)
|
|
149
152
|
SYLogger.info(f"[Sandbox] 目录内容: {len(entries)} 项")
|
|
150
153
|
return LsResult(entries=entries)
|
|
151
154
|
except Exception as e:
|
|
155
|
+
print(f"[Sandbox-DEBUG] ls() EXCEPTION: {type(e).__name__}: {e}", flush=True)
|
|
152
156
|
SYLogger.error(f"[Sandbox] 列出目录失败: {e}")
|
|
153
157
|
return LsResult(error=str(e))
|
|
154
158
|
|
|
@@ -156,15 +160,19 @@ class FileOperationsMixin:
|
|
|
156
160
|
"""异步列出目录内容(真正的异步实现)"""
|
|
157
161
|
try:
|
|
158
162
|
await self._ensure_synced_async()
|
|
163
|
+
print(f"[Sandbox-DEBUG] als() called with path={repr(path)}, user_id={repr(self.user_id)}, base_url={repr(self._base_url if hasattr(self, '_base_url') else 'N/A')}", flush=True)
|
|
159
164
|
SYLogger.info(f"[Sandbox] 异步列出目录: {path}")
|
|
160
165
|
result = await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/ls", {
|
|
161
166
|
"path": path,
|
|
162
167
|
"user_id": self.user_id
|
|
163
168
|
})
|
|
169
|
+
print(f"[Sandbox-DEBUG] als() raw result type={type(result).__name__}, repr={repr(result)[:500]}", flush=True)
|
|
164
170
|
entries = [FileInfo(**item) for item in result]
|
|
171
|
+
print(f"[Sandbox-DEBUG] als() parsed entries={len(entries)}, first 3 paths={[e.get('path','?') if isinstance(e, dict) else getattr(e, 'path','?') for e in entries[:3]]}", flush=True)
|
|
165
172
|
SYLogger.info(f"[Sandbox] 目录内容: {len(entries)} 项")
|
|
166
173
|
return LsResult(entries=entries)
|
|
167
174
|
except Exception as e:
|
|
175
|
+
print(f"[Sandbox-DEBUG] als() EXCEPTION: {type(e).__name__}: {e}", flush=True)
|
|
168
176
|
SYLogger.error(f"[Sandbox] 异步列出目录失败: {e}")
|
|
169
177
|
return LsResult(error=str(e))
|
|
170
178
|
|
|
@@ -101,6 +101,7 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
|
|
|
101
101
|
self._sync_dirs = sync_dirs or []
|
|
102
102
|
self._auto_sync = auto_sync
|
|
103
103
|
self._synced = False
|
|
104
|
+
self._workspace_verified = False
|
|
104
105
|
|
|
105
106
|
# Nacos 配置(用于故障转移)
|
|
106
107
|
self._nacos_service_name = nacos_service_name
|
|
@@ -485,15 +486,22 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
|
|
|
485
486
|
return False
|
|
486
487
|
|
|
487
488
|
async def _sync_async(self) -> dict:
|
|
488
|
-
"""同步目录(异步版本)
|
|
489
|
+
"""同步目录(异步版本)
|
|
490
|
+
|
|
491
|
+
sync_dirs 条目支持两种格式:
|
|
492
|
+
(local_path, remote_path) -> 全量覆盖
|
|
493
|
+
(local_path, remote_path, mode) -> mode="full" 全量覆盖, mode="partial" 跳过已有子目录
|
|
494
|
+
"""
|
|
489
495
|
if not self._sync_dirs:
|
|
490
496
|
SYLogger.info("[Sandbox] 没有配置同步目录")
|
|
491
497
|
return {}
|
|
492
498
|
|
|
493
499
|
SYLogger.info(f"[Sandbox] _sync_async 开始, 共 {len(self._sync_dirs)} 个目录")
|
|
494
500
|
results = {}
|
|
495
|
-
for idx,
|
|
496
|
-
|
|
501
|
+
for idx, entry in enumerate(self._sync_dirs):
|
|
502
|
+
local_path, remote_path = entry[0], entry[1]
|
|
503
|
+
mode = entry[2] if len(entry) > 2 else "full"
|
|
504
|
+
SYLogger.info(f"[Sandbox] 同步目录 [{idx+1}/{len(self._sync_dirs)}]: {local_path} -> {remote_path} (mode={mode})")
|
|
497
505
|
local_dir = Path(local_path)
|
|
498
506
|
|
|
499
507
|
if not local_dir.exists():
|
|
@@ -503,7 +511,7 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
|
|
|
503
511
|
|
|
504
512
|
if local_dir.is_dir():
|
|
505
513
|
SYLogger.info(f"[Sandbox] 开始上传目录: {local_path}")
|
|
506
|
-
result = await self._upload_directory_async(str(local_dir), remote_path)
|
|
514
|
+
result = await self._upload_directory_async(str(local_dir), remote_path, mode=mode)
|
|
507
515
|
results[local_path] = result
|
|
508
516
|
SYLogger.info(f"[Sandbox] 目录上传完成: {local_path}, 成功={result['success']}, 失败={result['failed']}")
|
|
509
517
|
else:
|
|
@@ -520,8 +528,16 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
|
|
|
520
528
|
SYLogger.info("[Sandbox] _sync_async 完成")
|
|
521
529
|
return results
|
|
522
530
|
|
|
523
|
-
async def _upload_directory_async(self, local_dir: str, remote_path: str = "/") -> dict:
|
|
524
|
-
"""上传整个目录到沙箱(异步版本)
|
|
531
|
+
async def _upload_directory_async(self, local_dir: str, remote_path: str = "/", *, mode: str = "full") -> dict:
|
|
532
|
+
"""上传整个目录到沙箱(异步版本)
|
|
533
|
+
|
|
534
|
+
Args:
|
|
535
|
+
local_dir: 本地目录路径
|
|
536
|
+
remote_path: 沙箱目标路径
|
|
537
|
+
mode: 同步模式
|
|
538
|
+
- "full": 全量覆盖(默认),上传所有文件
|
|
539
|
+
- "partial": 部分覆盖,查询沙箱已有子目录并跳过同名目录
|
|
540
|
+
"""
|
|
525
541
|
local_path = Path(local_dir)
|
|
526
542
|
if not local_path.exists():
|
|
527
543
|
raise FileNotFoundError(f"本地目录不存在: {local_dir}")
|
|
@@ -529,7 +545,24 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
|
|
|
529
545
|
if not local_path.is_dir():
|
|
530
546
|
raise NotADirectoryError(f"路径不是目录: {local_dir}")
|
|
531
547
|
|
|
532
|
-
SYLogger.info(f"[Sandbox] _upload_directory_async 开始: {local_dir} -> {remote_path}")
|
|
548
|
+
SYLogger.info(f"[Sandbox] _upload_directory_async 开始: {local_dir} -> {remote_path} (mode={mode})")
|
|
549
|
+
|
|
550
|
+
# partial 模式:查询沙箱已有子目录并跳过
|
|
551
|
+
existing_subdirs = set()
|
|
552
|
+
if mode == "partial":
|
|
553
|
+
try:
|
|
554
|
+
ls_result = await self._post_async(f"{SANDBOX_API_PREFIX}/ls", {
|
|
555
|
+
"path": remote_path,
|
|
556
|
+
"user_id": self._user_id
|
|
557
|
+
})
|
|
558
|
+
if ls_result and not ls_result.get("error"):
|
|
559
|
+
for item in ls_result.get("files", ls_result.get("children", [])):
|
|
560
|
+
if item.get("is_dir", False):
|
|
561
|
+
existing_subdirs.add(item.get("name", ""))
|
|
562
|
+
if existing_subdirs:
|
|
563
|
+
SYLogger.info(f"[Sandbox] partial 模式,跳过已有子目录: {existing_subdirs}")
|
|
564
|
+
except Exception as e:
|
|
565
|
+
SYLogger.warning(f"[Sandbox] 查询沙箱目录失败,将全量同步: {e}")
|
|
533
566
|
|
|
534
567
|
exclude_patterns = [".git", "__pycache__", ".pyc", ".DS_Store", "node_modules"]
|
|
535
568
|
|
|
@@ -547,6 +580,19 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
|
|
|
547
580
|
for root, dirs, files in os.walk(local_path):
|
|
548
581
|
dirs[:] = [d for d in dirs if not should_exclude(d)]
|
|
549
582
|
|
|
583
|
+
# 对于 /skills 目录,跳过沙箱中已存在的子目录(只检查最外层)
|
|
584
|
+
if existing_subdirs:
|
|
585
|
+
try:
|
|
586
|
+
rel = Path(root).relative_to(local_path)
|
|
587
|
+
if str(rel) == ".":
|
|
588
|
+
before = len(dirs)
|
|
589
|
+
skipped_names = [d for d in dirs if d in existing_subdirs]
|
|
590
|
+
dirs[:] = [d for d in dirs if d not in existing_subdirs]
|
|
591
|
+
if skipped_names:
|
|
592
|
+
SYLogger.info(f"[Sandbox] 跳过已有技能目录: {skipped_names}")
|
|
593
|
+
except ValueError:
|
|
594
|
+
pass
|
|
595
|
+
|
|
550
596
|
for file in files:
|
|
551
597
|
if should_exclude(file):
|
|
552
598
|
continue
|
|
@@ -558,32 +604,34 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
|
|
|
558
604
|
|
|
559
605
|
SYLogger.info(f"[Sandbox] 准备上传 {len(files_to_upload)} 个文件到沙箱")
|
|
560
606
|
|
|
561
|
-
|
|
562
|
-
failed_count = 0
|
|
563
|
-
errors = []
|
|
607
|
+
semaphore = asyncio.Semaphore(10)
|
|
564
608
|
|
|
565
|
-
|
|
566
|
-
|
|
609
|
+
async def _upload_one(idx, sandbox_path, local_file):
|
|
610
|
+
async with semaphore:
|
|
567
611
|
if idx % 10 == 0:
|
|
568
612
|
SYLogger.info(f"[Sandbox] 上传进度: {idx}/{len(files_to_upload)}")
|
|
613
|
+
try:
|
|
614
|
+
content = await asyncio.to_thread(lambda f=local_file: open(f, "rb").read())
|
|
615
|
+
result = await self._post_async(f"{SANDBOX_API_PREFIX}/upload", {
|
|
616
|
+
"path": sandbox_path,
|
|
617
|
+
"content": base64.b64encode(content).decode(),
|
|
618
|
+
"user_id": self._user_id
|
|
619
|
+
})
|
|
620
|
+
if result.get("error"):
|
|
621
|
+
return {"ok": False, "path": sandbox_path, "error": result["error"]}
|
|
622
|
+
return {"ok": True}
|
|
623
|
+
except Exception as e:
|
|
624
|
+
return {"ok": False, "path": sandbox_path, "error": str(e)}
|
|
569
625
|
|
|
570
|
-
|
|
626
|
+
upload_tasks = [
|
|
627
|
+
_upload_one(idx, sandbox_path, local_file)
|
|
628
|
+
for idx, (sandbox_path, local_file) in enumerate(files_to_upload)
|
|
629
|
+
]
|
|
630
|
+
upload_results = await asyncio.gather(*upload_tasks)
|
|
571
631
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
"user_id": self._user_id
|
|
576
|
-
})
|
|
577
|
-
|
|
578
|
-
if result.get("error"):
|
|
579
|
-
failed_count += 1
|
|
580
|
-
errors.append({"path": sandbox_path, "error": result["error"]})
|
|
581
|
-
else:
|
|
582
|
-
success_count += 1
|
|
583
|
-
|
|
584
|
-
except Exception as e:
|
|
585
|
-
failed_count += 1
|
|
586
|
-
errors.append({"path": sandbox_path, "error": str(e)})
|
|
632
|
+
success_count = sum(1 for r in upload_results if r["ok"])
|
|
633
|
+
failed_count = sum(1 for r in upload_results if not r["ok"])
|
|
634
|
+
errors = [{"path": r["path"], "error": r["error"]} for r in upload_results if not r["ok"]]
|
|
587
635
|
|
|
588
636
|
SYLogger.info(f"[Sandbox] _upload_directory_async 完成: 成功={success_count}, 失败={failed_count}")
|
|
589
637
|
return {"success": success_count, "failed": failed_count, "errors": errors}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class XxlJobDstcConfig(BaseModel):
|
|
5
|
+
"""XXL-JOB 调度中心地址配置"""
|
|
6
|
+
address: str
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class XxlJobExecutorConfig(BaseModel):
|
|
10
|
+
"""XXL-JOB 执行器配置"""
|
|
11
|
+
appname: str
|
|
12
|
+
dstc: XxlJobDstcConfig
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class XxlJobConfig(BaseModel):
|
|
16
|
+
"""XXL-JOB 配置模型,对应 Nacos 共享配置中的 task 节点"""
|
|
17
|
+
executor: XxlJobExecutorConfig
|
{sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/sandbox.py
RENAMED
|
@@ -619,14 +619,18 @@ COMMAND_EOF
|
|
|
619
619
|
async def ls_info(req: LsRequest):
|
|
620
620
|
"""列出目录内容"""
|
|
621
621
|
workspace = get_user_workspace(req.user_id)
|
|
622
|
+
print(f"[Sandbox-Server-DEBUG] /ls called: path={repr(req.path)}, user_id={repr(req.user_id)}, workspace={repr(workspace)}", flush=True)
|
|
622
623
|
try:
|
|
623
624
|
target_path = resolve_sandbox_path(req.path, workspace)
|
|
625
|
+
print(f"[Sandbox-Server-DEBUG] resolved target_path={repr(target_path)}", flush=True)
|
|
624
626
|
except ValueError as e:
|
|
625
627
|
SYLogger.error(f"[Sandbox Server] 列目录失败: {e}")
|
|
628
|
+
print(f"[Sandbox-Server-DEBUG] resolve_sandbox_path FAILED: {e}", flush=True)
|
|
626
629
|
return []
|
|
627
630
|
|
|
628
631
|
if not os.path.isdir(target_path):
|
|
629
632
|
SYLogger.error(f"[Sandbox Server] 列目录失败: 目录不存在 {target_path}")
|
|
633
|
+
print(f"[Sandbox-Server-DEBUG] target_path is NOT a dir: {target_path}", flush=True)
|
|
630
634
|
return []
|
|
631
635
|
|
|
632
636
|
SYLogger.info(f"[Sandbox Server] 列出目录: {target_path}")
|
|
@@ -634,7 +638,11 @@ COMMAND_EOF
|
|
|
634
638
|
try:
|
|
635
639
|
with os.scandir(target_path) as it:
|
|
636
640
|
for entry in it:
|
|
637
|
-
|
|
641
|
+
# 返回虚拟路径(相对于用户工作空间),而不是绝对文件系统路径
|
|
642
|
+
# 这样 AI 后续操作(ls、read_file 等)能正确解析路径
|
|
643
|
+
abs_path = os.path.join(target_path, entry.name)
|
|
644
|
+
virtual_path = "/" + os.path.relpath(abs_path, workspace)
|
|
645
|
+
info = FileInfo(path=virtual_path)
|
|
638
646
|
try:
|
|
639
647
|
info.is_dir = entry.is_dir(follow_symlinks=False)
|
|
640
648
|
if not info.is_dir:
|
|
@@ -646,6 +654,7 @@ COMMAND_EOF
|
|
|
646
654
|
except Exception as e:
|
|
647
655
|
SYLogger.error(f"[Sandbox Server] 列目录异常: {e}")
|
|
648
656
|
|
|
657
|
+
print(f"[Sandbox-Server-DEBUG] returning {len(results)} entries: {[r.path for r in results[:10]]}", flush=True)
|
|
649
658
|
SYLogger.info(f"[Sandbox Server] 目录内容: {len(results)} 项")
|
|
650
659
|
return results
|
|
651
660
|
|
|
@@ -849,7 +858,9 @@ COMMAND_EOF
|
|
|
849
858
|
|
|
850
859
|
results = []
|
|
851
860
|
for m in matches:
|
|
852
|
-
|
|
861
|
+
# 返回虚拟路径,与 ls 保持一致
|
|
862
|
+
virtual_path = "/" + os.path.relpath(m, workspace)
|
|
863
|
+
info = FileInfo(path=virtual_path)
|
|
853
864
|
try:
|
|
854
865
|
info.is_dir = os.path.isdir(m)
|
|
855
866
|
if not info.is_dir:
|
|
@@ -903,6 +914,11 @@ COMMAND_EOF
|
|
|
903
914
|
continue
|
|
904
915
|
|
|
905
916
|
path_part = line[:first_colon]
|
|
917
|
+
# 将绝对路径转换为虚拟路径
|
|
918
|
+
try:
|
|
919
|
+
virtual_path_part = "/" + os.path.relpath(path_part, workspace)
|
|
920
|
+
except ValueError:
|
|
921
|
+
virtual_path_part = path_part
|
|
906
922
|
try:
|
|
907
923
|
line_num = int(line[first_colon + 1:second_colon])
|
|
908
924
|
except ValueError:
|
|
@@ -910,7 +926,7 @@ COMMAND_EOF
|
|
|
910
926
|
text_part = line[second_colon + 1:]
|
|
911
927
|
|
|
912
928
|
matches.append(GrepMatch(
|
|
913
|
-
path=
|
|
929
|
+
path=virtual_path_part,
|
|
914
930
|
line=line_num,
|
|
915
931
|
text=text_part
|
|
916
932
|
))
|
|
@@ -941,7 +957,9 @@ COMMAND_EOF
|
|
|
941
957
|
try:
|
|
942
958
|
for item in os.listdir(target_path):
|
|
943
959
|
item_path = os.path.join(target_path, item)
|
|
944
|
-
|
|
960
|
+
# 返回虚拟路径
|
|
961
|
+
virtual_path = "/" + os.path.relpath(item_path, workspace)
|
|
962
|
+
info = FileInfo(path=virtual_path)
|
|
945
963
|
try:
|
|
946
964
|
info.is_dir = os.path.isdir(item_path)
|
|
947
965
|
if not info.is_dir:
|
|
@@ -971,7 +989,8 @@ COMMAND_EOF
|
|
|
971
989
|
return LsResponse(files=files, warning=f"Results truncated at {MAX_FILES} files")
|
|
972
990
|
|
|
973
991
|
filepath = os.path.join(root, filename)
|
|
974
|
-
|
|
992
|
+
virtual_filepath = "/" + os.path.relpath(filepath, workspace)
|
|
993
|
+
file_info = FileInfo(path=virtual_filepath)
|
|
975
994
|
try:
|
|
976
995
|
file_info.is_dir = False
|
|
977
996
|
file_info.size = os.path.getsize(filepath)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Callable, Coroutine
|
|
2
|
+
from pydantic import BaseModel, Field
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class XxlJobHandlerConfig(BaseModel):
|
|
6
|
+
"""XXL-JOB 任务处理器配置模型"""
|
|
7
|
+
name: str = Field(..., description="任务处理器名称")
|
|
8
|
+
handler: Callable[..., Coroutine] = Field(..., description="异步任务处理函数")
|
|
9
|
+
|
|
10
|
+
class Config:
|
|
11
|
+
arbitrary_types_allowed = True
|
|
@@ -10,6 +10,7 @@ from sycommon.config.Config import SingletonMeta
|
|
|
10
10
|
from sycommon.logging.logger_levels import setup_logger_levels
|
|
11
11
|
from sycommon.models.mqlistener_config import RabbitMQListenerConfig
|
|
12
12
|
from sycommon.models.mqsend_config import RabbitMQSendConfig
|
|
13
|
+
from sycommon.models.xxljob_handler_config import XxlJobHandlerConfig
|
|
13
14
|
from sycommon.rabbitmq.rabbitmq_service import RabbitMQService
|
|
14
15
|
from sycommon.tools.docs import custom_redoc_html, custom_swagger_ui_html
|
|
15
16
|
from sycommon.sentry.sy_sentry import sy_sentry_init
|
|
@@ -18,6 +19,7 @@ from sycommon.synacos.feign import close_all_feign_sessions
|
|
|
18
19
|
from sycommon.synacos.feign_client import close_all_feign_client_sessions
|
|
19
20
|
from sycommon.database.elasticsearch_service import ElasticsearchService
|
|
20
21
|
from sycommon.database.redis_service import RedisService
|
|
22
|
+
from sycommon.xxljob.xxljob_service import XxlJobService
|
|
21
23
|
|
|
22
24
|
# 延迟导入的类型(避免循环导入)
|
|
23
25
|
AgentConfig = Any # type: ignore[misc]
|
|
@@ -27,8 +29,10 @@ TeamConfig = Any # type: ignore[misc]
|
|
|
27
29
|
# - bool: True 启用默认配置,False 不启用
|
|
28
30
|
# - dict: 使用字典配置
|
|
29
31
|
# - AgentConfig/TeamConfig 对象: 使用配置对象
|
|
30
|
-
AgentServiceConfig = Union[bool, Dict[str, Any],
|
|
31
|
-
|
|
32
|
+
AgentServiceConfig = Union[bool, Dict[str, Any],
|
|
33
|
+
"AgentConfig"] # type: ignore[misc]
|
|
34
|
+
TeamServiceConfig = Union[bool, Dict[str, Any],
|
|
35
|
+
"TeamConfig"] # type: ignore[misc]
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
class Services(metaclass=SingletonMeta):
|
|
@@ -90,6 +94,7 @@ class Services(metaclass=SingletonMeta):
|
|
|
90
94
|
_enable_es: bool = True
|
|
91
95
|
_enable_redis: bool = True
|
|
92
96
|
_enable_sandbox: bool = False
|
|
97
|
+
_enable_xxljob: bool = False
|
|
93
98
|
|
|
94
99
|
def __init__(self, config: dict, app: FastAPI):
|
|
95
100
|
super().__init__()
|
|
@@ -135,6 +140,7 @@ class Services(metaclass=SingletonMeta):
|
|
|
135
140
|
sandbox_service: bool = False,
|
|
136
141
|
deep_agent_service: bool = False,
|
|
137
142
|
multi_agent_service: bool = False,
|
|
143
|
+
xxljob_service: Optional[List[XxlJobHandlerConfig]] = None,
|
|
138
144
|
) -> FastAPI:
|
|
139
145
|
load_dotenv()
|
|
140
146
|
setup_logger_levels()
|
|
@@ -166,6 +172,7 @@ class Services(metaclass=SingletonMeta):
|
|
|
166
172
|
cls._enable_es = elasticsearch_service is not None
|
|
167
173
|
cls._enable_redis = redis_service is not None
|
|
168
174
|
cls._enable_sandbox = sandbox_service or deep_agent_service or multi_agent_service
|
|
175
|
+
cls._enable_xxljob = xxljob_service is not None
|
|
169
176
|
|
|
170
177
|
# 将服务开关写入 config,供 middleware 和其他组件使用
|
|
171
178
|
if cls._config:
|
|
@@ -196,6 +203,10 @@ class Services(metaclass=SingletonMeta):
|
|
|
196
203
|
if redis_service:
|
|
197
204
|
redis_service()
|
|
198
205
|
|
|
206
|
+
# 初始化 XXL-JOB 执行器服务
|
|
207
|
+
if xxljob_service:
|
|
208
|
+
XxlJobService.setup(cls._config, xxljob_service)
|
|
209
|
+
|
|
199
210
|
@asynccontextmanager
|
|
200
211
|
async def combined_lifespan(app_instance: FastAPI) -> AsyncGenerator[None, None]:
|
|
201
212
|
# 获取 Services 实例
|
|
@@ -256,7 +267,7 @@ class Services(metaclass=SingletonMeta):
|
|
|
256
267
|
|
|
257
268
|
app_instance.state.services = instance
|
|
258
269
|
|
|
259
|
-
#
|
|
270
|
+
# 5. 执行用户定义的生命周期
|
|
260
271
|
if cls._user_lifespan:
|
|
261
272
|
async with cls._user_lifespan(app_instance):
|
|
262
273
|
yield
|
|
@@ -414,6 +425,13 @@ class Services(metaclass=SingletonMeta):
|
|
|
414
425
|
except Exception as e:
|
|
415
426
|
logging.debug(f"关闭 RedisService 时发生异常: {e}")
|
|
416
427
|
|
|
428
|
+
# 关闭 XXL-JOB 执行器(仅当启用时)
|
|
429
|
+
if cls._enable_xxljob:
|
|
430
|
+
try:
|
|
431
|
+
XxlJobService.shutdown()
|
|
432
|
+
except Exception as e:
|
|
433
|
+
logging.debug(f"关闭 XxlJobService 时发生异常: {e}")
|
|
434
|
+
|
|
417
435
|
cls._initialized = False
|
|
418
436
|
|
|
419
437
|
# 清理实例数据
|
{sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_service.py
RENAMED
|
@@ -20,6 +20,7 @@ class NacosService(metaclass=SingletonMeta):
|
|
|
20
20
|
# 进程模式标记
|
|
21
21
|
_use_process_mode: bool = False
|
|
22
22
|
_heartbeat_process_started: bool = False
|
|
23
|
+
|
|
23
24
|
def __init__(self, config):
|
|
24
25
|
if config:
|
|
25
26
|
self.config = config
|
|
@@ -29,7 +30,7 @@ class NacosService(metaclass=SingletonMeta):
|
|
|
29
30
|
self.port = config['Port']
|
|
30
31
|
self.version = get_env_var('VERSION')
|
|
31
32
|
self.enable_register_nacos = check_env_flag(
|
|
32
|
-
['
|
|
33
|
+
['REGISTER_NACOS'], 'true')
|
|
33
34
|
|
|
34
35
|
# 检查是否启用进程模式
|
|
35
36
|
self._check_process_mode()
|
|
@@ -200,7 +201,8 @@ class NacosService(metaclass=SingletonMeta):
|
|
|
200
201
|
port=self.port,
|
|
201
202
|
version=self.version,
|
|
202
203
|
heartbeat_interval=self.heartbeat_interval,
|
|
203
|
-
heartbeat_timeout=self.nacos_config.get(
|
|
204
|
+
heartbeat_timeout=self.nacos_config.get(
|
|
205
|
+
'heartbeatTimeout', 15),
|
|
204
206
|
username=self.nacos_config.get('username'),
|
|
205
207
|
password=self.nacos_config.get('password')
|
|
206
208
|
)
|
|
@@ -15,7 +15,7 @@ def _normalize_env_key(key: str) -> str:
|
|
|
15
15
|
def check_env_flag(target_keys: list, default: str = 'false') -> bool:
|
|
16
16
|
"""
|
|
17
17
|
检查环境变量是否为"true"(自动兼容:大小写、中划线/下划线)
|
|
18
|
-
:param target_keys: 目标变量名列表(如 ['
|
|
18
|
+
:param target_keys: 目标变量名列表(如 ['REGISTER_NACOS'],无需传双key)
|
|
19
19
|
:param default: 默认值(未找到变量时使用)
|
|
20
20
|
:return: 布尔值
|
|
21
21
|
"""
|
|
@@ -36,7 +36,7 @@ def check_env_flag(target_keys: list, default: str = 'false') -> bool:
|
|
|
36
36
|
def get_env_var(key: str, default='', case_insensitive: bool = True) -> str:
|
|
37
37
|
"""
|
|
38
38
|
获取环境变量值(自动兼容:大小写、中划线/下划线)
|
|
39
|
-
:param key: 目标环境变量名(如 '
|
|
39
|
+
:param key: 目标环境变量名(如 'REGISTER_NACOS'/'version')
|
|
40
40
|
:param default: 无匹配时的默认值,默认空字符串
|
|
41
41
|
:param case_insensitive: 是否忽略变量名大小写(默认True,建议保持)
|
|
42
42
|
:return: 匹配到的环境变量值 / 默认值
|