digitalkin 1.0.0.dev21__tar.gz → 1.0.0.dev23__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.dev21 → digitalkin-1.0.0.dev23}/PKG-INFO +2 -2
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/pyproject.toml +2 -2
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/__version__.py +1 -1
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/module_runner.py +4 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/gateway_servicer.py +38 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/module_servicer.py +40 -1
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/grpc_servers/stream_error_codes.py +1 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/module_context.py +6 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/communication/grpc_communication.py +35 -11
- digitalkin-1.0.0.dev23/src/digitalkin/services/secret/__init__.py +13 -0
- digitalkin-1.0.0.dev23/src/digitalkin/services/secret/default_secret.py +45 -0
- digitalkin-1.0.0.dev23/src/digitalkin/services/secret/exceptions.py +5 -0
- digitalkin-1.0.0.dev23/src/digitalkin/services/secret/grpc_secret.py +63 -0
- digitalkin-1.0.0.dev23/src/digitalkin/services/secret/secret_strategy.py +21 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/services_config.py +14 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/services_models.py +2 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/user_profile/default_user_profile.py +12 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/user_profile/grpc_user_profile.py +22 -1
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/user_profile/user_profile_strategy.py +15 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin.egg-info/PKG-INFO +2 -2
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin.egg-info/SOURCES.txt +5 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin.egg-info/requires.txt +1 -1
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/LICENSE +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/README.md +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/base_server/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/echo_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/models/input.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/models/output.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/models/secret.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/models/setup.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/server.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/bench_module/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/modules/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/modules/archetype_with_tools_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/monitoring/tests/test_metrics.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/client.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/echo_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/models/input.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/models/output.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/models/secret.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/models/setup.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/server.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/redis_demo/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/services/filesystem_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/examples/services/storage_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/setup.cfg +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/community/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/community/agno/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/community/agno/agno_adapter.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/community/agno/agui_tools.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/community/agno/hitl.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/community/agno/models.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/common/factories.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/profiling/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/profiling/step_timer.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/profiling/task_profiler.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/resilience/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/resilience/bulkhead.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/task_executor.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/task_session.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/module_server.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/stream_session.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/logger.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/mixins/agui_mixin.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/mixins/cost_mixin.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/mixins/file_history_mixin.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/core/redis.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/core/task_monitor.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/events/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/events/agent_events.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/grpc_servers/models.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/ag_ui.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/request_metadata.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/select_schema.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/setup_types.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/tool_cache.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/tool_reference.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/utility.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/services/registry.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/services/services.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/gateway.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/grpc_client.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/log.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/profiling.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/queue.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/redis.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/resilience.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/server/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/server/channel.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/server/grpc.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/server/server.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/server/servicer.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/task_manager.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/settings/utils/channel.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/_base_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/archetype_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/tool_module.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/py.typed +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/communication/communication_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/communication/default_communication.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/communication/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/cost/cost_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/cost/default_cost.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/cost/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/cost/grpc_cost.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/filesystem/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/registry/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/registry/default_registry.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/registry/grpc_registry.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/registry/registry_models.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/registry/registry_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/setup/default_setup.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/setup/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/setup/grpc_setup.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/setup/setup_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/storage/default_storage.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/storage/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/storage/grpc_storage.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/storage/storage_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/task_manager/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/task_manager/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/user_profile/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/conditional_schema.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/exceptions.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/proto_utils.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/utils/schema_splitter.py +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin.egg-info/top_level.txt +0 -0
- {digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/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.dev23
|
|
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
|
|
@@ -453,7 +453,7 @@ Requires-Python: >=3.10
|
|
|
453
453
|
Description-Content-Type: text/markdown
|
|
454
454
|
License-File: LICENSE
|
|
455
455
|
Requires-Dist: ag-ui-protocol>=0.1.18
|
|
456
|
-
Requires-Dist: agentic-mesh-protocol==1.0.
|
|
456
|
+
Requires-Dist: agentic-mesh-protocol==1.0.0a2
|
|
457
457
|
Requires-Dist: anyio>=4.13.0
|
|
458
458
|
Requires-Dist: grpcio-health-checking==1.81.0
|
|
459
459
|
Requires-Dist: grpcio-reflection==1.81.0
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
dependencies = [
|
|
30
30
|
"ag-ui-protocol>=0.1.18",
|
|
31
|
-
"agentic-mesh-protocol==1.0.
|
|
31
|
+
"agentic-mesh-protocol==1.0.0a2",
|
|
32
32
|
"anyio>=4.13.0",
|
|
33
33
|
"grpcio-health-checking==1.81.0",
|
|
34
34
|
"grpcio-reflection==1.81.0",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"pydantic-settings>=2.14.1",
|
|
38
38
|
"redis[hiredis]>=7.4.0,<9",
|
|
39
39
|
]
|
|
40
|
-
version = "1.0.0.
|
|
40
|
+
version = "1.0.0.dev23"
|
|
41
41
|
|
|
42
42
|
[project.optional-dependencies]
|
|
43
43
|
performance = [ "uvloop>=0.21" ]
|
{digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/core/task_manager/module_runner.py
RENAMED
|
@@ -13,6 +13,7 @@ from redis.exceptions import RedisError
|
|
|
13
13
|
from digitalkin.core.exceptions import BackpressureTimeoutError
|
|
14
14
|
from digitalkin.core.profiling.step_timer import StepTimer
|
|
15
15
|
from digitalkin.core.profiling.task_profiler import TaskProfiler
|
|
16
|
+
from digitalkin.grpc_servers.exceptions import PermissionDeniedError
|
|
16
17
|
from digitalkin.grpc_servers.interceptors.request_ids import RequestContext
|
|
17
18
|
from digitalkin.logger import logger
|
|
18
19
|
from digitalkin.models.grpc_servers.stream_error_codes import StreamErrorCode
|
|
@@ -226,6 +227,9 @@ class ModuleRunner:
|
|
|
226
227
|
StreamErrorCode.REDIS_UNAVAILABLE.value,
|
|
227
228
|
f"redis unavailable: {type(exc).__name__}: {exc}",
|
|
228
229
|
)
|
|
230
|
+
except PermissionDeniedError as exc:
|
|
231
|
+
logger.warning("ModuleRunner: setup access denied: %s", exc, extra=log_extra)
|
|
232
|
+
await on_fatal(StreamErrorCode.SETUP_ACCESS_DENIED.value, str(exc))
|
|
229
233
|
except Exception as exc:
|
|
230
234
|
logger.exception("ModuleRunner: module job failed", extra=log_extra)
|
|
231
235
|
await on_fatal(
|
{digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/gateway_servicer.py
RENAMED
|
@@ -7,6 +7,7 @@ import contextlib
|
|
|
7
7
|
import json
|
|
8
8
|
import random
|
|
9
9
|
import time
|
|
10
|
+
import uuid
|
|
10
11
|
from datetime import datetime, timezone
|
|
11
12
|
from typing import TYPE_CHECKING, Any
|
|
12
13
|
|
|
@@ -158,6 +159,43 @@ class GatewayServicer:
|
|
|
158
159
|
await self._m2m.stop()
|
|
159
160
|
await self._registry.shutdown()
|
|
160
161
|
|
|
162
|
+
async def AssociateTask(
|
|
163
|
+
self,
|
|
164
|
+
request: Any,
|
|
165
|
+
context: grpc.aio.ServicerContext, # noqa: ARG002
|
|
166
|
+
) -> Any:
|
|
167
|
+
"""Mint a sub-task id linked to a running parent task.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
request: AssociateTaskRequest proto.
|
|
171
|
+
context: gRPC service context.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
AssociateTaskResponse(task_id, parent_task_id); empty ``task_id`` on rejection.
|
|
175
|
+
"""
|
|
176
|
+
parent_task_id = request.parent_task_id
|
|
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)
|
|
198
|
+
|
|
161
199
|
async def StartStream( # noqa: PLR0911, PLR0915
|
|
162
200
|
self,
|
|
163
201
|
request: Any,
|
{digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/grpc_servers/module_servicer.py
RENAMED
|
@@ -14,12 +14,13 @@ from agentic_mesh_protocol.module.v1 import (
|
|
|
14
14
|
lifecycle_pb2,
|
|
15
15
|
module_service_pb2_grpc,
|
|
16
16
|
)
|
|
17
|
+
from agentic_mesh_protocol.user_profile.v1 import user_profile_pb2
|
|
17
18
|
from google.protobuf import json_format, struct_pb2
|
|
18
19
|
|
|
19
20
|
from digitalkin.core.job_manager.base_job_manager import BaseJobManager
|
|
20
21
|
from digitalkin.core.job_manager.single_job_manager import SingleJobManager
|
|
21
22
|
from digitalkin.core.task_manager.redis.redis_signal import SharedRedisListener
|
|
22
|
-
from digitalkin.grpc_servers.exceptions import ServicerError
|
|
23
|
+
from digitalkin.grpc_servers.exceptions import PermissionDeniedError, ServicerError
|
|
23
24
|
from digitalkin.logger import logger
|
|
24
25
|
from digitalkin.models.module.module import ModuleCodeModel
|
|
25
26
|
from digitalkin.models.module.setup_types import SetupModel
|
|
@@ -31,6 +32,7 @@ from digitalkin.services.registry import GrpcRegistry, RegistryStrategy
|
|
|
31
32
|
from digitalkin.services.setup.default_setup import DefaultSetup
|
|
32
33
|
from digitalkin.services.setup.grpc_setup import GrpcSetup
|
|
33
34
|
from digitalkin.services.setup.setup_strategy import SetupStrategy, SetupVersionData
|
|
35
|
+
from digitalkin.services.user_profile import DefaultUserProfile, GrpcUserProfile, UserProfileStrategy
|
|
34
36
|
from digitalkin.utils.arg_parser import ArgParser
|
|
35
37
|
from digitalkin.utils.development_mode_action import DevelopmentModeMappingAction
|
|
36
38
|
|
|
@@ -40,6 +42,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
40
42
|
|
|
41
43
|
args: Namespace
|
|
42
44
|
setup: SetupStrategy
|
|
45
|
+
user_profile: UserProfileStrategy
|
|
43
46
|
job_manager: BaseJobManager
|
|
44
47
|
_registry_cache: RegistryStrategy | None
|
|
45
48
|
_tool_cache_by_setup: dict[str, tuple[Any, float]]
|
|
@@ -82,6 +85,16 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
82
85
|
|
|
83
86
|
logger.debug("ModuleServicer initialized with SingleJobManager")
|
|
84
87
|
self.setup = GrpcSetup() if self.args.services_mode == ServicesMode.REMOTE else DefaultSetup()
|
|
88
|
+
# Access-control client gating the setup cache. Always built, always called (fail-closed).
|
|
89
|
+
if self.args.services_mode == ServicesMode.REMOTE:
|
|
90
|
+
up_cfg = self.module_class.services_config_params.get("user_profile") or {}
|
|
91
|
+
up_client_config = up_cfg.get("client_config")
|
|
92
|
+
if not up_client_config:
|
|
93
|
+
msg = "user_profile client_config is required for setup access control"
|
|
94
|
+
raise RuntimeError(msg)
|
|
95
|
+
self.user_profile = GrpcUserProfile("", "", "", up_client_config)
|
|
96
|
+
else:
|
|
97
|
+
self.user_profile = DefaultUserProfile("", "", "")
|
|
85
98
|
self._setup_cache: dict[str, tuple[float, SetupVersionData]] = {}
|
|
86
99
|
self._setup_inflight: dict[str, asyncio.Future[SetupVersionData]] = {}
|
|
87
100
|
|
|
@@ -97,6 +110,11 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
97
110
|
await self.setup.close_channel()
|
|
98
111
|
except Exception:
|
|
99
112
|
logger.exception("Error closing GrpcSetup channel")
|
|
113
|
+
if isinstance(self.user_profile, GrpcUserProfile):
|
|
114
|
+
try:
|
|
115
|
+
await self.user_profile.close_channel()
|
|
116
|
+
except Exception:
|
|
117
|
+
logger.exception("Error closing GrpcUserProfile channel")
|
|
100
118
|
# M8: close the Redis connection pools (were leaked on every server stop).
|
|
101
119
|
logger.info("[VALIDATE M8] closing module servicer Redis pools") # TODO(validate): remove after prod validation
|
|
102
120
|
await self._redis_client.close()
|
|
@@ -245,6 +263,19 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
245
263
|
del self._setup_cache[oldest_key]
|
|
246
264
|
self._setup_cache[setup_id] = (time.monotonic(), version_data)
|
|
247
265
|
|
|
266
|
+
async def _check_setup_access(self, setup_id: str) -> None:
|
|
267
|
+
"""Block if the caller may not access the setup (RESOURCE_TYPE_SETUP).
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
setup_id: The setup identifier being resolved.
|
|
271
|
+
|
|
272
|
+
Raises:
|
|
273
|
+
PermissionDeniedError: If access to the setup is denied.
|
|
274
|
+
"""
|
|
275
|
+
if not await self.user_profile.check_resource_access(user_profile_pb2.RESOURCE_TYPE_SETUP, setup_id):
|
|
276
|
+
msg = f"access denied to setup {setup_id}"
|
|
277
|
+
raise PermissionDeniedError(msg)
|
|
278
|
+
|
|
248
279
|
async def resolve_setup(self, setup_id: str, mission_id: str) -> SetupVersionData:
|
|
249
280
|
"""Return setup version data from cache or remote service.
|
|
250
281
|
|
|
@@ -257,7 +288,9 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
257
288
|
|
|
258
289
|
Raises:
|
|
259
290
|
LookupError: No setup data found for setup_id.
|
|
291
|
+
PermissionDeniedError: If the caller may not access this setup.
|
|
260
292
|
"""
|
|
293
|
+
await self._check_setup_access(setup_id)
|
|
261
294
|
# Fast path: cache hit within TTL
|
|
262
295
|
if (cached := self._setup_cache.get(setup_id)) is not None:
|
|
263
296
|
if time.monotonic() - cached[0] < get_module_servicer_settings().setup_cache_ttl:
|
|
@@ -326,6 +359,12 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
|
326
359
|
extra={"mission_id": request.mission_id},
|
|
327
360
|
)
|
|
328
361
|
setup_version = request.setup_version
|
|
362
|
+
if not await self.user_profile.check_resource_access(
|
|
363
|
+
user_profile_pb2.RESOURCE_TYPE_SETUP, setup_version.setup_id
|
|
364
|
+
):
|
|
365
|
+
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
|
|
366
|
+
context.set_details(f"access denied to setup {setup_version.setup_id}")
|
|
367
|
+
return lifecycle_pb2.ConfigSetupModuleResponse(success=False)
|
|
329
368
|
# Invalidate cached setup so concurrent/subsequent starts refetch the reconfigured version
|
|
330
369
|
self._setup_cache.pop(setup_version.setup_id, None)
|
|
331
370
|
config_setup_data = self.module_class.create_config_setup_model(json_format.MessageToDict(request.content))
|
{digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/models/module/module_context.py
RENAMED
|
@@ -17,6 +17,7 @@ from digitalkin.services.cost.cost_strategy import CostStrategy
|
|
|
17
17
|
from digitalkin.services.filesystem.filesystem_strategy import FilesystemStrategy
|
|
18
18
|
from digitalkin.services.identity.identity_strategy import IdentityStrategy
|
|
19
19
|
from digitalkin.services.registry.registry_strategy import RegistryStrategy
|
|
20
|
+
from digitalkin.services.secret.secret_strategy import SecretStrategy
|
|
20
21
|
from digitalkin.services.storage.storage_strategy import StorageStrategy
|
|
21
22
|
from digitalkin.services.task_manager.task_manager_strategy import TaskManagerStrategy
|
|
22
23
|
from digitalkin.services.user_profile.user_profile_strategy import UserProfileStrategy
|
|
@@ -95,6 +96,7 @@ class ModuleContext:
|
|
|
95
96
|
filesystem: FilesystemStrategy
|
|
96
97
|
identity: IdentityStrategy
|
|
97
98
|
registry: RegistryStrategy
|
|
99
|
+
secret: SecretStrategy
|
|
98
100
|
storage: StorageStrategy
|
|
99
101
|
task_manager: TaskManagerStrategy | None
|
|
100
102
|
user_profile: UserProfileStrategy
|
|
@@ -115,6 +117,7 @@ class ModuleContext:
|
|
|
115
117
|
filesystem: FilesystemStrategy,
|
|
116
118
|
identity: IdentityStrategy,
|
|
117
119
|
registry: RegistryStrategy,
|
|
120
|
+
secret: SecretStrategy,
|
|
118
121
|
storage: StorageStrategy,
|
|
119
122
|
user_profile: UserProfileStrategy,
|
|
120
123
|
session: dict[str, Any],
|
|
@@ -135,6 +138,7 @@ class ModuleContext:
|
|
|
135
138
|
filesystem: FilesystemStrategy.
|
|
136
139
|
identity: IdentityStrategy.
|
|
137
140
|
registry: RegistryStrategy.
|
|
141
|
+
secret: SecretStrategy.
|
|
138
142
|
storage: StorageStrategy.
|
|
139
143
|
user_profile: UserProfileStrategy.
|
|
140
144
|
task_manager: Optional, injected by SingleJobManager (RedisTaskManager).
|
|
@@ -153,6 +157,7 @@ class ModuleContext:
|
|
|
153
157
|
self.filesystem = filesystem
|
|
154
158
|
self.identity = identity
|
|
155
159
|
self.registry = registry
|
|
160
|
+
self.secret = secret
|
|
156
161
|
self.storage = storage
|
|
157
162
|
self.task_manager = task_manager
|
|
158
163
|
self.user_profile = user_profile
|
|
@@ -374,6 +379,7 @@ class ModuleContext:
|
|
|
374
379
|
("registry", self.registry),
|
|
375
380
|
("filesystem", self.filesystem),
|
|
376
381
|
("user_profile", self.user_profile),
|
|
382
|
+
("secret", self.secret),
|
|
377
383
|
("identity", self.identity),
|
|
378
384
|
)
|
|
379
385
|
for name, service in owned:
|
|
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import time
|
|
7
|
-
import uuid
|
|
8
7
|
from typing import TYPE_CHECKING, Any
|
|
9
8
|
|
|
10
9
|
import grpc.aio
|
|
@@ -16,6 +15,7 @@ from agentic_mesh_protocol.module.v1 import (
|
|
|
16
15
|
from google.protobuf import json_format, struct_pb2
|
|
17
16
|
|
|
18
17
|
from digitalkin.core.profiling.step_timer import StepTimer
|
|
18
|
+
from digitalkin.grpc_servers.interceptors.request_ids import RequestContext
|
|
19
19
|
from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
|
|
20
20
|
from digitalkin.grpc_servers.utils.validators import GatewayValidator
|
|
21
21
|
from digitalkin.logger import logger
|
|
@@ -315,8 +315,7 @@ class GrpcCommunication(CommunicationStrategy, GrpcClientWrapper):
|
|
|
315
315
|
"target_key": target_key,
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
task_id =
|
|
319
|
-
log_extra["task_id"] = task_id
|
|
318
|
+
task_id = ""
|
|
320
319
|
breaker = m2m.breaker_for(target_key)
|
|
321
320
|
|
|
322
321
|
last_mark = "init"
|
|
@@ -342,6 +341,38 @@ class GrpcCommunication(CommunicationStrategy, GrpcClientWrapper):
|
|
|
342
341
|
timer.mark("acquire_slot")
|
|
343
342
|
last_mark = "acquire_slot"
|
|
344
343
|
|
|
344
|
+
self._get_or_create_channel(module_address, module_port)
|
|
345
|
+
timer.mark("channel_create")
|
|
346
|
+
last_mark = "channel_create"
|
|
347
|
+
stub = self._get_or_create_stub(gateway_service_pb2_grpc.GatewayServiceStub)
|
|
348
|
+
timer.mark("stub_create")
|
|
349
|
+
last_mark = "stub_create"
|
|
350
|
+
|
|
351
|
+
# The gateway mints the sub-task id and links it to the running parent task.
|
|
352
|
+
try:
|
|
353
|
+
assoc = await stub.AssociateTask(
|
|
354
|
+
gateway_pb2.AssociateTaskRequest(
|
|
355
|
+
parent_task_id=RequestContext.current().get("task_id", ""),
|
|
356
|
+
),
|
|
357
|
+
)
|
|
358
|
+
except grpc.aio.AioRpcError as exc:
|
|
359
|
+
breaker.record_failure()
|
|
360
|
+
logger.warning(
|
|
361
|
+
"[m2m] AssociateTask failed: [%s] %s",
|
|
362
|
+
exc.code().name,
|
|
363
|
+
exc.details() or "",
|
|
364
|
+
extra=log_extra,
|
|
365
|
+
)
|
|
366
|
+
raise
|
|
367
|
+
task_id = assoc.task_id
|
|
368
|
+
if not task_id:
|
|
369
|
+
breaker.record_failure()
|
|
370
|
+
msg = f"target {target_key} returned no task_id from AssociateTask"
|
|
371
|
+
raise RuntimeError(msg) # noqa: TRY301
|
|
372
|
+
log_extra["task_id"] = task_id
|
|
373
|
+
timer.mark("associate_task")
|
|
374
|
+
last_mark = "associate_task"
|
|
375
|
+
|
|
345
376
|
output_queue: asyncio.Queue[struct_pb2.Struct | None] = asyncio.Queue(
|
|
346
377
|
maxsize=m2m_settings.call_queue_maxsize,
|
|
347
378
|
)
|
|
@@ -361,13 +392,6 @@ class GrpcCommunication(CommunicationStrategy, GrpcClientWrapper):
|
|
|
361
392
|
timer.mark("register")
|
|
362
393
|
last_mark = "register"
|
|
363
394
|
|
|
364
|
-
self._get_or_create_channel(module_address, module_port)
|
|
365
|
-
timer.mark("channel_create")
|
|
366
|
-
last_mark = "channel_create"
|
|
367
|
-
stub = self._get_or_create_stub(gateway_service_pb2_grpc.GatewayServiceStub)
|
|
368
|
-
timer.mark("stub_create")
|
|
369
|
-
last_mark = "stub_create"
|
|
370
|
-
|
|
371
395
|
try: # noqa: PLW0717
|
|
372
396
|
grpc_metadata: list[tuple[str, str]] = []
|
|
373
397
|
if metadata:
|
|
@@ -467,7 +491,7 @@ class GrpcCommunication(CommunicationStrategy, GrpcClientWrapper):
|
|
|
467
491
|
cancelled = True
|
|
468
492
|
raise
|
|
469
493
|
finally:
|
|
470
|
-
if cancelled and stub is not None:
|
|
494
|
+
if cancelled and stub is not None and task_id:
|
|
471
495
|
sig_t0 = time.perf_counter_ns()
|
|
472
496
|
sig_failure = ""
|
|
473
497
|
try:
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Secret service package."""
|
|
2
|
+
|
|
3
|
+
from digitalkin.services.secret.default_secret import DefaultSecret
|
|
4
|
+
from digitalkin.services.secret.exceptions import SecretServiceError
|
|
5
|
+
from digitalkin.services.secret.grpc_secret import GrpcSecret
|
|
6
|
+
from digitalkin.services.secret.secret_strategy import SecretStrategy
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"DefaultSecret",
|
|
10
|
+
"GrpcSecret",
|
|
11
|
+
"SecretServiceError",
|
|
12
|
+
"SecretStrategy",
|
|
13
|
+
]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Default secret implementation."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from digitalkin.logger import logger
|
|
6
|
+
from digitalkin.services.secret.secret_strategy import SecretStrategy
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DefaultSecret(SecretStrategy):
|
|
10
|
+
"""Default secret strategy with in-memory storage."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
mission_id: str,
|
|
15
|
+
setup_id: str,
|
|
16
|
+
setup_version_id: str,
|
|
17
|
+
) -> None:
|
|
18
|
+
"""Initialize the strategy.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
mission_id: The ID of the mission this strategy is associated with
|
|
22
|
+
setup_id: The ID of the setup
|
|
23
|
+
setup_version_id: The ID of the setup version
|
|
24
|
+
"""
|
|
25
|
+
super().__init__(mission_id=mission_id, setup_id=setup_id, setup_version_id=setup_version_id)
|
|
26
|
+
self.db: dict[str, dict[str, Any]] = {}
|
|
27
|
+
|
|
28
|
+
async def get_secret(self) -> dict[str, Any] | None:
|
|
29
|
+
"""Get the secret for this setup from in-memory storage.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Secret values, or None if not found.
|
|
33
|
+
"""
|
|
34
|
+
if self.setup_id not in self.db:
|
|
35
|
+
logger.warning("No secret found for setup_id: %s", self.setup_id)
|
|
36
|
+
return None
|
|
37
|
+
return self.db[self.setup_id]
|
|
38
|
+
|
|
39
|
+
def add_secret(self, secret_data: dict[str, Any]) -> None:
|
|
40
|
+
"""Add a secret to the in-memory database (helper for testing).
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
secret_data: Dictionary containing secret values.
|
|
44
|
+
"""
|
|
45
|
+
self.db[self.setup_id] = secret_data
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Digital Kin Secret Service gRPC Client (wraps UserProfileService.GetSetupSecret)."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from agentic_mesh_protocol.user_profile.v1 import (
|
|
6
|
+
user_profile_pb2,
|
|
7
|
+
user_profile_service_pb2_grpc,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
|
|
11
|
+
from digitalkin.grpc_servers.utils.grpc_error_handler import GrpcErrorHandlerMixin
|
|
12
|
+
from digitalkin.logger import logger
|
|
13
|
+
from digitalkin.models.grpc_servers.models import ClientConfig
|
|
14
|
+
from digitalkin.services.secret.exceptions import SecretServiceError
|
|
15
|
+
from digitalkin.services.secret.secret_strategy import SecretStrategy
|
|
16
|
+
from digitalkin.utils.proto_utils import ProtoUtils
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GrpcSecret(SecretStrategy, GrpcClientWrapper, GrpcErrorHandlerMixin):
|
|
20
|
+
"""gRPC client for setup secrets (backed by the UserProfileService)."""
|
|
21
|
+
|
|
22
|
+
service_name: str = "UserProfileService"
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
mission_id: str,
|
|
27
|
+
setup_id: str,
|
|
28
|
+
setup_version_id: str,
|
|
29
|
+
client_config: ClientConfig,
|
|
30
|
+
) -> None:
|
|
31
|
+
"""Initialize the secret service.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
mission_id: The ID of the mission this strategy is associated with
|
|
35
|
+
setup_id: The ID of the setup
|
|
36
|
+
setup_version_id: The ID of the setup version
|
|
37
|
+
client_config: Client configuration for gRPC connection
|
|
38
|
+
"""
|
|
39
|
+
super().__init__(mission_id=mission_id, setup_id=setup_id, setup_version_id=setup_version_id)
|
|
40
|
+
self._init_channel(client_config)
|
|
41
|
+
self.stub = self._get_or_create_stub(user_profile_service_pb2_grpc.UserProfileServiceStub)
|
|
42
|
+
logger.debug("Channel client 'Secret' initialized successfully")
|
|
43
|
+
|
|
44
|
+
async def close(self) -> None:
|
|
45
|
+
"""Release this instance's pooled gRPC channel ref."""
|
|
46
|
+
await self.close_channel()
|
|
47
|
+
|
|
48
|
+
async def get_secret(self) -> dict[str, Any] | None:
|
|
49
|
+
"""Resolve the secret object attached to this setup.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
The secret values, or None if not found.
|
|
53
|
+
|
|
54
|
+
Raises:
|
|
55
|
+
SecretServiceError: If the gRPC operation fails.
|
|
56
|
+
"""
|
|
57
|
+
async with self.handle_grpc_errors("GetSetupSecret", SecretServiceError):
|
|
58
|
+
request = user_profile_pb2.GetSetupSecretRequest(setup_id=self.setup_id, mission_id=self.mission_id)
|
|
59
|
+
response = await self.exec_grpc_query("GetSetupSecret", request)
|
|
60
|
+
if not response.success:
|
|
61
|
+
logger.warning("No secret found for setup_id: %s", self.setup_id)
|
|
62
|
+
return None
|
|
63
|
+
return ProtoUtils.proto_to_dict(response.secret, with_defaults=True)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""This module contains the abstract base class for Secret strategies."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from digitalkin.services.base_strategy import BaseStrategy
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SecretStrategy(BaseStrategy, ABC):
|
|
10
|
+
"""Abstract base class for Secret strategies."""
|
|
11
|
+
|
|
12
|
+
@abstractmethod
|
|
13
|
+
async def get_secret(self) -> dict[str, Any] | None:
|
|
14
|
+
"""Resolve the secret object attached to this setup.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
The secret values (matching the module's secret_schema), or None if not found.
|
|
18
|
+
|
|
19
|
+
Raises:
|
|
20
|
+
SecretServiceError: If the service call fails.
|
|
21
|
+
"""
|
{digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/services_config.py
RENAMED
|
@@ -10,6 +10,7 @@ from digitalkin.services.cost import CostStrategy, DefaultCost, GrpcCost
|
|
|
10
10
|
from digitalkin.services.filesystem import DefaultFilesystem, FilesystemStrategy, GrpcFilesystem
|
|
11
11
|
from digitalkin.services.identity import DefaultIdentity, IdentityStrategy
|
|
12
12
|
from digitalkin.services.registry import DefaultRegistry, GrpcRegistry, RegistryStrategy
|
|
13
|
+
from digitalkin.services.secret import DefaultSecret, GrpcSecret, SecretStrategy
|
|
13
14
|
from digitalkin.services.services_models import ServicesStrategy
|
|
14
15
|
from digitalkin.services.storage import DefaultStorage, GrpcStorage, StorageStrategy
|
|
15
16
|
from digitalkin.services.user_profile import DefaultUserProfile, GrpcUserProfile, UserProfileStrategy
|
|
@@ -36,6 +37,7 @@ class ServicesConfig(BaseModel):
|
|
|
36
37
|
"identity",
|
|
37
38
|
"communication",
|
|
38
39
|
"user_profile",
|
|
40
|
+
"secret",
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
def __init__(
|
|
@@ -67,6 +69,7 @@ class ServicesConfig(BaseModel):
|
|
|
67
69
|
"identity": ServicesStrategy(local=DefaultIdentity, remote=DefaultIdentity),
|
|
68
70
|
"communication": ServicesStrategy(local=DefaultCommunication, remote=GrpcCommunication),
|
|
69
71
|
"user_profile": ServicesStrategy(local=DefaultUserProfile, remote=GrpcUserProfile),
|
|
72
|
+
"secret": ServicesStrategy(local=DefaultSecret, remote=GrpcSecret),
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
# Apply strategy overrides
|
|
@@ -75,6 +78,12 @@ class ServicesConfig(BaseModel):
|
|
|
75
78
|
self._strategies[name] = override if override is not None else defaults[name]
|
|
76
79
|
self._configs[name] = services_config_params.get(name) or {}
|
|
77
80
|
|
|
81
|
+
# The secret service is backed by the UserProfileService — reuse the
|
|
82
|
+
# user_profile client_config (same host/port) when no dedicated secret
|
|
83
|
+
# config is registered, so GrpcSecret can build its channel.
|
|
84
|
+
if not self._configs.get("secret"):
|
|
85
|
+
self._configs["secret"] = self._configs.get("user_profile") or {}
|
|
86
|
+
|
|
78
87
|
@classmethod
|
|
79
88
|
def valid_strategy_names(cls) -> set[str]:
|
|
80
89
|
"""Get the list of valid strategy names.
|
|
@@ -162,6 +171,11 @@ class ServicesConfig(BaseModel):
|
|
|
162
171
|
"""The user_profile service strategy class for the current mode."""
|
|
163
172
|
return self._strategies["user_profile"][self.mode.value]
|
|
164
173
|
|
|
174
|
+
@property
|
|
175
|
+
def secret(self) -> type[SecretStrategy]:
|
|
176
|
+
"""The secret service strategy class for the current mode."""
|
|
177
|
+
return self._strategies["secret"][self.mode.value]
|
|
178
|
+
|
|
165
179
|
def update_mode(self, mode: ServicesMode) -> None:
|
|
166
180
|
"""Update the strategy mode.
|
|
167
181
|
|
{digitalkin-1.0.0.dev21 → digitalkin-1.0.0.dev23}/src/digitalkin/services/services_models.py
RENAMED
|
@@ -11,6 +11,7 @@ from digitalkin.services.cost import CostStrategy
|
|
|
11
11
|
from digitalkin.services.filesystem import FilesystemStrategy
|
|
12
12
|
from digitalkin.services.identity import IdentityStrategy
|
|
13
13
|
from digitalkin.services.registry import RegistryStrategy
|
|
14
|
+
from digitalkin.services.secret import SecretStrategy
|
|
14
15
|
from digitalkin.services.storage import StorageStrategy
|
|
15
16
|
from digitalkin.services.task_manager.task_manager_strategy import TaskManagerStrategy
|
|
16
17
|
from digitalkin.services.user_profile import UserProfileStrategy
|
|
@@ -23,6 +24,7 @@ T = TypeVar(
|
|
|
23
24
|
| FilesystemStrategy
|
|
24
25
|
| IdentityStrategy
|
|
25
26
|
| RegistryStrategy
|
|
27
|
+
| SecretStrategy
|
|
26
28
|
| StorageStrategy
|
|
27
29
|
| UserProfileStrategy
|
|
28
30
|
| TaskManagerStrategy,
|
|
@@ -38,6 +38,18 @@ class DefaultUserProfile(UserProfileStrategy):
|
|
|
38
38
|
logger.debug("Retrieved user profile for mission_id: %s", self.mission_id)
|
|
39
39
|
return self.db[self.mission_id]
|
|
40
40
|
|
|
41
|
+
async def check_resource_access(self, resource_type: int, resource_id: str) -> bool: # noqa: ARG002, PLR6301
|
|
42
|
+
"""Local strategy: grant access (no access backend in local mode).
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
resource_type: The ResourceType enum value.
|
|
46
|
+
resource_id: The resource identifier.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
True.
|
|
50
|
+
"""
|
|
51
|
+
return True
|
|
52
|
+
|
|
41
53
|
def add_user_profile(self, user_profile_data: dict[str, Any]) -> None:
|
|
42
54
|
"""Add a user profile to the in-memory database (helper for testing).
|
|
43
55
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Digital Kin UserProfile Service gRPC Client."""
|
|
2
2
|
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any, cast
|
|
4
4
|
|
|
5
5
|
from agentic_mesh_protocol.user_profile.v1 import (
|
|
6
6
|
user_profile_pb2,
|
|
@@ -69,3 +69,24 @@ class GrpcUserProfile(UserProfileStrategy, GrpcClientWrapper, GrpcErrorHandlerMi
|
|
|
69
69
|
|
|
70
70
|
logger.debug("Retrieved user profile for mission_id: %s", self.mission_id)
|
|
71
71
|
return user_profile_dict
|
|
72
|
+
|
|
73
|
+
async def check_resource_access(self, resource_type: int, resource_id: str) -> bool:
|
|
74
|
+
"""Check whether the caller may access a resource (e.g. a setup).
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
resource_type: The ResourceType enum value (e.g. RESOURCE_TYPE_SETUP).
|
|
78
|
+
resource_id: The resource identifier (e.g. the setup_id).
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
True if access is granted, False otherwise.
|
|
82
|
+
|
|
83
|
+
Raises:
|
|
84
|
+
UserProfileServiceError: If the gRPC operation fails.
|
|
85
|
+
"""
|
|
86
|
+
async with self.handle_grpc_errors("CheckResourceAccess", UserProfileServiceError):
|
|
87
|
+
request = user_profile_pb2.CheckResourceAccessRequest(
|
|
88
|
+
resource_type=cast("user_profile_pb2.ResourceType", resource_type),
|
|
89
|
+
resource_id=resource_id,
|
|
90
|
+
)
|
|
91
|
+
response = await self.exec_grpc_query("CheckResourceAccess", request)
|
|
92
|
+
return response.allowed
|
|
@@ -19,3 +19,18 @@ class UserProfileStrategy(BaseStrategy, ABC):
|
|
|
19
19
|
Raises:
|
|
20
20
|
UserProfileServiceError: If the service call fails (not for missing profiles).
|
|
21
21
|
"""
|
|
22
|
+
|
|
23
|
+
@abstractmethod
|
|
24
|
+
async def check_resource_access(self, resource_type: int, resource_id: str) -> bool:
|
|
25
|
+
"""Check whether the caller may access a resource.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
resource_type: The ResourceType enum value (e.g. RESOURCE_TYPE_SETUP).
|
|
29
|
+
resource_id: The resource identifier (e.g. the setup_id).
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
True if access is granted, False otherwise.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
UserProfileServiceError: If the service call fails.
|
|
36
|
+
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalkin
|
|
3
|
-
Version: 1.0.0.
|
|
3
|
+
Version: 1.0.0.dev23
|
|
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
|
|
@@ -453,7 +453,7 @@ Requires-Python: >=3.10
|
|
|
453
453
|
Description-Content-Type: text/markdown
|
|
454
454
|
License-File: LICENSE
|
|
455
455
|
Requires-Dist: ag-ui-protocol>=0.1.18
|
|
456
|
-
Requires-Dist: agentic-mesh-protocol==1.0.
|
|
456
|
+
Requires-Dist: agentic-mesh-protocol==1.0.0a2
|
|
457
457
|
Requires-Dist: anyio>=4.13.0
|
|
458
458
|
Requires-Dist: grpcio-health-checking==1.81.0
|
|
459
459
|
Requires-Dist: grpcio-reflection==1.81.0
|