sycommon-python-lib 0.2.1a36__tar.gz → 0.2.1a38__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.1a36 → sycommon_python_lib-0.2.1a38}/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/pyproject.toml +1 -1
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/sandbox/file_ops.py +156 -13
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/sandbox/http_sandbox_backend.py +296 -53
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/README.md +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/setup.cfg +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/core/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/core/console.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/core/models.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/core/project.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/core/utils.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/templates/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/templates/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/templates/base/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/command/templates/web/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/agent_manager.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/chat_events.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/deep_agent.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/multi_agent_team.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/sandbox/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/sandbox/session.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/auth/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/auth/ldap_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/ElasticsearchConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/LangfuseConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/RedisConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/SentryConfig.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/database/async_base_db_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/database/async_database_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/database/elasticsearch_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/database/redis_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/database/token_usage_db_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/heartbeat_process/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/embedding.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/get_llm.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/llm_logger.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/llm_tokens.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/llm_with_token_tracking.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/output_fixing_runnable.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/struct_token.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/sy_langfuse.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/token_usage_es_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/llm/usage_token.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/logging/async_sql_logger.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/logging/kafka_log.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/logging/logger_levels.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/logging/process_logger.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/background_execution.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/context.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/sandbox.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/middleware/traceid.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/sandbox.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/token_usage.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/models/token_usage_mysql.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/notice/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/notice/uvicorn_monitor.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/sentry/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/sentry/sy_sentry.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/services.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/feign.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/feign_client.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/nacos_client_base.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/nacos_config_manager.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/nacos_service.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/nacos_service_registration.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tests/deep_agent_server.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tests/test_deep_agent.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tests/test_email.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tests/test_mq.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tools/async_utils.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tools/env.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tools/merge_headers.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tools/snowflake.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tools/syemail.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon_python_lib.egg-info/SOURCES.txt +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
- {sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
{sycommon_python_lib-0.2.1a36 → sycommon_python_lib-0.2.1a38}/src/sycommon/agent/sandbox/file_ops.py
RENAMED
|
@@ -33,7 +33,7 @@ class FileOperationsMixin:
|
|
|
33
33
|
"""文件操作 Mixin
|
|
34
34
|
|
|
35
35
|
适配 deepagents 0.5.0a2 协议
|
|
36
|
-
|
|
36
|
+
同步方法为主实现,异步方法使用 aiohttp 实现
|
|
37
37
|
"""
|
|
38
38
|
|
|
39
39
|
_timeout: int # 类型提示,子类需要提供此属性
|
|
@@ -46,6 +46,10 @@ class FileOperationsMixin:
|
|
|
46
46
|
"""发送同步 POST 请求"""
|
|
47
47
|
...
|
|
48
48
|
|
|
49
|
+
async def _post_async_with_failover(self: "HTTPSandboxBackend", endpoint: str, data: dict, timeout: int = None) -> dict:
|
|
50
|
+
"""发送异步 POST 请求(带故障转移)"""
|
|
51
|
+
...
|
|
52
|
+
|
|
49
53
|
def _ensure_synced_sync(self: "HTTPSandboxBackend"):
|
|
50
54
|
"""确保目录已同步(同步版本)"""
|
|
51
55
|
if not self._auto_sync:
|
|
@@ -72,6 +76,32 @@ class FileOperationsMixin:
|
|
|
72
76
|
self._workspace_verified = True
|
|
73
77
|
SYLogger.info(f"[Sandbox] 同步完成")
|
|
74
78
|
|
|
79
|
+
async def _ensure_synced_async(self: "HTTPSandboxBackend"):
|
|
80
|
+
"""确保目录已同步(异步版本)"""
|
|
81
|
+
if not self._auto_sync:
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
if self._synced and self._workspace_verified:
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
SYLogger.info(f"[Sandbox] 开始检查工作空间同步状态(异步)...")
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
workspace_exists = await self._check_workspace_exists_async()
|
|
91
|
+
except Exception as e:
|
|
92
|
+
SYLogger.warning(f"[Sandbox] 检查工作空间异常: {e},跳过检查")
|
|
93
|
+
workspace_exists = True
|
|
94
|
+
|
|
95
|
+
if not workspace_exists:
|
|
96
|
+
SYLogger.info(f"[Sandbox] 工作空间不存在或已被清空,重新同步...")
|
|
97
|
+
self._synced = False
|
|
98
|
+
|
|
99
|
+
if not self._synced:
|
|
100
|
+
SYLogger.info(f"[Sandbox] 开始同步目录(异步)...")
|
|
101
|
+
await self._sync_async()
|
|
102
|
+
self._workspace_verified = True
|
|
103
|
+
SYLogger.info(f"[Sandbox] 同步完成")
|
|
104
|
+
|
|
75
105
|
def _check_workspace_exists_sync(self: "HTTPSandboxBackend") -> bool:
|
|
76
106
|
"""检查沙箱工作空间是否存在(同步版本)"""
|
|
77
107
|
try:
|
|
@@ -84,10 +114,26 @@ class FileOperationsMixin:
|
|
|
84
114
|
SYLogger.warning(f"[Sandbox] 检查工作空间失败: {e}")
|
|
85
115
|
return False
|
|
86
116
|
|
|
117
|
+
async def _check_workspace_exists_async(self: "HTTPSandboxBackend") -> bool:
|
|
118
|
+
"""检查沙箱工作空间是否存在(异步版本)"""
|
|
119
|
+
try:
|
|
120
|
+
await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/ls", {
|
|
121
|
+
"path": "/",
|
|
122
|
+
"user_id": self.user_id
|
|
123
|
+
})
|
|
124
|
+
return True
|
|
125
|
+
except Exception as e:
|
|
126
|
+
SYLogger.warning(f"[Sandbox] 检查工作空间失败: {e}")
|
|
127
|
+
return False
|
|
128
|
+
|
|
87
129
|
def _sync_sync(self: "HTTPSandboxBackend"):
|
|
88
130
|
"""同步目录(同步版本,由子类实现)"""
|
|
89
131
|
...
|
|
90
132
|
|
|
133
|
+
async def _sync_async(self: "HTTPSandboxBackend") -> dict:
|
|
134
|
+
"""同步目录(异步版本,由子类实现)"""
|
|
135
|
+
...
|
|
136
|
+
|
|
91
137
|
# ============== 目录操作 ==============
|
|
92
138
|
|
|
93
139
|
def ls(self: "HTTPSandboxBackend", path: str) -> LsResult:
|
|
@@ -107,8 +153,20 @@ class FileOperationsMixin:
|
|
|
107
153
|
return LsResult(error=str(e))
|
|
108
154
|
|
|
109
155
|
async def als(self: "HTTPSandboxBackend", path: str) -> LsResult:
|
|
110
|
-
"""
|
|
111
|
-
|
|
156
|
+
"""异步列出目录内容(真正的异步实现)"""
|
|
157
|
+
try:
|
|
158
|
+
await self._ensure_synced_async()
|
|
159
|
+
SYLogger.info(f"[Sandbox] 异步列出目录: {path}")
|
|
160
|
+
result = await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/ls", {
|
|
161
|
+
"path": path,
|
|
162
|
+
"user_id": self.user_id
|
|
163
|
+
})
|
|
164
|
+
entries = [FileInfo(**item) for item in result]
|
|
165
|
+
SYLogger.info(f"[Sandbox] 目录内容: {len(entries)} 项")
|
|
166
|
+
return LsResult(entries=entries)
|
|
167
|
+
except Exception as e:
|
|
168
|
+
SYLogger.error(f"[Sandbox] 异步列出目录失败: {e}")
|
|
169
|
+
return LsResult(error=str(e))
|
|
112
170
|
|
|
113
171
|
# ============== 文件读写 ==============
|
|
114
172
|
|
|
@@ -153,8 +211,33 @@ class FileOperationsMixin:
|
|
|
153
211
|
offset: int = 0,
|
|
154
212
|
limit: int = 2000,
|
|
155
213
|
) -> ReadResult:
|
|
156
|
-
"""
|
|
157
|
-
|
|
214
|
+
"""异步读取文件内容(真正的异步实现)"""
|
|
215
|
+
try:
|
|
216
|
+
await self._ensure_synced_async()
|
|
217
|
+
SYLogger.info(f"[Sandbox] 异步读取文件: {file_path} (offset={offset}, limit={limit})")
|
|
218
|
+
result = await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/read", {
|
|
219
|
+
"file_path": file_path,
|
|
220
|
+
"user_id": self.user_id,
|
|
221
|
+
"offset": offset,
|
|
222
|
+
"limit": limit
|
|
223
|
+
})
|
|
224
|
+
if result.get("error"):
|
|
225
|
+
SYLogger.error(f"[Sandbox] 异步读取文件失败: {result['error']}")
|
|
226
|
+
return ReadResult(error=result["error"])
|
|
227
|
+
content = result.get("content", "")
|
|
228
|
+
SYLogger.info(f"[Sandbox] 异步读取完成: {len(content)} 字符")
|
|
229
|
+
from datetime import datetime
|
|
230
|
+
now = datetime.now().isoformat()
|
|
231
|
+
file_data = FileData(
|
|
232
|
+
content=content,
|
|
233
|
+
encoding="utf-8",
|
|
234
|
+
created_at=result.get("created_at", now),
|
|
235
|
+
modified_at=result.get("modified_at", now),
|
|
236
|
+
)
|
|
237
|
+
return ReadResult(file_data=file_data)
|
|
238
|
+
except Exception as e:
|
|
239
|
+
SYLogger.error(f"[Sandbox] 异步读取文件异常: {e}")
|
|
240
|
+
return ReadResult(error=str(e))
|
|
158
241
|
|
|
159
242
|
def write(
|
|
160
243
|
self: "HTTPSandboxBackend",
|
|
@@ -188,8 +271,27 @@ class FileOperationsMixin:
|
|
|
188
271
|
file_path: str,
|
|
189
272
|
content: str,
|
|
190
273
|
) -> WriteResult:
|
|
191
|
-
"""
|
|
192
|
-
|
|
274
|
+
"""异步写入文件(真正的异步实现)"""
|
|
275
|
+
try:
|
|
276
|
+
await self._ensure_synced_async()
|
|
277
|
+
SYLogger.info(f"[Sandbox] 异步写入文件: {file_path} ({len(content)} 字符)")
|
|
278
|
+
result = await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/write", {
|
|
279
|
+
"file_path": file_path,
|
|
280
|
+
"content": base64.b64encode(content.encode()).decode(),
|
|
281
|
+
"user_id": self.user_id
|
|
282
|
+
})
|
|
283
|
+
write_result = WriteResult(
|
|
284
|
+
error=result.get("error"),
|
|
285
|
+
path=result.get("path")
|
|
286
|
+
)
|
|
287
|
+
if write_result.error:
|
|
288
|
+
SYLogger.error(f"[Sandbox] 异步写入失败: {write_result.error}")
|
|
289
|
+
else:
|
|
290
|
+
SYLogger.info(f"[Sandbox] 异步写入成功: {write_result.path}")
|
|
291
|
+
return write_result
|
|
292
|
+
except Exception as e:
|
|
293
|
+
SYLogger.error(f"[Sandbox] 异步写入文件异常: {e}")
|
|
294
|
+
return WriteResult(error=str(e))
|
|
193
295
|
|
|
194
296
|
def edit(
|
|
195
297
|
self: "HTTPSandboxBackend",
|
|
@@ -224,8 +326,24 @@ class FileOperationsMixin:
|
|
|
224
326
|
new_string: str,
|
|
225
327
|
replace_all: bool = False,
|
|
226
328
|
) -> EditResult:
|
|
227
|
-
"""
|
|
228
|
-
|
|
329
|
+
"""异步编辑文件(真正的异步实现)"""
|
|
330
|
+
try:
|
|
331
|
+
await self._ensure_synced_async()
|
|
332
|
+
result = await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/edit", {
|
|
333
|
+
"file_path": file_path,
|
|
334
|
+
"old_string": base64.b64encode(old_string.encode()).decode(),
|
|
335
|
+
"new_string": base64.b64encode(new_string.encode()).decode(),
|
|
336
|
+
"user_id": self.user_id,
|
|
337
|
+
"replace_all": replace_all
|
|
338
|
+
})
|
|
339
|
+
return EditResult(
|
|
340
|
+
error=result.get("error"),
|
|
341
|
+
path=result.get("path"),
|
|
342
|
+
occurrences=result.get("occurrences")
|
|
343
|
+
)
|
|
344
|
+
except Exception as e:
|
|
345
|
+
SYLogger.error(f"[Sandbox] 异步编辑文件异常: {e}")
|
|
346
|
+
return EditResult(error=str(e))
|
|
229
347
|
|
|
230
348
|
# ============== 搜索 ==============
|
|
231
349
|
|
|
@@ -245,8 +363,19 @@ class FileOperationsMixin:
|
|
|
245
363
|
return GlobResult(error=str(e))
|
|
246
364
|
|
|
247
365
|
async def aglob(self: "HTTPSandboxBackend", pattern: str, path: str = "/") -> GlobResult:
|
|
248
|
-
"""异步 glob
|
|
249
|
-
|
|
366
|
+
"""异步 glob 搜索文件(真正的异步实现)"""
|
|
367
|
+
try:
|
|
368
|
+
await self._ensure_synced_async()
|
|
369
|
+
result = await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/glob", {
|
|
370
|
+
"pattern": pattern,
|
|
371
|
+
"path": path,
|
|
372
|
+
"user_id": self.user_id
|
|
373
|
+
})
|
|
374
|
+
matches = [FileInfo(**item) for item in result]
|
|
375
|
+
return GlobResult(matches=matches)
|
|
376
|
+
except Exception as e:
|
|
377
|
+
SYLogger.error(f"[Sandbox] 异步 glob 搜索失败: {e}")
|
|
378
|
+
return GlobResult(error=str(e))
|
|
250
379
|
|
|
251
380
|
def grep(
|
|
252
381
|
self: "HTTPSandboxBackend",
|
|
@@ -277,8 +406,22 @@ class FileOperationsMixin:
|
|
|
277
406
|
path: str = None,
|
|
278
407
|
glob: str = None,
|
|
279
408
|
) -> GrepResult:
|
|
280
|
-
"""
|
|
281
|
-
|
|
409
|
+
"""异步搜索文件内容(真正的异步实现)"""
|
|
410
|
+
try:
|
|
411
|
+
await self._ensure_synced_async()
|
|
412
|
+
result = await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/grep", {
|
|
413
|
+
"pattern": pattern,
|
|
414
|
+
"user_id": self.user_id,
|
|
415
|
+
"path": path,
|
|
416
|
+
"glob": glob
|
|
417
|
+
})
|
|
418
|
+
if isinstance(result, list):
|
|
419
|
+
matches = [GrepMatch(**item) for item in result]
|
|
420
|
+
return GrepResult(matches=matches)
|
|
421
|
+
return GrepResult(error="Unexpected result format")
|
|
422
|
+
except Exception as e:
|
|
423
|
+
SYLogger.error(f"[Sandbox] 异步 grep 搜索失败: {e}")
|
|
424
|
+
return GrepResult(error=str(e))
|
|
282
425
|
|
|
283
426
|
# ============== 兼容旧版 API(已废弃)==============
|
|
284
427
|
|