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.
Files changed (148) hide show
  1. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/PKG-INFO +3 -1
  2. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/pyproject.toml +3 -1
  3. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/file_ops.py +8 -0
  4. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/http_sandbox_backend.py +76 -28
  5. sycommon_python_lib-0.2.1b4/src/sycommon/config/XxlJobConfig.py +17 -0
  6. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/kafka_log.py +1 -1
  7. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/sandbox.py +24 -5
  8. sycommon_python_lib-0.2.1b4/src/sycommon/models/xxljob_handler_config.py +11 -0
  9. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/services.py +21 -3
  10. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_service.py +4 -2
  11. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/env.py +2 -2
  12. sycommon_python_lib-0.2.1b4/src/sycommon/xxljob/__init__.py +3 -0
  13. sycommon_python_lib-0.2.1b4/src/sycommon/xxljob/xxljob_service.py +196 -0
  14. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/PKG-INFO +3 -1
  15. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/SOURCES.txt +4 -0
  16. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/requires.txt +2 -0
  17. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/README.md +0 -0
  18. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/setup.cfg +0 -0
  19. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/__init__.py +0 -0
  20. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/cli.py +0 -0
  21. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/__init__.py +0 -0
  22. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/console.py +0 -0
  23. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/models.py +0 -0
  24. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/project.py +0 -0
  25. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/core/utils.py +0 -0
  26. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/templates/__init__.py +0 -0
  27. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/templates/agent/__init__.py +0 -0
  28. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/templates/base/__init__.py +0 -0
  29. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/command/templates/web/__init__.py +0 -0
  30. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/__init__.py +0 -0
  31. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/__init__.py +0 -0
  32. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/agent_manager.py +0 -0
  33. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/chat_events.py +0 -0
  34. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/deep_agent.py +0 -0
  35. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/multi_agent_team.py +0 -0
  36. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/__init__.py +0 -0
  37. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
  38. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
  39. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/agent/sandbox/session.py +0 -0
  40. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/auth/__init__.py +0 -0
  41. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/auth/ldap_service.py +0 -0
  42. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/Config.py +0 -0
  43. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/DatabaseConfig.py +0 -0
  44. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/ElasticsearchConfig.py +0 -0
  45. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/EmbeddingConfig.py +0 -0
  46. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/LLMConfig.py +0 -0
  47. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/LangfuseConfig.py +0 -0
  48. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/MQConfig.py +0 -0
  49. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/RedisConfig.py +0 -0
  50. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/RerankerConfig.py +0 -0
  51. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/SentryConfig.py +0 -0
  52. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/config/__init__.py +0 -0
  53. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/async_base_db_service.py +0 -0
  54. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/async_database_service.py +0 -0
  55. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/base_db_service.py +0 -0
  56. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/database_service.py +0 -0
  57. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/elasticsearch_service.py +0 -0
  58. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/redis_service.py +0 -0
  59. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/database/token_usage_db_service.py +0 -0
  60. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/health/__init__.py +0 -0
  61. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/health/health_check.py +0 -0
  62. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/health/metrics.py +0 -0
  63. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/health/ping.py +0 -0
  64. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/heartbeat_process/__init__.py +0 -0
  65. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
  66. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
  67. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
  68. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/__init__.py +0 -0
  69. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/embedding.py +0 -0
  70. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/get_llm.py +0 -0
  71. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/llm_logger.py +0 -0
  72. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/llm_tokens.py +0 -0
  73. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/llm_with_token_tracking.py +0 -0
  74. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
  75. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/output_fixing_runnable.py +0 -0
  76. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/struct_token.py +0 -0
  77. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/sy_langfuse.py +0 -0
  78. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/token_usage_es_service.py +0 -0
  79. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
  80. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/llm/usage_token.py +0 -0
  81. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/__init__.py +0 -0
  82. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/async_sql_logger.py +0 -0
  83. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/logger_levels.py +0 -0
  84. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/logger_wrapper.py +0 -0
  85. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/process_logger.py +0 -0
  86. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/logging/sql_logger.py +0 -0
  87. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/__init__.py +0 -0
  88. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/background_execution.py +0 -0
  89. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/context.py +0 -0
  90. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/cors.py +0 -0
  91. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/docs.py +0 -0
  92. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/exception.py +0 -0
  93. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/middleware.py +0 -0
  94. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/monitor_memory.py +0 -0
  95. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/mq.py +0 -0
  96. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/timeout.py +0 -0
  97. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/middleware/traceid.py +0 -0
  98. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/__init__.py +0 -0
  99. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/base_http.py +0 -0
  100. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/log.py +0 -0
  101. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/mqlistener_config.py +0 -0
  102. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/mqmsg_model.py +0 -0
  103. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/mqsend_config.py +0 -0
  104. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/sandbox.py +0 -0
  105. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/sso_user.py +0 -0
  106. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/token_usage.py +0 -0
  107. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/models/token_usage_mysql.py +0 -0
  108. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/notice/__init__.py +0 -0
  109. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/notice/uvicorn_monitor.py +0 -0
  110. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
  111. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
  112. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
  113. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
  114. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
  115. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
  116. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
  117. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
  118. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
  119. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sentry/__init__.py +0 -0
  120. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sentry/sy_sentry.py +0 -0
  121. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sse/__init__.py +0 -0
  122. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sse/event.py +0 -0
  123. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/sse/sse.py +0 -0
  124. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/__init__.py +0 -0
  125. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/example.py +0 -0
  126. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/example2.py +0 -0
  127. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/feign.py +0 -0
  128. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/feign_client.py +0 -0
  129. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_client_base.py +0 -0
  130. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_config_manager.py +0 -0
  131. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
  132. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
  133. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/nacos_service_registration.py +0 -0
  134. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/synacos/param.py +0 -0
  135. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tests/deep_agent_server.py +0 -0
  136. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tests/test_deep_agent.py +0 -0
  137. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tests/test_email.py +0 -0
  138. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tests/test_mq.py +0 -0
  139. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/__init__.py +0 -0
  140. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/async_utils.py +0 -0
  141. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/docs.py +0 -0
  142. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/merge_headers.py +0 -0
  143. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/snowflake.py +0 -0
  144. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/syemail.py +0 -0
  145. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon/tools/timing.py +0 -0
  146. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
  147. {sycommon_python_lib-0.2.1b3 → sycommon_python_lib-0.2.1b4}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
  148. {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.1b3
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.1b3"
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",
@@ -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, (local_path, remote_path) in enumerate(self._sync_dirs):
496
- SYLogger.info(f"[Sandbox] 同步目录 [{idx+1}/{len(self._sync_dirs)}]: {local_path} -> {remote_path}")
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
- success_count = 0
562
- failed_count = 0
563
- errors = []
607
+ semaphore = asyncio.Semaphore(10)
564
608
 
565
- for idx, (sandbox_path, local_file) in enumerate(files_to_upload):
566
- try:
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
- content = await asyncio.to_thread(lambda f=local_file: open(f, "rb").read())
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
- result = await self._post_async(f"{SANDBOX_API_PREFIX}/upload", {
573
- "path": sandbox_path,
574
- "content": base64.b64encode(content).decode(),
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
@@ -287,7 +287,7 @@ class SYLogger:
287
287
  else:
288
288
  logger.info(log_json)
289
289
 
290
- if check_env_flag(['DEV-LOG']):
290
+ if check_env_flag(['DEV_LOG']):
291
291
  print(log_json)
292
292
 
293
293
  @staticmethod
@@ -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
- info = FileInfo(path=os.path.join(target_path, entry.name))
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
- info = FileInfo(path=m)
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=path_part,
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
- info = FileInfo(path=item_path)
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
- file_info = FileInfo(path=filepath)
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], "AgentConfig"] # type: ignore[misc]
31
- TeamServiceConfig = Union[bool, Dict[str, Any], "TeamConfig"] # type: ignore[misc]
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
- # 4. 执行用户定义的生命周期
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
  # 清理实例数据
@@ -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
- ['REGISTER-NACOS'], 'true')
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('heartbeatTimeout', 15),
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: 目标变量名列表(如 ['REGISTER-NACOS'],无需传双key)
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: 目标环境变量名(如 'REGISTER-NACOS'/'version')
39
+ :param key: 目标环境变量名(如 'REGISTER_NACOS'/'version')
40
40
  :param default: 无匹配时的默认值,默认空字符串
41
41
  :param case_insensitive: 是否忽略变量名大小写(默认True,建议保持)
42
42
  :return: 匹配到的环境变量值 / 默认值
@@ -0,0 +1,3 @@
1
+ from sycommon.xxljob.xxljob_service import XxlJobService
2
+
3
+ __all__ = ['XxlJobService']