digitalkin 1.0.0.dev13__tar.gz → 1.0.0.dev15__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.
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/PKG-INFO +2 -2
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/pyproject.toml +3 -2
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/__version__.py +1 -1
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/common/factories.py +4 -10
- digitalkin-1.0.0.dev15/src/digitalkin/core/exceptions.py +33 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/base_task_manager.py +4 -7
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/local_task_manager.py +6 -10
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/redis_client.py +10 -3
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/remote_task_manager.py +6 -10
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/task_session.py +1 -1
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/gateway_servicer.py +11 -1
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/module_server.py +4 -4
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +29 -11
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/mixins/cost_mixin.py +1 -1
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/tool_cache.py +3 -5
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/_base_module.py +4 -4
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/storage/grpc_storage.py +46 -19
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin.egg-info/PKG-INFO +2 -2
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin.egg-info/requires.txt +1 -1
- digitalkin-1.0.0.dev13/src/digitalkin/core/exceptions.py +0 -16
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/LICENSE +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/README.md +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/echo_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/models/input.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/models/output.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/models/secret.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/models/setup.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/server.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/modules/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/modules/archetype_with_tools_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/monitoring/tests/test_metrics.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/client.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/echo_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/models/input.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/models/output.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/models/secret.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/models/setup.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/server.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/redis_demo/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/services/filesystem_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/services/storage_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/setup.cfg +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/community/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/community/agno/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/community/agno/agno_adapter.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/community/agno/agui_tools.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/community/agno/hitl.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/community/agno/models.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/profiling/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/profiling/step_timer.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/profiling/task_profiler.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/resilience/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/resilience/bulkhead.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/module_runner.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/instrumented.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/redis_checkpoint.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/redis_streams.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/redis/shadow.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/task_executor.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/interceptors/circuit_breaker_interceptor.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/module_servicer.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/stream_session.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/logger.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/mixins/agui_mixin.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/mixins/file_history_mixin.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/core/redis.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/core/task_monitor.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/events/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/events/agent_events.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/grpc_servers/models.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/ag_ui.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/module_context.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/request_metadata.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/select_schema.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/setup_types.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/tool_reference.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/utility.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/services/registry.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/services/services.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/consumer.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/gateway.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/grpc_client.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/log.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/profiling.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/queue.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/redis.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/resilience.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/server/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/server/channel.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/server/grpc.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/server/server.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/server/servicer.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/task_manager.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/settings/utils/channel.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/archetype_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/tool_module.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/py.typed +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/communication/communication_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/communication/default_communication.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/communication/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/communication/grpc_communication.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/cost/cost_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/cost/default_cost.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/cost/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/cost/grpc_cost.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/filesystem/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/registry/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/registry/default_registry.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/registry/grpc_registry.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/registry/registry_models.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/registry/registry_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/services_config.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/setup/default_setup.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/setup/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/setup/grpc_setup.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/setup/setup_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/storage/default_storage.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/storage/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/storage/storage_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/task_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/task_manager/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/user_profile/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/conditional_schema.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/exceptions.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/proto_utils.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/utils/schema_splitter.py +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin.egg-info/SOURCES.txt +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin.egg-info/top_level.txt +0 -0
- {digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/tests/test_exceptions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalkin
|
|
3
|
-
Version: 1.0.0.
|
|
3
|
+
Version: 1.0.0.dev15
|
|
4
4
|
Summary: SDK to build kin used in DigitalKin
|
|
5
5
|
Author-email: "DigitalKin.ai" <contact@digitalkin.ai>
|
|
6
6
|
License: Attribution-NonCommercial-ShareAlike 4.0 International
|
|
@@ -452,7 +452,7 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
452
452
|
Requires-Python: >=3.10
|
|
453
453
|
Description-Content-Type: text/markdown
|
|
454
454
|
License-File: LICENSE
|
|
455
|
-
Requires-Dist: ag-ui-protocol>=0.1.
|
|
455
|
+
Requires-Dist: ag-ui-protocol>=0.1.19
|
|
456
456
|
Requires-Dist: agentic-mesh-protocol==1.0.0.dev2
|
|
457
457
|
Requires-Dist: anyio>=4.13.0
|
|
458
458
|
Requires-Dist: grpcio-health-checking==1.80.0
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
]
|
|
28
28
|
|
|
29
29
|
dependencies = [
|
|
30
|
-
"ag-ui-protocol>=0.1.
|
|
30
|
+
"ag-ui-protocol>=0.1.19",
|
|
31
31
|
"agentic-mesh-protocol==1.0.0.dev2",
|
|
32
32
|
"anyio>=4.13.0",
|
|
33
33
|
"grpcio-health-checking==1.80.0",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"pydantic-settings>=2.14.1",
|
|
38
38
|
"redis[hiredis]>=7.4.0,<8",
|
|
39
39
|
]
|
|
40
|
-
version = "1.0.0.
|
|
40
|
+
version = "1.0.0.dev15"
|
|
41
41
|
|
|
42
42
|
[project.optional-dependencies]
|
|
43
43
|
performance = [ "uvloop>=0.21" ]
|
|
@@ -305,5 +305,6 @@
|
|
|
305
305
|
"smoke: marks critical path tests that should always pass",
|
|
306
306
|
"stability: marks long-running stability and soak tests",
|
|
307
307
|
"stress: marks stress/load tests for performance under pressure",
|
|
308
|
+
"unit: marks a plain unit test with no other applicable category",
|
|
308
309
|
"validation: marks tests for input validation and schema checking",
|
|
309
310
|
]
|
|
@@ -64,16 +64,10 @@ class ModuleFactory:
|
|
|
64
64
|
raise ValueError(msg)
|
|
65
65
|
|
|
66
66
|
logger.debug(
|
|
67
|
-
"Creating module instance: %s
|
|
67
|
+
"Creating module instance: %s (setup_version_id=%s)",
|
|
68
68
|
module_class.__name__,
|
|
69
|
-
|
|
70
|
-
extra={
|
|
71
|
-
"module_class": module_class.__name__,
|
|
72
|
-
"job_id": job_id,
|
|
73
|
-
"mission_id": mission_id,
|
|
74
|
-
"setup_id": setup_id,
|
|
75
|
-
"setup_version_id": setup_version_id,
|
|
76
|
-
},
|
|
69
|
+
setup_version_id,
|
|
70
|
+
extra={"job_id": job_id, "mission_id": mission_id, "setup_id": setup_id},
|
|
77
71
|
)
|
|
78
72
|
|
|
79
73
|
return module_class(
|
|
@@ -116,5 +110,5 @@ class QueueFactory:
|
|
|
116
110
|
msg = "maxsize must be >= 0"
|
|
117
111
|
raise ValueError(msg)
|
|
118
112
|
|
|
119
|
-
logger.debug("Creating bounded queue with maxsize: %d", maxsize
|
|
113
|
+
logger.debug("Creating bounded queue with maxsize: %d", maxsize)
|
|
120
114
|
return asyncio.Queue(maxsize=maxsize)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Exceptions for the DigitalKin core package."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BackpressureTimeoutError(Exception):
|
|
5
|
+
"""Producer's XADD throttled past the backpressure timeout.
|
|
6
|
+
|
|
7
|
+
Throttled past :data:`GatewayBackpressureSettings.backpressure_timeout_s`.
|
|
8
|
+
Caller (typically the module's ``_on_output`` callback) must surface
|
|
9
|
+
this as ``stream.error(code=BACKPRESSURE_TIMEOUT)`` via the
|
|
10
|
+
``_emit_fatal_to_redis`` path so the consumer sees a typed sentinel
|
|
11
|
+
instead of a silent stall.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BulkheadFullError(Exception):
|
|
16
|
+
"""Raised when a bulkhead semaphore cannot be acquired within timeout."""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class RedisUnreachableError(Exception):
|
|
20
|
+
"""Raised at gateway boot when Redis ping fails.
|
|
21
|
+
|
|
22
|
+
Redis is a required dependency for gateway operation (stream persistence,
|
|
23
|
+
pub/sub signals). Failing fast at boot is preferable to lazy first-request
|
|
24
|
+
failures that surface as opaque task errors.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, masked_url: str) -> None:
|
|
28
|
+
"""Initialize the error with a (masked) Redis URL for context.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
masked_url: Redis connection URL with credentials masked.
|
|
32
|
+
"""
|
|
33
|
+
super().__init__(f"Redis ping failed at gateway boot ({masked_url})")
|
|
@@ -103,14 +103,11 @@ class BaseTaskManager(ABC):
|
|
|
103
103
|
if get_task_manager_settings().max_queued_tasks > 0:
|
|
104
104
|
self._system_gate.release()
|
|
105
105
|
logger.info(
|
|
106
|
-
"Task cleaned up (%d remaining)",
|
|
106
|
+
"Task cleaned up (%d remaining) final_status=%s cancellation_reason=%s",
|
|
107
107
|
len(self.tasks_sessions),
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"final_status": final_status,
|
|
112
|
-
"cancellation_reason": cancellation_reason,
|
|
113
|
-
},
|
|
108
|
+
final_status,
|
|
109
|
+
cancellation_reason,
|
|
110
|
+
extra={"mission_id": mission_id, "task_id": task_id},
|
|
114
111
|
)
|
|
115
112
|
|
|
116
113
|
async def _validate_task_creation(self, task_id: str, mission_id: str, coro: Coroutine[Any, Any, None]) -> None:
|
|
@@ -76,26 +76,22 @@ class LocalTaskManager(BaseTaskManager):
|
|
|
76
76
|
self.tasks[task_id] = supervisor_task
|
|
77
77
|
|
|
78
78
|
logger.info(
|
|
79
|
-
"Local task created and started: '%s'",
|
|
79
|
+
"Local task created and started: '%s' (total_tasks=%d)",
|
|
80
80
|
task_id,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"task_id": task_id,
|
|
84
|
-
"total_tasks": len(self.tasks),
|
|
85
|
-
},
|
|
81
|
+
len(self.tasks),
|
|
82
|
+
extra={"mission_id": mission_id, "task_id": task_id},
|
|
86
83
|
)
|
|
87
84
|
|
|
88
|
-
except Exception
|
|
85
|
+
except Exception:
|
|
89
86
|
coro.close()
|
|
90
87
|
# Release the slot if cleanup won't (session never registered).
|
|
91
88
|
if task_id not in self.tasks_sessions:
|
|
92
89
|
self._task_slot.release()
|
|
93
90
|
else:
|
|
94
91
|
await self._cleanup_task(task_id, mission_id=mission_id)
|
|
95
|
-
logger.
|
|
92
|
+
logger.exception(
|
|
96
93
|
"Failed to create local task: '%s'",
|
|
97
94
|
task_id,
|
|
98
|
-
extra={"mission_id": mission_id, "task_id": task_id
|
|
99
|
-
exc_info=True,
|
|
95
|
+
extra={"mission_id": mission_id, "task_id": task_id},
|
|
100
96
|
)
|
|
101
97
|
raise
|
|
@@ -69,17 +69,24 @@ class RedisClient: # noqa: PLR0904
|
|
|
69
69
|
)
|
|
70
70
|
|
|
71
71
|
async def verify(self) -> bool:
|
|
72
|
-
"""Verify Redis is reachable by
|
|
72
|
+
"""Verify Redis is reachable by pinging both pools.
|
|
73
|
+
|
|
74
|
+
Pings ``_client`` and ``_blocking_client`` concurrently so the first
|
|
75
|
+
XADD and first XREAD don't each pay DNS+TCP+AUTH on cold pools.
|
|
73
76
|
|
|
74
77
|
Timeout comes from ``RedisPoolSettings.health_check_timeout`` (env
|
|
75
78
|
``DIGITALKIN_REDIS_HEALTH_CHECK_TIMEOUT``).
|
|
76
79
|
|
|
77
80
|
Returns:
|
|
78
|
-
True if
|
|
81
|
+
True if both pools responded, False if either is unreachable.
|
|
79
82
|
"""
|
|
80
83
|
try:
|
|
81
84
|
timeout = get_redis_settings().pool.health_check_timeout
|
|
82
|
-
|
|
85
|
+
results = await asyncio.gather(
|
|
86
|
+
asyncio.wait_for(self._client.ping(), timeout=timeout), # type: ignore[arg-type]
|
|
87
|
+
asyncio.wait_for(self._blocking_client.ping(), timeout=timeout), # type: ignore[arg-type]
|
|
88
|
+
)
|
|
89
|
+
return all(results)
|
|
83
90
|
except Exception:
|
|
84
91
|
logger.warning("Redis health check failed for %s", GatewayValidator.mask_redis_url(self.url), exc_info=True)
|
|
85
92
|
return False
|
|
@@ -57,26 +57,22 @@ class RemoteTaskManager(BaseTaskManager):
|
|
|
57
57
|
coro.close()
|
|
58
58
|
|
|
59
59
|
logger.info(
|
|
60
|
-
"Remote task registered: '%s'",
|
|
60
|
+
"Remote task registered: '%s' (total_sessions=%d)",
|
|
61
61
|
task_id,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"task_id": task_id,
|
|
65
|
-
"total_sessions": len(self.tasks_sessions),
|
|
66
|
-
},
|
|
62
|
+
len(self.tasks_sessions),
|
|
63
|
+
extra={"mission_id": mission_id, "task_id": task_id},
|
|
67
64
|
)
|
|
68
65
|
|
|
69
|
-
except Exception
|
|
66
|
+
except Exception:
|
|
70
67
|
coro.close()
|
|
71
68
|
# Release semaphore if session was never registered (cleanup won't release it)
|
|
72
69
|
if task_id not in self.tasks_sessions:
|
|
73
70
|
self._task_slot.release()
|
|
74
71
|
else:
|
|
75
72
|
await self._cleanup_task(task_id, mission_id=mission_id)
|
|
76
|
-
logger.
|
|
73
|
+
logger.exception(
|
|
77
74
|
"Failed to register remote task: '%s'",
|
|
78
75
|
task_id,
|
|
79
|
-
extra={"mission_id": mission_id, "task_id": task_id
|
|
80
|
-
exc_info=True,
|
|
76
|
+
extra={"mission_id": mission_id, "task_id": task_id},
|
|
81
77
|
)
|
|
82
78
|
raise
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/core/task_manager/task_session.py
RENAMED
|
@@ -284,7 +284,7 @@ class TaskSession:
|
|
|
284
284
|
return
|
|
285
285
|
self._cleanup_done = True
|
|
286
286
|
|
|
287
|
-
logger.debug("Cleanup: draining queue
|
|
287
|
+
logger.debug("Cleanup: draining queue (queue_size=%d)", self.queue.qsize(), extra=ids)
|
|
288
288
|
try:
|
|
289
289
|
while not self.queue.empty():
|
|
290
290
|
self.queue.get_nowait()
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/gateway_servicer.py
RENAMED
|
@@ -15,6 +15,7 @@ from google.protobuf import struct_pb2
|
|
|
15
15
|
from grpc._cython.cygrpc import UsageError as _GrpcUsageError # noqa: PLC2701
|
|
16
16
|
from redis.exceptions import RedisError
|
|
17
17
|
|
|
18
|
+
from digitalkin.core.exceptions import RedisUnreachableError
|
|
18
19
|
from digitalkin.core.profiling.step_timer import StepTimer
|
|
19
20
|
from digitalkin.core.task_manager.redis.proto_streams import ProtoStreamReader
|
|
20
21
|
from digitalkin.core.task_manager.redis.redis_signal import SharedRedisListener
|
|
@@ -131,7 +132,16 @@ class GatewayServicer:
|
|
|
131
132
|
return task
|
|
132
133
|
|
|
133
134
|
async def start(self) -> None:
|
|
134
|
-
"""Start the M2M call-registry TTL sweeper and PSUBSCRIBE the signal listener.
|
|
135
|
+
"""Start the M2M call-registry TTL sweeper and PSUBSCRIBE the signal listener.
|
|
136
|
+
|
|
137
|
+
Pre-warms both Redis pools so the first XADD and first XREAD don't pay
|
|
138
|
+
DNS+TCP+AUTH on cold connections.
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
RedisUnreachableError: Redis ping failed; gateway cannot serve traffic.
|
|
142
|
+
"""
|
|
143
|
+
if not await self._redis_client.verify():
|
|
144
|
+
raise RedisUnreachableError(GatewayValidator.mask_redis_url(self._redis_client.url))
|
|
135
145
|
await self._m2m.start()
|
|
136
146
|
listener = SharedRedisListener.singleton_or_none()
|
|
137
147
|
if listener is not None:
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/grpc_servers/module_server.py
RENAMED
|
@@ -246,11 +246,11 @@ class ModuleServer(BaseServer):
|
|
|
246
246
|
advertise_address = get_server_settings().channel.advertise_host or get_server_settings().channel.host
|
|
247
247
|
|
|
248
248
|
logger.info(
|
|
249
|
-
"Registering module with registry at %s:%d version=%s",
|
|
249
|
+
"Registering module with registry at %s:%d version=%s module_id=%s",
|
|
250
250
|
advertise_address,
|
|
251
251
|
get_server_settings().channel.port,
|
|
252
252
|
version,
|
|
253
|
-
|
|
253
|
+
module_id,
|
|
254
254
|
)
|
|
255
255
|
|
|
256
256
|
result = await self.registry.register(
|
|
@@ -265,10 +265,10 @@ class ModuleServer(BaseServer):
|
|
|
265
265
|
raise RuntimeError(msg)
|
|
266
266
|
|
|
267
267
|
logger.info(
|
|
268
|
-
"Module registered successfully at %s:%d",
|
|
268
|
+
"Module registered successfully at %s:%d module_id=%s",
|
|
269
269
|
advertise_address,
|
|
270
270
|
get_server_settings().channel.port,
|
|
271
|
-
|
|
271
|
+
result.module_id,
|
|
272
272
|
)
|
|
273
273
|
|
|
274
274
|
async def start_async(self) -> None:
|
|
@@ -48,6 +48,14 @@ class GrpcClientWrapper:
|
|
|
48
48
|
grpc.StatusCode.DEADLINE_EXCEEDED,
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
# Codes that count toward opening the circuit (service-health failures).
|
|
52
|
+
# Application-level codes (NOT_FOUND, INVALID_ARGUMENT, …) mean the service
|
|
53
|
+
# responded, so they never trip the breaker.
|
|
54
|
+
_CIRCUIT_FAILURE_CODES: ClassVar[set[grpc.StatusCode]] = _RETRYABLE_CODES | {
|
|
55
|
+
grpc.StatusCode.UNKNOWN,
|
|
56
|
+
grpc.StatusCode.RESOURCE_EXHAUSTED,
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
@staticmethod
|
|
52
60
|
def _build_channel_credentials(config: ClientConfig) -> grpc.ChannelCredentials | None:
|
|
53
61
|
"""Build SSL channel credentials from config if secure mode.
|
|
@@ -242,18 +250,28 @@ class GrpcClientWrapper:
|
|
|
242
250
|
response = await rpc_method(request, timeout=timeout)
|
|
243
251
|
except grpc.RpcError as e:
|
|
244
252
|
last_error = e
|
|
245
|
-
if e.code()
|
|
253
|
+
if e.code() in self._RETRYABLE_CODES and attempt < max_retries:
|
|
254
|
+
logger.warning(
|
|
255
|
+
"gRPC transient error on %s.%s [%s] (attempt %d/%d), retrying in %.0fms",
|
|
256
|
+
self.service_name,
|
|
257
|
+
query_endpoint,
|
|
258
|
+
e.code().name,
|
|
259
|
+
attempt + 1,
|
|
260
|
+
max_retries + 1,
|
|
261
|
+
backoff_delays[attempt] * 1000,
|
|
262
|
+
)
|
|
263
|
+
continue
|
|
264
|
+
if e.code() in self._CIRCUIT_FAILURE_CODES:
|
|
265
|
+
logger.warning(
|
|
266
|
+
"circuit-breaker tick: %s.%s [%s]",
|
|
267
|
+
self.service_name,
|
|
268
|
+
query_endpoint,
|
|
269
|
+
e.code().name,
|
|
270
|
+
)
|
|
246
271
|
cb.record_failure()
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
self.service_name,
|
|
251
|
-
query_endpoint,
|
|
252
|
-
e.code().name,
|
|
253
|
-
attempt + 1,
|
|
254
|
-
max_retries + 1,
|
|
255
|
-
backoff_delays[attempt] * 1000,
|
|
256
|
-
)
|
|
272
|
+
else:
|
|
273
|
+
cb.record_success()
|
|
274
|
+
break
|
|
257
275
|
else:
|
|
258
276
|
cb.record_success()
|
|
259
277
|
return response
|
|
@@ -28,7 +28,7 @@ class CostMixin:
|
|
|
28
28
|
try:
|
|
29
29
|
await context.cost.add(name, cost_config_name, quantity)
|
|
30
30
|
except Exception:
|
|
31
|
-
logger.
|
|
31
|
+
logger.exception("Failed to add cost '%s' (config=%s), continuing", name, cost_config_name)
|
|
32
32
|
|
|
33
33
|
@staticmethod
|
|
34
34
|
async def get_cost(context: ModuleContext, name: str) -> list[CostData]:
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/models/module/tool_cache.py
RENAMED
|
@@ -205,11 +205,9 @@ class ToolCache(BaseModel):
|
|
|
205
205
|
)
|
|
206
206
|
self.entries[setup_id] = tool_module_info
|
|
207
207
|
logger.debug(
|
|
208
|
-
"Tool cached",
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
"module_id": tool_module_info.module_id,
|
|
212
|
-
},
|
|
208
|
+
"Tool cached: module_id=%s",
|
|
209
|
+
tool_module_info.module_id,
|
|
210
|
+
extra={"setup_id": setup_id},
|
|
213
211
|
)
|
|
214
212
|
|
|
215
213
|
def get(
|
|
@@ -560,7 +560,7 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
|
|
|
560
560
|
)
|
|
561
561
|
)
|
|
562
562
|
except Exception:
|
|
563
|
-
logger.exception("Failed to send error callback")
|
|
563
|
+
logger.exception("Failed to send error callback", extra=self.context.session.current_ids())
|
|
564
564
|
else:
|
|
565
565
|
self._status = ModuleStatus.STOPPING
|
|
566
566
|
|
|
@@ -627,7 +627,7 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
|
|
|
627
627
|
self._status = ModuleStatus.FAILED
|
|
628
628
|
short_description = "Error initializing module"
|
|
629
629
|
error_detail = f"{type(e).__name__}: {e}" if str(e) else type(e).__name__
|
|
630
|
-
logger.exception("%s: %s", short_description, error_detail)
|
|
630
|
+
logger.exception("%s: %s", short_description, error_detail, extra=self.context.session.current_ids())
|
|
631
631
|
await callback(
|
|
632
632
|
ModuleCodeModel(
|
|
633
633
|
code="Error",
|
|
@@ -645,7 +645,7 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
|
|
|
645
645
|
timer.mark("run_lifecycle")
|
|
646
646
|
except Exception:
|
|
647
647
|
self._status = ModuleStatus.FAILED
|
|
648
|
-
logger.exception("Error during module
|
|
648
|
+
logger.exception("Error during module lifecycle", extra=self.context.session.current_ids())
|
|
649
649
|
finally:
|
|
650
650
|
timer.log("module.start", task_id=self.context.session.current_ids().get("job_id", ""))
|
|
651
651
|
await self.stop()
|
|
@@ -691,7 +691,7 @@ class BaseModule( # Module SDK base class requires many public methods # noqa:
|
|
|
691
691
|
)
|
|
692
692
|
except Exception:
|
|
693
693
|
self._status = ModuleStatus.FAILED
|
|
694
|
-
logger.exception("Error stopping module")
|
|
694
|
+
logger.exception("Error stopping module", extra=self.context.session.current_ids())
|
|
695
695
|
|
|
696
696
|
async def _resolve_tools(self, config_setup_data: SetupModelT) -> None:
|
|
697
697
|
"""Resolve tool references and build cache.
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/src/digitalkin/services/storage/grpc_storage.py
RENAMED
|
@@ -4,6 +4,7 @@ from agentic_mesh_protocol.storage.v1 import data_pb2, storage_service_pb2_grpc
|
|
|
4
4
|
from google.protobuf.struct_pb2 import Struct
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
7
|
+
from digitalkin.grpc_servers.exceptions import CircuitOpenError
|
|
7
8
|
from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
|
|
8
9
|
from digitalkin.logger import logger
|
|
9
10
|
from digitalkin.models.grpc_servers.models import ClientConfig
|
|
@@ -21,6 +22,22 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
21
22
|
|
|
22
23
|
service_name: str = "StorageService"
|
|
23
24
|
|
|
25
|
+
@staticmethod
|
|
26
|
+
def _is_circuit_open(error: Exception) -> bool:
|
|
27
|
+
"""Whether ``error`` is a fast-fail from an open circuit breaker.
|
|
28
|
+
|
|
29
|
+
An open breaker is an expected, already-logged condition (the
|
|
30
|
+
CLOSED -> OPEN transition is logged once), so per-call rejections are
|
|
31
|
+
logged quietly to avoid flooding logs during an outage window.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
error: The exception raised by ``exec_grpc_query``.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
True if the error's cause is a ``CircuitOpenError``.
|
|
38
|
+
"""
|
|
39
|
+
return isinstance(error.__cause__, CircuitOpenError)
|
|
40
|
+
|
|
24
41
|
def _build_record_from_proto(self, proto: data_pb2.StorageRecord) -> StorageRecord:
|
|
25
42
|
"""Convert a protobuf StorageRecord message into our Pydantic model.
|
|
26
43
|
|
|
@@ -83,11 +100,10 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
83
100
|
resp = await self.exec_grpc_query("StoreRecord", req)
|
|
84
101
|
return self._build_record_from_proto(resp.stored_data)
|
|
85
102
|
except Exception as e:
|
|
86
|
-
|
|
87
|
-
"gRPC StoreRecord
|
|
88
|
-
|
|
89
|
-
record.record_id
|
|
90
|
-
)
|
|
103
|
+
if self._is_circuit_open(e):
|
|
104
|
+
logger.debug("gRPC StoreRecord skipped (circuit open) for %s:%s", record.collection, record.record_id)
|
|
105
|
+
else:
|
|
106
|
+
logger.exception("gRPC StoreRecord failed for %s:%s", record.collection, record.record_id)
|
|
91
107
|
raise StorageServiceError(str(e)) from e
|
|
92
108
|
|
|
93
109
|
async def _read(self, collection: str, record_id: str) -> StorageRecord | None:
|
|
@@ -105,8 +121,11 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
105
121
|
)
|
|
106
122
|
resp = await self.exec_grpc_query("ReadRecord", req)
|
|
107
123
|
return self._build_record_from_proto(resp.stored_data)
|
|
108
|
-
except Exception:
|
|
109
|
-
|
|
124
|
+
except Exception as e:
|
|
125
|
+
if self._is_circuit_open(e):
|
|
126
|
+
logger.debug("gRPC ReadRecord skipped (circuit open) for %s:%s", collection, record_id)
|
|
127
|
+
else:
|
|
128
|
+
logger.info("gRPC ReadRecord failed for %s:%s: %s", collection, record_id, e)
|
|
110
129
|
return None
|
|
111
130
|
|
|
112
131
|
async def _update(
|
|
@@ -137,8 +156,11 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
137
156
|
)
|
|
138
157
|
resp = await self.exec_grpc_query("UpdateRecord", req)
|
|
139
158
|
return self._build_record_from_proto(resp.stored_data)
|
|
140
|
-
except Exception:
|
|
141
|
-
|
|
159
|
+
except Exception as e:
|
|
160
|
+
if self._is_circuit_open(e):
|
|
161
|
+
logger.debug("gRPC UpdateRecord skipped (circuit open) for %s:%s", collection, record_id)
|
|
162
|
+
else:
|
|
163
|
+
logger.warning("gRPC UpdateRecord failed for %s:%s: %s", collection, record_id, e)
|
|
142
164
|
return None
|
|
143
165
|
|
|
144
166
|
async def _remove(self, collection: str, record_id: str) -> bool:
|
|
@@ -159,12 +181,11 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
159
181
|
record_id=record_id,
|
|
160
182
|
)
|
|
161
183
|
await self.exec_grpc_query("RemoveRecord", req)
|
|
162
|
-
except Exception:
|
|
163
|
-
|
|
164
|
-
"gRPC RemoveRecord
|
|
165
|
-
|
|
166
|
-
record_id,
|
|
167
|
-
)
|
|
184
|
+
except Exception as e:
|
|
185
|
+
if self._is_circuit_open(e):
|
|
186
|
+
logger.debug("gRPC RemoveRecord skipped (circuit open) for %s:%s", collection, record_id)
|
|
187
|
+
else:
|
|
188
|
+
logger.warning("gRPC RemoveRecord failed for %s:%s: %s", collection, record_id, e)
|
|
168
189
|
return False
|
|
169
190
|
return True
|
|
170
191
|
|
|
@@ -185,8 +206,11 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
185
206
|
)
|
|
186
207
|
resp = await self.exec_grpc_query("ListRecords", req)
|
|
187
208
|
return [self._build_record_from_proto(r) for r in resp.records]
|
|
188
|
-
except Exception:
|
|
189
|
-
|
|
209
|
+
except Exception as e:
|
|
210
|
+
if self._is_circuit_open(e):
|
|
211
|
+
logger.debug("gRPC ListRecords skipped (circuit open) for %s", collection)
|
|
212
|
+
else:
|
|
213
|
+
logger.warning("gRPC ListRecords failed for %s: %s", collection, e)
|
|
190
214
|
return []
|
|
191
215
|
|
|
192
216
|
async def _remove_collection(self, collection: str) -> bool:
|
|
@@ -204,8 +228,11 @@ class GrpcStorage(StorageStrategy, GrpcClientWrapper):
|
|
|
204
228
|
collection=collection,
|
|
205
229
|
)
|
|
206
230
|
await self.exec_grpc_query("RemoveCollection", req)
|
|
207
|
-
except Exception:
|
|
208
|
-
|
|
231
|
+
except Exception as e:
|
|
232
|
+
if self._is_circuit_open(e):
|
|
233
|
+
logger.debug("gRPC RemoveCollection skipped (circuit open) for %s", collection)
|
|
234
|
+
else:
|
|
235
|
+
logger.warning("gRPC RemoveCollection failed for %s: %s", collection, e)
|
|
209
236
|
return False
|
|
210
237
|
return True
|
|
211
238
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalkin
|
|
3
|
-
Version: 1.0.0.
|
|
3
|
+
Version: 1.0.0.dev15
|
|
4
4
|
Summary: SDK to build kin used in DigitalKin
|
|
5
5
|
Author-email: "DigitalKin.ai" <contact@digitalkin.ai>
|
|
6
6
|
License: Attribution-NonCommercial-ShareAlike 4.0 International
|
|
@@ -452,7 +452,7 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
452
452
|
Requires-Python: >=3.10
|
|
453
453
|
Description-Content-Type: text/markdown
|
|
454
454
|
License-File: LICENSE
|
|
455
|
-
Requires-Dist: ag-ui-protocol>=0.1.
|
|
455
|
+
Requires-Dist: ag-ui-protocol>=0.1.19
|
|
456
456
|
Requires-Dist: agentic-mesh-protocol==1.0.0.dev2
|
|
457
457
|
Requires-Dist: anyio>=4.13.0
|
|
458
458
|
Requires-Dist: grpcio-health-checking==1.80.0
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"""Exceptions for the DigitalKin core package."""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class BackpressureTimeoutError(Exception):
|
|
5
|
-
"""Producer's XADD throttled past the backpressure timeout.
|
|
6
|
-
|
|
7
|
-
Throttled past :data:`GatewayBackpressureSettings.backpressure_timeout_s`.
|
|
8
|
-
Caller (typically the module's ``_on_output`` callback) must surface
|
|
9
|
-
this as ``stream.error(code=BACKPRESSURE_TIMEOUT)`` via the
|
|
10
|
-
``_emit_fatal_to_redis`` path so the consumer sees a typed sentinel
|
|
11
|
-
instead of a silent stall.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class BulkheadFullError(Exception):
|
|
16
|
-
"""Raised when a bulkhead semaphore cannot be acquired within timeout."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/mock/mock_pb2_grpc.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/server_async_insecure.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/server_async_secure.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/server_sync_insecure.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/base_server/server_sync_secure.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/triggers/__init__.py
RENAMED
|
File without changes
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/bench_module/triggers/message_trigger.py
RENAMED
|
File without changes
|
|
File without changes
|
{digitalkin-1.0.0.dev13 → digitalkin-1.0.0.dev15}/examples/modules/archetype_with_tools_module.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|