digitalkin 1.0.0.dev23__tar.gz → 1.0.0.dev25__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.dev23 → digitalkin-1.0.0.dev25}/PKG-INFO +1 -1
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/pyproject.toml +1 -1
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/__version__.py +1 -1
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/profiling/step_timer.py +2 -2
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/local_task_manager.py +0 -4
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/module_runner.py +2 -13
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -6
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/redis/redis_signal.py +14 -20
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -4
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/task_session.py +4 -4
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/gateway_servicer.py +11 -104
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/m2m_call_registry.py +1 -8
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/module_server.py +0 -4
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/module_servicer.py +19 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/stream_registry.py +0 -5
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +6 -20
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/logger.py +0 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/mixins/agui_mixin.py +0 -4
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/tool_reference.py +3 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/gateway.py +4 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/communication/grpc_communication.py +58 -29
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/cost/grpc_cost.py +0 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/registry/grpc_registry.py +0 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/secret/grpc_secret.py +13 -2
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/services_config.py +8 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/setup/grpc_setup.py +0 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/storage/grpc_storage.py +0 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/task_manager/default_task_manager.py +1 -4
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -3
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin.egg-info/PKG-INFO +1 -1
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/LICENSE +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/README.md +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/base_server/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/echo_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/models/input.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/models/output.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/models/secret.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/models/setup.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/server.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/bench_module/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/modules/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/modules/archetype_with_tools_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/monitoring/tests/test_metrics.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/client.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/echo_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/models/input.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/models/output.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/models/secret.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/models/setup.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/server.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/redis_demo/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/services/filesystem_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/examples/services/storage_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/setup.cfg +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/community/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/community/agno/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/community/agno/agno_adapter.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/community/agno/agui_tools.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/community/agno/hitl.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/community/agno/models.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/common/factories.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/profiling/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/profiling/task_profiler.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/resilience/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/resilience/bulkhead.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/task_executor.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/stream_session.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/mixins/cost_mixin.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/mixins/file_history_mixin.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/core/redis.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/core/task_monitor.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/events/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/events/agent_events.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/grpc_servers/models.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/ag_ui.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/module_context.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/request_metadata.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/select_schema.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/setup_types.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/tool_cache.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/module/utility.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/services/registry.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/services/services.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/grpc_client.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/log.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/profiling.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/queue.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/redis.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/resilience.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/server/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/server/channel.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/server/grpc.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/server/server.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/server/servicer.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/task_manager.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/settings/utils/channel.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/_base_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/archetype_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/tool_module.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/py.typed +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/communication/communication_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/communication/default_communication.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/communication/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/cost/cost_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/cost/default_cost.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/cost/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/filesystem/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/registry/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/registry/default_registry.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/registry/registry_models.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/registry/registry_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/secret/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/secret/default_secret.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/secret/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/secret/secret_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/setup/default_setup.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/setup/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/setup/setup_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/storage/default_storage.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/storage/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/storage/storage_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/task_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/task_manager/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/user_profile/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/conditional_schema.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/exceptions.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/proto_utils.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/utils/schema_splitter.py +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin.egg-info/SOURCES.txt +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin.egg-info/requires.txt +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin.egg-info/top_level.txt +0 -0
- {digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/tests/test_exceptions.py +0 -0
{digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/profiling/step_timer.py
RENAMED
|
@@ -51,9 +51,9 @@ class StepTimer:
|
|
|
51
51
|
total = (self._last - self._t0) / 1e6
|
|
52
52
|
parts.append(f"total={total:.2f}ms")
|
|
53
53
|
if task_id:
|
|
54
|
-
logger.
|
|
54
|
+
logger.debug("[perf] %s: %s task_id=%s", prefix, " ".join(parts), task_id)
|
|
55
55
|
else:
|
|
56
|
-
logger.
|
|
56
|
+
logger.debug("[perf] %s: %s", prefix, " ".join(parts))
|
|
57
57
|
|
|
58
58
|
def total_ms(self) -> float:
|
|
59
59
|
"""Total elapsed time across all marks in milliseconds.
|
|
@@ -91,10 +91,6 @@ class LocalTaskManager(BaseTaskManager):
|
|
|
91
91
|
else:
|
|
92
92
|
# H2: this call never registered a session (e.g. duplicate task_id) —
|
|
93
93
|
# undo only THIS call's admission; never touch the live task.
|
|
94
|
-
logger.info(
|
|
95
|
-
"[VALIDATE H2] create rejected without touching live task: '%s'",
|
|
96
|
-
task_id,
|
|
97
|
-
) # TODO(validate): remove after prod validation
|
|
98
94
|
self._release_admission()
|
|
99
95
|
logger.exception(
|
|
100
96
|
"Failed to create local task: '%s'",
|
{digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/module_runner.py
RENAMED
|
@@ -113,12 +113,6 @@ class ModuleRunner:
|
|
|
113
113
|
await self._redis_client.xadd(stream_key, {"eos": b"true"})
|
|
114
114
|
await self._redis_client.expire(stream_key, stream_settings.redis_stream_ttl)
|
|
115
115
|
t_eos_write_end = time.perf_counter_ns()
|
|
116
|
-
logger.info(
|
|
117
|
-
"[VALIDATE M4] proto stream wrote %d seq'd entries (maxlen=%d): task_id=%s",
|
|
118
|
-
seq,
|
|
119
|
-
stream_maxlen,
|
|
120
|
-
task_id,
|
|
121
|
-
) # TODO(validate): remove after prod validation
|
|
122
116
|
logger.info(
|
|
123
117
|
"[close-debug] producer_eos_write: xadd_expire=%.2fms t_done_ns=%d task_id=%s",
|
|
124
118
|
(t_eos_write_end - t_eos_write_start) / 1e6,
|
|
@@ -137,8 +131,8 @@ class ModuleRunner:
|
|
|
137
131
|
# Arm a TTL on first XADD; final EXPIRE on stream.end shortens it.
|
|
138
132
|
if not first_logged:
|
|
139
133
|
elapsed_ms = (time.perf_counter_ns() - runner_start_ns) / 1e6
|
|
140
|
-
logger.
|
|
141
|
-
"[
|
|
134
|
+
logger.debug(
|
|
135
|
+
"[perf] producer_first_byte_to_redis: %.1fms task_id=%s",
|
|
142
136
|
elapsed_ms,
|
|
143
137
|
task_id,
|
|
144
138
|
extra=log_extra,
|
|
@@ -218,11 +212,6 @@ class ModuleRunner:
|
|
|
218
212
|
logger.exception("ModuleRunner: backpressure timeout", extra=log_extra)
|
|
219
213
|
await on_fatal(StreamErrorCode.BACKPRESSURE_TIMEOUT.value, str(exc))
|
|
220
214
|
except RedisError as exc:
|
|
221
|
-
logger.error(
|
|
222
|
-
"[VALIDATE R2] ModuleRunner: Redis unavailable writing output: task_id=%s",
|
|
223
|
-
task_id,
|
|
224
|
-
extra=log_extra,
|
|
225
|
-
) # TODO(validate): remove after prod validation
|
|
226
215
|
await on_fatal(
|
|
227
216
|
StreamErrorCode.REDIS_UNAVAILABLE.value,
|
|
228
217
|
f"redis unavailable: {type(exc).__name__}: {exc}",
|
|
@@ -150,12 +150,6 @@ class ProtoStreamReader:
|
|
|
150
150
|
s.ParseFromString(pb_bytes)
|
|
151
151
|
except DecodeError:
|
|
152
152
|
# M6: poison entry (truncated/corrupt pb) — drop it, keep the stream alive.
|
|
153
|
-
logger.warning(
|
|
154
|
-
"[VALIDATE M6] dropped corrupt proto stream entry: task_id=%s seq=%d bytes=%d",
|
|
155
|
-
self._task_id,
|
|
156
|
-
seq,
|
|
157
|
-
len(pb_bytes),
|
|
158
|
-
) # TODO(validate): remove after prod validation
|
|
159
153
|
continue
|
|
160
154
|
yield s
|
|
161
155
|
|
|
@@ -108,8 +108,8 @@ class SharedRedisListener:
|
|
|
108
108
|
self._pubsub = self._redis_client.pubsub()
|
|
109
109
|
await self._pubsub.psubscribe("signal_ch:*")
|
|
110
110
|
psub_ms = (time.perf_counter_ns() - psub_t0) / 1e6
|
|
111
|
-
logger.
|
|
112
|
-
"[
|
|
111
|
+
logger.debug(
|
|
112
|
+
"[perf] signal_psubscribe: psubscribe_ms=%.2f pattern=signal_ch:* phase=boot origin=%s",
|
|
113
113
|
psub_ms,
|
|
114
114
|
SharedRedisListener.PROCESS_ID,
|
|
115
115
|
)
|
|
@@ -142,8 +142,8 @@ class SharedRedisListener:
|
|
|
142
142
|
task.add_done_callback(lambda _: self.unregister(task_id))
|
|
143
143
|
|
|
144
144
|
self._counters["subscribed"] += 1
|
|
145
|
-
logger.
|
|
146
|
-
"[
|
|
145
|
+
logger.debug(
|
|
146
|
+
"[perf] signal_subscribe: register_ms=%.2f active_subs=%d task_id=%s origin=%s",
|
|
147
147
|
(time.perf_counter_ns() - reg_t0) / 1e6,
|
|
148
148
|
len(self._task_refs),
|
|
149
149
|
task_id,
|
|
@@ -176,14 +176,11 @@ class SharedRedisListener:
|
|
|
176
176
|
if action.startswith("invalidate_"):
|
|
177
177
|
origin = data.get("origin")
|
|
178
178
|
if origin is not None and origin == SharedRedisListener.PROCESS_ID:
|
|
179
|
-
logger.debug(
|
|
180
|
-
"[VALIDATE D3b] skipped self-originated invalidate action=%s", action
|
|
181
|
-
) # TODO(validate): remove after prod validation
|
|
182
179
|
return True
|
|
183
180
|
setup_id = data.get("setup_id", "")
|
|
184
181
|
self._counters["invalidated"] += 1
|
|
185
|
-
logger.
|
|
186
|
-
"[
|
|
182
|
+
logger.debug(
|
|
183
|
+
"[perf] signal_invalidate: e2e_ms=%.2f action=%s setup_id=%s",
|
|
187
184
|
e2e_ms,
|
|
188
185
|
action,
|
|
189
186
|
setup_id,
|
|
@@ -196,8 +193,8 @@ class SharedRedisListener:
|
|
|
196
193
|
inv_task.add_done_callback(log_unhandled)
|
|
197
194
|
return True
|
|
198
195
|
|
|
199
|
-
logger.
|
|
200
|
-
"[
|
|
196
|
+
logger.debug(
|
|
197
|
+
"[perf] signal_dispatch: e2e_ms=%.2f dispatch_ms=%.2f action=%s task_id=%s",
|
|
201
198
|
e2e_ms,
|
|
202
199
|
(time.perf_counter_ns() - dispatch_t0) / 1e6,
|
|
203
200
|
action,
|
|
@@ -253,8 +250,8 @@ class SharedRedisListener:
|
|
|
253
250
|
psub_t0 = time.perf_counter_ns()
|
|
254
251
|
await self._pubsub.psubscribe("signal_ch:*")
|
|
255
252
|
psub_ms = (time.perf_counter_ns() - psub_t0) / 1e6
|
|
256
|
-
logger.
|
|
257
|
-
"[
|
|
253
|
+
logger.debug(
|
|
254
|
+
"[perf] signal_psubscribe: psubscribe_ms=%.2f pattern=signal_ch:* phase=loop",
|
|
258
255
|
psub_ms,
|
|
259
256
|
)
|
|
260
257
|
msg = await self._pubsub.get_message(ignore_subscribe_messages=True, timeout=0.5)
|
|
@@ -264,8 +261,8 @@ class SharedRedisListener:
|
|
|
264
261
|
route_task_id, data, raw_json = parsed
|
|
265
262
|
pub_ns = data.get("published_at_ns") or 0
|
|
266
263
|
e2e_ms = (time.time_ns() - pub_ns) / 1e6 if pub_ns else 0.0
|
|
267
|
-
logger.
|
|
268
|
-
"[
|
|
264
|
+
logger.debug(
|
|
265
|
+
"[perf] signal_route: e2e_ms=%.2f action=%s task_id=%s",
|
|
269
266
|
e2e_ms,
|
|
270
267
|
data.get("action", ""),
|
|
271
268
|
route_task_id,
|
|
@@ -279,9 +276,6 @@ class SharedRedisListener:
|
|
|
279
276
|
if self._pubsub is not None:
|
|
280
277
|
with contextlib.suppress(Exception):
|
|
281
278
|
await self._pubsub.aclose()
|
|
282
|
-
logger.info(
|
|
283
|
-
"[VALIDATE D3a] closed stale pubsub before reconnect (backoff=%.1fs)", backoff
|
|
284
|
-
) # TODO(validate): remove after prod validation
|
|
285
279
|
self._pubsub = None
|
|
286
280
|
logger.exception("SharedRedisListener iteration error, retrying in %.1fs", backoff)
|
|
287
281
|
await asyncio.sleep(backoff)
|
|
@@ -290,8 +284,8 @@ class SharedRedisListener:
|
|
|
290
284
|
now = time.monotonic()
|
|
291
285
|
if now - self._last_counters_log >= 60.0: # noqa: PLR2004
|
|
292
286
|
c = self._counters
|
|
293
|
-
logger.
|
|
294
|
-
"[
|
|
287
|
+
logger.debug(
|
|
288
|
+
"[perf] signal_counters: origin=%s received=%d deduped=%d evicted=%d "
|
|
295
289
|
"dropped=%d listener_restarts=%d active_subs=%d subscribed_total=%d "
|
|
296
290
|
"invalidated=%d",
|
|
297
291
|
SharedRedisListener.PROCESS_ID,
|
|
@@ -72,10 +72,6 @@ class RemoteTaskManager(BaseTaskManager):
|
|
|
72
72
|
else:
|
|
73
73
|
# H2: this call never registered a session (e.g. duplicate task_id) —
|
|
74
74
|
# undo only THIS call's admission; never touch the live task.
|
|
75
|
-
logger.info(
|
|
76
|
-
"[VALIDATE H2] remote create rejected without touching live task: '%s'",
|
|
77
|
-
task_id,
|
|
78
|
-
) # TODO(validate): remove after prod validation
|
|
79
75
|
self._release_admission()
|
|
80
76
|
logger.exception(
|
|
81
77
|
"Failed to register remote task: '%s'",
|
{digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/core/task_manager/task_session.py
RENAMED
|
@@ -208,8 +208,8 @@ class TaskSession:
|
|
|
208
208
|
pub_ns = self.last_signal_published_ns
|
|
209
209
|
e2e_ms = (time.time_ns() - pub_ns) / 1e6 if pub_ns else 0.0
|
|
210
210
|
self.last_signal_published_ns = 0
|
|
211
|
-
logger.
|
|
212
|
-
"[
|
|
211
|
+
logger.debug(
|
|
212
|
+
"[perf] signal_handle: handler=cancel reason=%s e2e_ms=%.2f "
|
|
213
213
|
"body_ms=%.2f ack_send_ms=%.2f ack_ok=%s task_id=%s",
|
|
214
214
|
reason.value,
|
|
215
215
|
e2e_ms,
|
|
@@ -263,8 +263,8 @@ class TaskSession:
|
|
|
263
263
|
pub_ns = self.last_signal_published_ns
|
|
264
264
|
e2e_ms = (time.time_ns() - pub_ns) / 1e6 if pub_ns else 0.0
|
|
265
265
|
self.last_signal_published_ns = 0
|
|
266
|
-
logger.
|
|
267
|
-
"[
|
|
266
|
+
logger.debug(
|
|
267
|
+
"[perf] signal_handle: handler=stop reason=%s e2e_ms=%.2f "
|
|
268
268
|
"body_ms=%.2f ack_send_ms=%.2f ack_ok=%s task_id=%s",
|
|
269
269
|
CancellationReason.SIGNAL_SERVICE_STOP.value,
|
|
270
270
|
e2e_ms,
|
{digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/gateway_servicer.py
RENAMED
|
@@ -7,7 +7,6 @@ import contextlib
|
|
|
7
7
|
import json
|
|
8
8
|
import random
|
|
9
9
|
import time
|
|
10
|
-
import uuid
|
|
11
10
|
from datetime import datetime, timezone
|
|
12
11
|
from typing import TYPE_CHECKING, Any
|
|
13
12
|
|
|
@@ -159,44 +158,15 @@ class GatewayServicer:
|
|
|
159
158
|
await self._m2m.stop()
|
|
160
159
|
await self._registry.shutdown()
|
|
161
160
|
|
|
162
|
-
async def AssociateTask(
|
|
163
|
-
|
|
164
|
-
request: Any,
|
|
165
|
-
context: grpc.aio.ServicerContext, # noqa: ARG002
|
|
166
|
-
) -> Any:
|
|
167
|
-
"""Mint a sub-task id linked to a running parent task.
|
|
161
|
+
async def AssociateTask(self, request: Any, context: grpc.aio.ServicerContext) -> Any: # noqa: ARG002, PLR6301
|
|
162
|
+
"""Not served by the SDK — the backend mints sub-tasks.
|
|
168
163
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
context: gRPC service context.
|
|
172
|
-
|
|
173
|
-
Returns:
|
|
174
|
-
AssociateTaskResponse(task_id, parent_task_id); empty ``task_id`` on rejection.
|
|
164
|
+
Present only so the generated ``add_GatewayServiceServicer_to_server`` finds all
|
|
165
|
+
four RPCs; nothing dials the module for it. Callers use the backend endpoint.
|
|
175
166
|
"""
|
|
176
|
-
|
|
177
|
-
err = GatewayValidator.validate_id(parent_task_id, "parent_task_id")
|
|
178
|
-
if err is not None:
|
|
179
|
-
logger.warning("AssociateTask rejected: %s", err)
|
|
180
|
-
return gateway_pb2.AssociateTaskResponse(task_id="", parent_task_id=parent_task_id)
|
|
181
|
-
|
|
182
|
-
child_task_id = str(uuid.uuid4())
|
|
183
|
-
ttl = get_gateway_settings().stream.redis_stream_initial_ttl
|
|
184
|
-
try:
|
|
185
|
-
await self._redis_client.sadd(f"task:{parent_task_id}:children", child_task_id)
|
|
186
|
-
await self._redis_client.expire(f"task:{parent_task_id}:children", ttl)
|
|
187
|
-
await self._redis_client.set(f"task:{child_task_id}:parent", parent_task_id, ex=ttl)
|
|
188
|
-
except RedisError:
|
|
189
|
-
logger.warning(
|
|
190
|
-
"[VALIDATE AT1] AssociateTask persist failed parent=%s → task_id=''",
|
|
191
|
-
parent_task_id,
|
|
192
|
-
exc_info=True,
|
|
193
|
-
) # TODO(validate): remove after prod validation
|
|
194
|
-
return gateway_pb2.AssociateTaskResponse(task_id="", parent_task_id=parent_task_id)
|
|
195
|
-
|
|
196
|
-
logger.info("AssociateTask: parent=%s child=%s", parent_task_id, child_task_id)
|
|
197
|
-
return gateway_pb2.AssociateTaskResponse(task_id=child_task_id, parent_task_id=parent_task_id)
|
|
167
|
+
await context.abort(grpc.StatusCode.UNIMPLEMENTED, "AssociateTask is served by the backend")
|
|
198
168
|
|
|
199
|
-
async def StartStream( # noqa: PLR0911
|
|
169
|
+
async def StartStream( # noqa: PLR0911
|
|
200
170
|
self,
|
|
201
171
|
request: Any,
|
|
202
172
|
context: grpc.aio.ServicerContext,
|
|
@@ -247,11 +217,6 @@ class GatewayServicer:
|
|
|
247
217
|
return gateway_pb2.StartStreamResponse(accepted=False, task_id=task_id)
|
|
248
218
|
|
|
249
219
|
if self._registry.get(task_id) is not None:
|
|
250
|
-
logger.info(
|
|
251
|
-
"[VALIDATE RD1] StartStream refused: a dial is already live for task_id=%s",
|
|
252
|
-
task_id,
|
|
253
|
-
extra=log_extra,
|
|
254
|
-
) # TODO(validate): remove after prod validation
|
|
255
220
|
return gateway_pb2.StartStreamResponse(accepted=False, task_id=task_id)
|
|
256
221
|
timer.mark("dedup_check")
|
|
257
222
|
|
|
@@ -262,20 +227,9 @@ class GatewayServicer:
|
|
|
262
227
|
try:
|
|
263
228
|
claim = await self._idempotency.claim(task_id, SharedRedisListener.PROCESS_ID)
|
|
264
229
|
except RedisError:
|
|
265
|
-
logger.warning(
|
|
266
|
-
"[VALIDATE R2] StartStream claim Redis failure → accepted=False",
|
|
267
|
-
extra=log_extra,
|
|
268
|
-
exc_info=True,
|
|
269
|
-
) # TODO(validate): remove after prod validation
|
|
270
230
|
return gateway_pb2.StartStreamResponse(accepted=False, task_id=task_id)
|
|
271
231
|
timer.mark("idempotency_claim")
|
|
272
232
|
if claim is not ClaimResult.CLAIMED:
|
|
273
|
-
logger.info(
|
|
274
|
-
"[VALIDATE RD1] StartStream refused: task already claimed/running task_id=%s (%s)",
|
|
275
|
-
task_id,
|
|
276
|
-
claim.name,
|
|
277
|
-
extra=log_extra,
|
|
278
|
-
) # TODO(validate): remove after prod validation
|
|
279
233
|
return gateway_pb2.StartStreamResponse(accepted=False, task_id=task_id)
|
|
280
234
|
|
|
281
235
|
session = StreamSession(task_id=task_id)
|
|
@@ -310,11 +264,6 @@ class GatewayServicer:
|
|
|
310
264
|
{"pb": start_info.SerializeToString(), "seq": "0"},
|
|
311
265
|
)
|
|
312
266
|
except RedisError:
|
|
313
|
-
logger.warning(
|
|
314
|
-
"[VALIDATE R2] StartStream xadd(stream.start) Redis failure → accepted=False",
|
|
315
|
-
extra=log_extra,
|
|
316
|
-
exc_info=True,
|
|
317
|
-
) # TODO(validate): remove after prod validation
|
|
318
267
|
# Claimed + registered but the stream couldn't be seeded: undo both so a retry re-runs.
|
|
319
268
|
with contextlib.suppress(RedisError):
|
|
320
269
|
await self._idempotency.release(task_id)
|
|
@@ -571,8 +520,8 @@ class GatewayServicer:
|
|
|
571
520
|
extra=log_extra,
|
|
572
521
|
exc_info=True,
|
|
573
522
|
)
|
|
574
|
-
logger.
|
|
575
|
-
"[
|
|
523
|
+
logger.debug(
|
|
524
|
+
"[perf] SendSignal: %s path=cache total=%.2fms action=%s setup_id=%s",
|
|
576
525
|
timer.format_steps(),
|
|
577
526
|
timer.total_ms(),
|
|
578
527
|
action_name,
|
|
@@ -618,8 +567,8 @@ class GatewayServicer:
|
|
|
618
567
|
await self._redis_client.publish(f"signal_ch:{task_id}", payload)
|
|
619
568
|
timer.mark("redis_publish")
|
|
620
569
|
last_mark = "redis_publish"
|
|
621
|
-
logger.
|
|
622
|
-
"[
|
|
570
|
+
logger.debug(
|
|
571
|
+
"[perf] SendSignal: %s path=redis total=%.2fms action=%s task_id=%s",
|
|
623
572
|
timer.format_steps(),
|
|
624
573
|
timer.total_ms(),
|
|
625
574
|
action_name,
|
|
@@ -728,12 +677,6 @@ class GatewayServicer:
|
|
|
728
677
|
except StopAsyncIteration:
|
|
729
678
|
return
|
|
730
679
|
except asyncio.TimeoutError:
|
|
731
|
-
logger.warning(
|
|
732
|
-
"[VALIDATE B1] stream read idle %.0fs with no EOS (producer likely died) — "
|
|
733
|
-
"closing stream: task_id=%s",
|
|
734
|
-
idle,
|
|
735
|
-
task_id,
|
|
736
|
-
) # TODO(validate): remove after prod validation
|
|
737
680
|
yield self._sentinel(
|
|
738
681
|
0,
|
|
739
682
|
task_id,
|
|
@@ -745,10 +688,6 @@ class GatewayServicer:
|
|
|
745
688
|
yield self._sentinel(0, task_id, "stream.end")
|
|
746
689
|
return
|
|
747
690
|
except RedisError:
|
|
748
|
-
logger.warning(
|
|
749
|
-
"[VALIDATE R2] stream read Redis failure — closing stream: task_id=%s",
|
|
750
|
-
task_id,
|
|
751
|
-
) # TODO(validate): remove after prod validation
|
|
752
691
|
yield self._sentinel(
|
|
753
692
|
0,
|
|
754
693
|
task_id,
|
|
@@ -829,21 +768,9 @@ class GatewayServicer:
|
|
|
829
768
|
if deadline is None:
|
|
830
769
|
deadline = now + reconnect.window_s
|
|
831
770
|
if now >= deadline:
|
|
832
|
-
logger.info(
|
|
833
|
-
"[VALIDATE RD1] dial-back gave up after %.0fs reconnect window: task_id=%s attempts=%d",
|
|
834
|
-
reconnect.window_s,
|
|
835
|
-
task_id,
|
|
836
|
-
attempt,
|
|
837
|
-
) # TODO(validate): remove after prod validation
|
|
838
771
|
break
|
|
839
772
|
attempt += 1
|
|
840
773
|
delay = min(random.uniform(reconnect.backoff_base_s, reconnect.backoff_max_s), deadline - now) # noqa: S311
|
|
841
|
-
logger.info(
|
|
842
|
-
"[VALIDATE RD1] dial-back disconnected — re-dial attempt %d in %.1fs (resume): task_id=%s",
|
|
843
|
-
attempt,
|
|
844
|
-
delay,
|
|
845
|
-
task_id,
|
|
846
|
-
) # TODO(validate): remove after prod validation
|
|
847
774
|
await asyncio.sleep(max(0.0, delay))
|
|
848
775
|
resume = True
|
|
849
776
|
finally:
|
|
@@ -1028,11 +955,6 @@ class GatewayServicer:
|
|
|
1028
955
|
)
|
|
1029
956
|
return
|
|
1030
957
|
except RedisError:
|
|
1031
|
-
logger.warning(
|
|
1032
|
-
"[VALIDATE R2] dial-back stream read Redis failure — closing BiDi: task_id=%s",
|
|
1033
|
-
task_id,
|
|
1034
|
-
extra=log_extra,
|
|
1035
|
-
) # TODO(validate): remove after prod validation
|
|
1036
958
|
for sc in (
|
|
1037
959
|
self._sentinel(
|
|
1038
960
|
0,
|
|
@@ -1101,14 +1023,6 @@ class GatewayServicer:
|
|
|
1101
1023
|
if first and resume:
|
|
1102
1024
|
limit = get_gateway_settings().stream.from_seq_limit
|
|
1103
1025
|
resume_cursor = min(upstream.from_seq, limit)
|
|
1104
|
-
if upstream.from_seq > limit:
|
|
1105
|
-
logger.warning(
|
|
1106
|
-
"[VALIDATE RESUME1] resume cursor %d exceeds limit %d, clamped: task_id=%s",
|
|
1107
|
-
upstream.from_seq,
|
|
1108
|
-
limit,
|
|
1109
|
-
task_id,
|
|
1110
|
-
extra=log_extra,
|
|
1111
|
-
) # TODO(validate): remove after prod validation
|
|
1112
1026
|
logger.info(
|
|
1113
1027
|
"← Consumer resume cursor=%d received — resuming output (no re-run)",
|
|
1114
1028
|
resume_cursor,
|
|
@@ -1147,18 +1061,11 @@ class GatewayServicer:
|
|
|
1147
1061
|
first = False
|
|
1148
1062
|
continue
|
|
1149
1063
|
# Follow-up multi-turn input → task's input stream.
|
|
1150
|
-
|
|
1064
|
+
with contextlib.suppress(RedisError):
|
|
1151
1065
|
await self._redis_client.xadd(
|
|
1152
1066
|
f"task:{task_id}:input",
|
|
1153
1067
|
{"pb": upstream.data.SerializeToString()},
|
|
1154
1068
|
)
|
|
1155
|
-
except RedisError:
|
|
1156
|
-
logger.warning(
|
|
1157
|
-
"[VALIDATE R2] dropped follow-up input (redis unavailable): task_id=%s data=%s",
|
|
1158
|
-
task_id,
|
|
1159
|
-
str(upstream.data)[:512],
|
|
1160
|
-
extra=log_extra,
|
|
1161
|
-
) # TODO(validate): remove after prod validation
|
|
1162
1069
|
except grpc.aio.AioRpcError as exc:
|
|
1163
1070
|
code_name = exc.code().name
|
|
1164
1071
|
details = exc.details() or ""
|
{digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/m2m_call_registry.py
RENAMED
|
@@ -83,10 +83,7 @@ class M2MCallRegistry:
|
|
|
83
83
|
)
|
|
84
84
|
self._breakers[target_key] = breaker
|
|
85
85
|
if len(self._breakers) > 256: # noqa: PLR2004
|
|
86
|
-
|
|
87
|
-
logger.info(
|
|
88
|
-
"[VALIDATE D4] evicted LRU m2m breaker target=%s", evicted
|
|
89
|
-
) # TODO(validate): remove after prod validation
|
|
86
|
+
self._breakers.popitem(last=False)
|
|
90
87
|
return breaker
|
|
91
88
|
|
|
92
89
|
async def acquire_slot(self) -> None:
|
|
@@ -222,10 +219,6 @@ class M2MCallRegistry:
|
|
|
222
219
|
is_fatal = fatal_field is not None and fatal_field.bool_value
|
|
223
220
|
if is_fatal:
|
|
224
221
|
# M2: breaker outcome recorded only in call_module (was double-counted here).
|
|
225
|
-
logger.warning(
|
|
226
|
-
"[VALIDATE M2] fatal dial-back; breaker recorded only in call_module: task_id=%s",
|
|
227
|
-
task_id,
|
|
228
|
-
) # TODO(validate): remove after prod validation
|
|
229
222
|
return
|
|
230
223
|
finally:
|
|
231
224
|
with contextlib.suppress(asyncio.QueueFull):
|
{digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/module_server.py
RENAMED
|
@@ -197,9 +197,6 @@ class ModuleServer(BaseServer):
|
|
|
197
197
|
from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
|
|
198
198
|
|
|
199
199
|
# M9: close channels (resets ref_counts, clears stubs + breakers) instead of a bare cache clear.
|
|
200
|
-
logger.info(
|
|
201
|
-
"[VALIDATE M9] closing all cached gRPC channels on INVALIDATE_CHANNELS"
|
|
202
|
-
) # TODO(validate): remove after prod validation
|
|
203
200
|
await GrpcClientWrapper.close_all_cached_channels()
|
|
204
201
|
Bulkhead.clear_all()
|
|
205
202
|
|
|
@@ -331,7 +328,6 @@ class ModuleServer(BaseServer):
|
|
|
331
328
|
if self._gateway_redis_client is not None:
|
|
332
329
|
# M8: this server created the gateway's Redis client, so it closes it (owner closes;
|
|
333
330
|
# the gateway only borrows). Pools were leaked on every server stop.
|
|
334
|
-
logger.info("[VALIDATE M8] closing gateway Redis pools") # TODO(validate): remove after prod validation
|
|
335
331
|
try:
|
|
336
332
|
await self._gateway_redis_client.close()
|
|
337
333
|
except Exception:
|
{digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/module_servicer.py
RENAMED
|
@@ -21,6 +21,7 @@ from digitalkin.core.job_manager.base_job_manager import BaseJobManager
|
|
|
21
21
|
from digitalkin.core.job_manager.single_job_manager import SingleJobManager
|
|
22
22
|
from digitalkin.core.task_manager.redis.redis_signal import SharedRedisListener
|
|
23
23
|
from digitalkin.grpc_servers.exceptions import PermissionDeniedError, ServicerError
|
|
24
|
+
from digitalkin.grpc_servers.interceptors.request_ids import RequestContext
|
|
24
25
|
from digitalkin.logger import logger
|
|
25
26
|
from digitalkin.models.module.module import ModuleCodeModel
|
|
26
27
|
from digitalkin.models.module.setup_types import SetupModel
|
|
@@ -116,7 +117,6 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
116
117
|
except Exception:
|
|
117
118
|
logger.exception("Error closing GrpcUserProfile channel")
|
|
118
119
|
# M8: close the Redis connection pools (were leaked on every server stop).
|
|
119
|
-
logger.info("[VALIDATE M8] closing module servicer Redis pools") # TODO(validate): remove after prod validation
|
|
120
120
|
await self._redis_client.close()
|
|
121
121
|
|
|
122
122
|
if isinstance(self._registry_cache, GrpcRegistry):
|
|
@@ -253,7 +253,12 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
253
253
|
|
|
254
254
|
from digitalkin.services.communication.grpc_communication import GrpcCommunication
|
|
255
255
|
|
|
256
|
-
|
|
256
|
+
gateway_backend_config = (self.module_class.services_config_params.get("user_profile") or {}).get(
|
|
257
|
+
"client_config"
|
|
258
|
+
)
|
|
259
|
+
self._communication_cache = GrpcCommunication(
|
|
260
|
+
"", "", "", client_config, gateway_backend_config=gateway_backend_config
|
|
261
|
+
)
|
|
257
262
|
return self._communication_cache
|
|
258
263
|
|
|
259
264
|
def _cache_setup(self, setup_id: str, version_data: SetupVersionData) -> None:
|
|
@@ -272,9 +277,17 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
272
277
|
Raises:
|
|
273
278
|
PermissionDeniedError: If access to the setup is denied.
|
|
274
279
|
"""
|
|
275
|
-
|
|
280
|
+
allowed = await self.user_profile.check_resource_access(user_profile_pb2.RESOURCE_TYPE_SETUP, setup_id)
|
|
281
|
+
ids = RequestContext.current()
|
|
282
|
+
if not allowed:
|
|
283
|
+
logger.info(
|
|
284
|
+
"[VALIDATE AC1] setup access DENIED: setup_id=%s", setup_id, extra=ids
|
|
285
|
+
) # TODO(validate): remove after prod validation
|
|
276
286
|
msg = f"access denied to setup {setup_id}"
|
|
277
287
|
raise PermissionDeniedError(msg)
|
|
288
|
+
logger.info(
|
|
289
|
+
"[VALIDATE AC1] setup access granted: setup_id=%s", setup_id, extra=ids
|
|
290
|
+
) # TODO(validate): remove after prod validation
|
|
278
291
|
|
|
279
292
|
async def resolve_setup(self, setup_id: str, mission_id: str) -> SetupVersionData:
|
|
280
293
|
"""Return setup version data from cache or remote service.
|
|
@@ -362,6 +375,9 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
362
375
|
if not await self.user_profile.check_resource_access(
|
|
363
376
|
user_profile_pb2.RESOURCE_TYPE_SETUP, setup_version.setup_id
|
|
364
377
|
):
|
|
378
|
+
logger.info(
|
|
379
|
+
"[VALIDATE AC1] setup config access DENIED: setup_id=%s", setup_version.setup_id
|
|
380
|
+
) # TODO(validate): remove after prod validation
|
|
365
381
|
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
|
|
366
382
|
context.set_details(f"access denied to setup {setup_version.setup_id}")
|
|
367
383
|
return lifecycle_pb2.ConfigSetupModuleResponse(success=False)
|
{digitalkin-1.0.0.dev23 → digitalkin-1.0.0.dev25}/src/digitalkin/grpc_servers/stream_registry.py
RENAMED
|
@@ -76,11 +76,6 @@ class StreamRegistry:
|
|
|
76
76
|
settings = get_gateway_settings()
|
|
77
77
|
if len(self._local_cache) >= settings.max_streams:
|
|
78
78
|
# H3: reject at capacity instead of evicting a live session.
|
|
79
|
-
logger.info(
|
|
80
|
-
"[VALIDATE H3] stream registry at capacity (%d), rejecting task_id=%s",
|
|
81
|
-
settings.max_streams,
|
|
82
|
-
session.task_id,
|
|
83
|
-
) # TODO(validate): remove after prod validation
|
|
84
79
|
return False
|
|
85
80
|
|
|
86
81
|
self._local_cache[session.task_id] = session
|
|
@@ -225,11 +225,12 @@ class GrpcClientWrapper:
|
|
|
225
225
|
cls._stub_cache.clear()
|
|
226
226
|
CircuitBreaker.clear_all()
|
|
227
227
|
|
|
228
|
-
async def exec_grpc_query( # noqa:
|
|
228
|
+
async def exec_grpc_query( # noqa: PLR0914
|
|
229
229
|
self,
|
|
230
230
|
query_endpoint: str,
|
|
231
231
|
request: Any,
|
|
232
232
|
timeout: float | None = None,
|
|
233
|
+
metadata: tuple[tuple[str, str], ...] | None = None,
|
|
233
234
|
) -> Any:
|
|
234
235
|
"""Execute a gRPC query with circuit breaker protection and retry.
|
|
235
236
|
|
|
@@ -245,6 +246,8 @@ class GrpcClientWrapper:
|
|
|
245
246
|
query_endpoint: rpc query name (e.g., "GetSetup", "CreateSetupVersion")
|
|
246
247
|
request: gRPC protobuf request object
|
|
247
248
|
timeout: Per-call timeout in seconds. ``None`` applies no client-side deadline.
|
|
249
|
+
metadata: Optional gRPC metadata pairs (e.g. an idempotency key); the same
|
|
250
|
+
metadata is sent on every retry attempt.
|
|
248
251
|
|
|
249
252
|
Returns:
|
|
250
253
|
gRPC protobuf response object.
|
|
@@ -256,11 +259,6 @@ class GrpcClientWrapper:
|
|
|
256
259
|
if rpc_method is None:
|
|
257
260
|
# M3: validate the method before claiming the half-open probe lock,
|
|
258
261
|
# so a missing method can't escape cb.check() and wedge the breaker.
|
|
259
|
-
logger.info(
|
|
260
|
-
"[VALIDATE M3] RPC method missing, raised before breaker probe: %s.%s",
|
|
261
|
-
self.service_name,
|
|
262
|
-
query_endpoint,
|
|
263
|
-
) # TODO(validate): remove after prod validation
|
|
264
262
|
msg = f"[gRPC-client:{self.service_name}] RPC method '{query_endpoint}' not found on stub"
|
|
265
263
|
raise ServerError(msg)
|
|
266
264
|
|
|
@@ -273,13 +271,6 @@ class GrpcClientWrapper:
|
|
|
273
271
|
|
|
274
272
|
grpc_settings = get_grpc_client_settings()
|
|
275
273
|
eff_timeout = timeout if timeout is not None else grpc_settings.timeout
|
|
276
|
-
if timeout is None:
|
|
277
|
-
logger.info(
|
|
278
|
-
"[VALIDATE H1] default gRPC deadline applied: %.1fs (%s.%s)",
|
|
279
|
-
eff_timeout,
|
|
280
|
-
self.service_name,
|
|
281
|
-
query_endpoint,
|
|
282
|
-
) # TODO(validate): remove after prod validation
|
|
283
274
|
max_retries = grpc_settings.max_retries
|
|
284
275
|
backoff_base_ms = grpc_settings.backoff_base_ms
|
|
285
276
|
backoff_delays = tuple(backoff_base_ms / 1000 * (2**i) for i in range(max_retries))
|
|
@@ -291,7 +282,7 @@ class GrpcClientWrapper:
|
|
|
291
282
|
await asyncio.sleep(backoff_delays[attempt - 1])
|
|
292
283
|
|
|
293
284
|
try:
|
|
294
|
-
response = await rpc_method(request, timeout=eff_timeout)
|
|
285
|
+
response = await rpc_method(request, timeout=eff_timeout, metadata=metadata)
|
|
295
286
|
except grpc.RpcError as e:
|
|
296
287
|
last_error = e
|
|
297
288
|
if e.code() in self._RETRYABLE_CODES and attempt < max_retries:
|
|
@@ -342,9 +333,4 @@ class GrpcClientWrapper:
|
|
|
342
333
|
raise ServerError(error_msg) from last_error
|
|
343
334
|
finally:
|
|
344
335
|
# Free a half-open probe the loop never resolved (e.g. CancelledError mid-call or backoff).
|
|
345
|
-
|
|
346
|
-
logger.info(
|
|
347
|
-
"[VALIDATE R1] released abandoned circuit probe: %s.%s",
|
|
348
|
-
self.service_name,
|
|
349
|
-
query_endpoint,
|
|
350
|
-
) # TODO(validate): remove after prod validation
|
|
336
|
+
cb.release_probe()
|
|
@@ -197,9 +197,6 @@ class LoggerFactory:
|
|
|
197
197
|
return
|
|
198
198
|
if any(isinstance(h, RotatingFileHandler) for h in logger.handlers):
|
|
199
199
|
# Low: idempotent — repeated setup_logger() calls must not stack handlers.
|
|
200
|
-
logger.debug(
|
|
201
|
-
"[VALIDATE Low-loghandler] file handler already attached, skipping"
|
|
202
|
-
) # TODO(validate): remove after prod validation
|
|
203
200
|
return
|
|
204
201
|
|
|
205
202
|
log_file = settings.file or os.path.join(log_dir, f"{logger.name}.log")
|
|
@@ -30,7 +30,6 @@ from ag_ui.core.events import ToolCallEndEvent as AgUiToolCallEndEvent
|
|
|
30
30
|
from ag_ui.core.events import ToolCallResultEvent as AgUiToolCallResultEvent
|
|
31
31
|
from ag_ui.core.events import ToolCallStartEvent as AgUiToolCallStartEvent
|
|
32
32
|
|
|
33
|
-
from digitalkin.logger import logger
|
|
34
33
|
from digitalkin.models.events import (
|
|
35
34
|
AgentRunEvent,
|
|
36
35
|
BaseAgentRunEvent,
|
|
@@ -408,9 +407,6 @@ class AgUiMixin:
|
|
|
408
407
|
event: CustomEvent,
|
|
409
408
|
) -> None:
|
|
410
409
|
"""Handle custom event - emit AG-UI CustomEvent."""
|
|
411
|
-
logger.info(
|
|
412
|
-
"[VALIDATE M15] CustomEvent dispatched via AG-UI: name=%s", event.name
|
|
413
|
-
) # TODO(validate): remove after prod validation
|
|
414
410
|
from ag_ui.core.events import CustomEvent as AgUiCustomEvent # pylint: disable=C0415
|
|
415
411
|
|
|
416
412
|
from digitalkin.models.module.ag_ui import AgUiCustomEventOutput # pylint: disable=C0415
|