digitalkin 1.0.5.dev4__tar.gz → 1.0.5.dev6__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.5.dev4 → digitalkin-1.0.5.dev6}/PKG-INFO +6 -4
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/client.py +52 -155
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/pyproject.toml +6 -4
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/__version__.py +1 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/action.py +19 -11
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/base.py +22 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/services/action.py +10 -10
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/services/kit.py +1 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/profiling/task_profiler.py +2 -2
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/module_runner.py +7 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/redis/redis_client.py +1 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +6 -4
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/redis/redis_signal.py +2 -2
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/task_executor.py +4 -4
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/task_session.py +5 -5
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/gateway_servicer.py +153 -100
- digitalkin-1.0.5.dev6/src/digitalkin/grpc_servers/interceptors/validation.py +96 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/m2m_call_registry.py +3 -3
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/module_server.py +39 -33
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/module_servicer.py +130 -140
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +43 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/module_context.py +2 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/setup_types.py +1 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/tool_cache.py +1 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/services/registry.py +13 -9
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/gateway.py +2 -2
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/server/grpc.py +7 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/_base_module.py +55 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/communication/communication_strategy.py +6 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/communication/default_communication.py +7 -6
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/communication/exceptions.py +4 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/communication/grpc_communication.py +36 -29
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/cost/cost_strategy.py +1 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/cost/default_cost.py +17 -24
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/cost/grpc_cost.py +115 -66
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/filesystem/filesystem_strategy.py +2 -2
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/filesystem/grpc_filesystem.py +127 -81
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/registry/__init__.py +0 -2
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/registry/default_registry.py +2 -22
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/registry/grpc_registry.py +111 -125
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/registry/registry_strategy.py +2 -6
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/secret/grpc_secret.py +7 -5
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/setup/default_setup.py +192 -49
- digitalkin-1.0.5.dev6/src/digitalkin/services/setup/grpc_setup.py +604 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/setup/setup_strategy.py +90 -19
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/storage/default_storage.py +8 -13
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/storage/grpc_storage.py +112 -62
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/storage/storage_strategy.py +21 -19
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/user_profile/default_user_profile.py +9 -3
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/user_profile/grpc_user_profile.py +18 -12
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/user_profile/user_profile_strategy.py +7 -3
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/setup_content_validator.py +24 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin.egg-info/PKG-INFO +6 -4
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin.egg-info/SOURCES.txt +1 -1
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin.egg-info/requires.txt +5 -3
- digitalkin-1.0.5.dev4/src/digitalkin/services/registry/registry_models.py +0 -15
- digitalkin-1.0.5.dev4/src/digitalkin/services/setup/grpc_setup.py +0 -406
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/LICENSE +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/README.md +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/base_server/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/echo_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/models/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/models/input.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/models/output.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/models/secret.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/models/setup.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/server.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/triggers/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/bench_module/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/modules/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/modules/archetype_with_tools_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/monitoring/tests/test_metrics.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/echo_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/models/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/models/input.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/models/output.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/models/secret.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/models/setup.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/server.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/triggers/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/redis_demo/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/services/filesystem_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/examples/services/storage_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/setup.cfg +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/agno_adapter.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/agui_tools.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/hitl.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/models.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/module_toolkit.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/base.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/chat_history.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/defaults.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/action.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/kins/kit.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/action.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/loader/kit.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/services/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/action.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/registry/tools/kit.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/community/agno/toolkits/user_profile.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/common/factories.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/profiling/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/profiling/step_timer.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/resilience/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/resilience/bulkhead.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/stream_session.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/logger.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/mixins/agui_mixin.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/mixins/cost_mixin.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/mixins/file_history_mixin.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/core/redis.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/core/task_monitor.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/events/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/events/agent_events.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/grpc_servers/models.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/ag_ui.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/knowledge_files.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/loaded_tools.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/request_metadata.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/select_schema.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/tool_reference.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/module/utility.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/services/filesystem.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/services/services.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/certificate.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/client/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/client/channel.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/client/circuit_breaker.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/client/client.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/client/grpc.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/log.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/profiling.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/queue.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/redis.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/registry.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/resilience.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/server/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/server/channel.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/server/server.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/server/servicer.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/task_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/utils/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/settings/utils/channel.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/utils/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/archetype_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/tool_module.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/py.typed +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/cost/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/filesystem/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/secret/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/secret/default_secret.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/secret/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/secret/secret_strategy.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/services_config.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/setup/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/storage/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/task_manager/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/task_manager/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/services/user_profile/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/conditional_schema.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/env_manager.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/env_template.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/exceptions.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/json_structure.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/proto_utils.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/utils/schema_splitter.py +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin.egg-info/top_level.txt +0 -0
- {digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/tests/test_exceptions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalkin
|
|
3
|
-
Version: 1.0.5.
|
|
3
|
+
Version: 1.0.5.dev6
|
|
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,17 +453,19 @@ 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.21.dev1787220377
|
|
456
|
-
Requires-Dist: agentic-mesh-protocol==1.0
|
|
457
|
-
Requires-Dist: agno<3
|
|
456
|
+
Requires-Dist: agentic-mesh-protocol==1.2.0
|
|
457
|
+
Requires-Dist: agno<4,>=3.1.1
|
|
458
458
|
Requires-Dist: anyio>=4.13.0
|
|
459
|
+
Requires-Dist: cel-python>=0.5
|
|
459
460
|
Requires-Dist: grpcio-health-checking==1.82.1
|
|
460
461
|
Requires-Dist: grpcio-reflection==1.82.1
|
|
461
462
|
Requires-Dist: grpcio-status==1.82.1
|
|
463
|
+
Requires-Dist: protovalidate<2,>=1.2.0
|
|
462
464
|
Requires-Dist: pydantic-settings>=2.14.1
|
|
463
465
|
Requires-Dist: pydantic>=2.12.4
|
|
464
466
|
Requires-Dist: redis[hiredis]<9,>=7.4.0
|
|
465
467
|
Provides-Extra: agno
|
|
466
|
-
Requires-Dist: agno
|
|
468
|
+
Requires-Dist: agno<4,>=3.1.1; extra == "agno"
|
|
467
469
|
Provides-Extra: performance
|
|
468
470
|
Requires-Dist: uvloop>=0.21; extra == "performance"
|
|
469
471
|
Provides-Extra: profiling
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
"""Demo client for the Gateway gRPC service with per-endpoint testing.
|
|
3
3
|
|
|
4
4
|
Subcommands:
|
|
5
|
-
full Full pipeline: StartStream →
|
|
5
|
+
full Full pipeline: StartStream → Stream → SendSignal
|
|
6
6
|
start StartStream only (unary)
|
|
7
|
-
consume
|
|
8
|
-
|
|
9
|
-
signal SendSignal on existing task (requires --task-id)
|
|
7
|
+
consume Stream on existing task (requires --task-id)
|
|
8
|
+
signal SendSignal(cancel) on existing task (requires --task-id)
|
|
10
9
|
inspect Dump Redis keys for a task (no gRPC)
|
|
11
10
|
|
|
12
11
|
Usage:
|
|
@@ -14,8 +13,7 @@ Usage:
|
|
|
14
13
|
python client.py full --prompt "Test" --setup '{"uppercase": true, "repeat": 5}'
|
|
15
14
|
python client.py start --prompt "Hello"
|
|
16
15
|
python client.py consume --task-id <uuid>
|
|
17
|
-
python client.py
|
|
18
|
-
python client.py signal --task-id <uuid> --action cancel
|
|
16
|
+
python client.py signal --task-id <uuid>
|
|
19
17
|
python client.py inspect --task-id <uuid>
|
|
20
18
|
"""
|
|
21
19
|
|
|
@@ -34,7 +32,7 @@ import grpc
|
|
|
34
32
|
import redis.asyncio as aioredis
|
|
35
33
|
from google.protobuf import json_format, struct_pb2
|
|
36
34
|
|
|
37
|
-
from agentic_mesh_protocol.gateway.v1 import
|
|
35
|
+
from agentic_mesh_protocol.gateway.v1 import gateway_dto_pb2, gateway_messages_pb2, gateway_service_pb2_grpc
|
|
38
36
|
|
|
39
37
|
# ── ANSI colors ─────────────────────────────────────────────────────
|
|
40
38
|
|
|
@@ -291,29 +289,18 @@ def _print_diff_report(tracker: RedisTracker, task_id: str) -> None:
|
|
|
291
289
|
async def cmd_start(
|
|
292
290
|
stub: gateway_service_pb2_grpc.GatewayServiceStub,
|
|
293
291
|
task_id: str,
|
|
294
|
-
prompt: str,
|
|
295
|
-
setup: dict[str, Any] | None,
|
|
296
292
|
) -> bool:
|
|
297
293
|
"""StartStream — create a task session.
|
|
298
294
|
|
|
299
295
|
Returns:
|
|
300
296
|
True if accepted.
|
|
301
297
|
"""
|
|
302
|
-
input_struct = struct_pb2.Struct()
|
|
303
|
-
payload: dict[str, Any] = {
|
|
304
|
-
"root": {"protocol": "message", "text": prompt},
|
|
305
|
-
}
|
|
306
|
-
if setup:
|
|
307
|
-
payload["setup"] = setup
|
|
308
|
-
input_struct.update(payload)
|
|
309
|
-
|
|
310
298
|
t0 = time.monotonic()
|
|
311
299
|
resp = await stub.StartStream(
|
|
312
|
-
|
|
300
|
+
gateway_dto_pb2.StartStreamRequest(
|
|
313
301
|
task_id=task_id,
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
mission_id="demo-mission",
|
|
302
|
+
setup_id="setups:demo",
|
|
303
|
+
mission_id="missions:demo",
|
|
317
304
|
),
|
|
318
305
|
)
|
|
319
306
|
elapsed = (time.monotonic() - t0) * 1000
|
|
@@ -327,112 +314,58 @@ async def cmd_start(
|
|
|
327
314
|
async def cmd_consume(
|
|
328
315
|
stub: gateway_service_pb2_grpc.GatewayServiceStub,
|
|
329
316
|
task_id: str,
|
|
317
|
+
prompt: str,
|
|
318
|
+
setup: dict[str, Any] | None,
|
|
330
319
|
verbose: bool,
|
|
331
320
|
) -> list[dict[str, Any]]:
|
|
332
|
-
"""
|
|
321
|
+
"""Stream — send the query, then read module output until ``stream.end``.
|
|
333
322
|
|
|
334
323
|
Returns:
|
|
335
324
|
List of received items.
|
|
336
325
|
"""
|
|
337
326
|
received: list[dict[str, Any]] = []
|
|
327
|
+
query: dict[str, Any] = {"root": {"protocol": "message", "text": prompt}}
|
|
328
|
+
if setup:
|
|
329
|
+
query["setup"] = setup
|
|
330
|
+
query_struct = struct_pb2.Struct()
|
|
331
|
+
query_struct.update(query)
|
|
338
332
|
|
|
339
333
|
async def _requests() -> AsyncGenerator:
|
|
340
|
-
yield
|
|
341
|
-
init=gateway_pb2.ConsumeStreamInit(task_id=task_id, from_seq=0),
|
|
342
|
-
)
|
|
334
|
+
yield gateway_messages_pb2.StreamRequest(task_id=task_id, from_seq=0, data=query_struct)
|
|
343
335
|
|
|
344
336
|
t0 = time.monotonic()
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
received.append({"seq": resp.
|
|
354
|
-
print(f" {GREEN}
|
|
355
|
-
if verbose:
|
|
356
|
-
print(f" {DIM}{json.dumps(data_dict, ensure_ascii=False)}{RESET}") # noqa: T201
|
|
357
|
-
|
|
358
|
-
elif payload_type == "status":
|
|
359
|
-
state_name = gateway_pb2.StreamState.Name(resp.status.state)
|
|
360
|
-
received.append({"status": state_name})
|
|
361
|
-
color = GREEN if "COMPLETED" in state_name else YELLOW
|
|
362
|
-
print(f" {color}status: {state_name}{RESET} ({elapsed:.1f}ms total)") # noqa: T201
|
|
363
|
-
break
|
|
364
|
-
|
|
365
|
-
elif payload_type == "error":
|
|
366
|
-
received.append({"error": resp.error.message})
|
|
367
|
-
print(f" {RED}error: code={resp.error.code} msg={resp.error.message}{RESET}") # noqa: T201
|
|
337
|
+
async for resp in stub.Stream(_requests()):
|
|
338
|
+
root = json_format.MessageToDict(resp.data).get("root", {})
|
|
339
|
+
protocol = root.get("protocol", "")
|
|
340
|
+
if protocol == "stream.error":
|
|
341
|
+
received.append({"seq": resp.seq, "error": root.get("message", "")})
|
|
342
|
+
print(f" {RED}error: code={root.get('code')} msg={root.get('message')}{RESET}") # noqa: T201
|
|
343
|
+
continue
|
|
344
|
+
if protocol == "stream.end":
|
|
345
|
+
received.append({"seq": resp.seq, "status": "stream.end"})
|
|
346
|
+
print(f" {GREEN}stream.end{RESET} ({(time.monotonic() - t0) * 1000:.1f}ms total)") # noqa: T201
|
|
368
347
|
break
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
348
|
+
text = root.get("text", protocol)
|
|
349
|
+
received.append({"seq": resp.seq, "text": text})
|
|
350
|
+
print(f" {GREEN}seq={resp.seq:>2}{RESET} {text}") # noqa: T201
|
|
351
|
+
if verbose:
|
|
352
|
+
print(f" {DIM}{json.dumps(root, ensure_ascii=False)}{RESET}") # noqa: T201
|
|
373
353
|
|
|
374
354
|
return received
|
|
375
355
|
|
|
376
356
|
|
|
377
|
-
async def cmd_produce(
|
|
378
|
-
stub: gateway_service_pb2_grpc.GatewayServiceStub,
|
|
379
|
-
task_id: str,
|
|
380
|
-
prompt: str,
|
|
381
|
-
num_chunks: int,
|
|
382
|
-
) -> int:
|
|
383
|
-
"""ProduceStream — act as Module A, push output chunks.
|
|
384
|
-
|
|
385
|
-
Returns:
|
|
386
|
-
Number of server responses.
|
|
387
|
-
"""
|
|
388
|
-
async def _requests() -> AsyncGenerator:
|
|
389
|
-
yield gateway_pb2.ProduceStreamRequest(
|
|
390
|
-
init=gateway_pb2.ProduceStreamInit(task_id=task_id),
|
|
391
|
-
)
|
|
392
|
-
for i in range(num_chunks):
|
|
393
|
-
data = struct_pb2.Struct()
|
|
394
|
-
data.update({
|
|
395
|
-
"root": {
|
|
396
|
-
"protocol": "message",
|
|
397
|
-
"text": f"[{i + 1}/{num_chunks}] {prompt}",
|
|
398
|
-
},
|
|
399
|
-
})
|
|
400
|
-
yield gateway_pb2.ProduceStreamRequest(
|
|
401
|
-
output=gateway_pb2.ProduceStreamOutput(task_id=task_id, data=data),
|
|
402
|
-
)
|
|
403
|
-
await asyncio.sleep(0.05)
|
|
404
|
-
|
|
405
|
-
t0 = time.monotonic()
|
|
406
|
-
resp_stream = stub.ProduceStream(_requests())
|
|
407
|
-
count = 0
|
|
408
|
-
async for resp in resp_stream:
|
|
409
|
-
count += 1
|
|
410
|
-
payload = resp.WhichOneof("payload")
|
|
411
|
-
print(f" response #{count}: {payload}") # noqa: T201
|
|
412
|
-
|
|
413
|
-
elapsed = (time.monotonic() - t0) * 1000
|
|
414
|
-
print(f" {DIM}stream closed ({count} responses, {elapsed:.1f}ms){RESET}") # noqa: T201
|
|
415
|
-
return count
|
|
416
|
-
|
|
417
|
-
|
|
418
357
|
async def cmd_signal(
|
|
419
358
|
stub: gateway_service_pb2_grpc.GatewayServiceStub,
|
|
420
359
|
task_id: str,
|
|
421
|
-
action: str,
|
|
422
360
|
) -> bool:
|
|
423
|
-
"""SendSignal —
|
|
361
|
+
"""SendSignal — cancel a running task.
|
|
424
362
|
|
|
425
363
|
Returns:
|
|
426
364
|
True if accepted.
|
|
427
365
|
"""
|
|
428
|
-
action_enum = (
|
|
429
|
-
gateway_pb2.SIGNAL_ACTION_CANCEL if action == "cancel"
|
|
430
|
-
else gateway_pb2.SIGNAL_ACTION_PAUSE
|
|
431
|
-
)
|
|
432
|
-
|
|
433
366
|
t0 = time.monotonic()
|
|
434
367
|
resp = await stub.SendSignal(
|
|
435
|
-
|
|
368
|
+
gateway_dto_pb2.SendSignalRequest(cancel=gateway_messages_pb2.CancelSignal(task_id=task_id)),
|
|
436
369
|
)
|
|
437
370
|
elapsed = (time.monotonic() - t0) * 1000
|
|
438
371
|
|
|
@@ -447,7 +380,7 @@ async def cmd_signal(
|
|
|
447
380
|
|
|
448
381
|
|
|
449
382
|
async def run_full(args: argparse.Namespace) -> None:
|
|
450
|
-
"""Full pipeline: StartStream →
|
|
383
|
+
"""Full pipeline: StartStream → Stream → SendSignal."""
|
|
451
384
|
task_id = args.task_id or str(uuid.uuid4())
|
|
452
385
|
setup = json.loads(args.setup) if args.setup else None
|
|
453
386
|
tracker = RedisTracker(args.redis) if args.verbose else None
|
|
@@ -467,7 +400,7 @@ async def run_full(args: argparse.Namespace) -> None:
|
|
|
467
400
|
|
|
468
401
|
# 1. StartStream
|
|
469
402
|
print(f"\n{BOLD}[1] StartStream{RESET}") # noqa: T201
|
|
470
|
-
accepted = await cmd_start(stub, task_id
|
|
403
|
+
accepted = await cmd_start(stub, task_id)
|
|
471
404
|
if not accepted:
|
|
472
405
|
print(f" {RED}Server rejected the task — aborting.{RESET}") # noqa: T201
|
|
473
406
|
return
|
|
@@ -476,18 +409,17 @@ async def run_full(args: argparse.Namespace) -> None:
|
|
|
476
409
|
await asyncio.sleep(0.1)
|
|
477
410
|
await tracker.snapshot("StartStream", task_id)
|
|
478
411
|
|
|
479
|
-
# 2.
|
|
480
|
-
print(f"\n{BOLD}[2]
|
|
481
|
-
await
|
|
482
|
-
received = await cmd_consume(stub, task_id, args.verbose)
|
|
412
|
+
# 2. Stream — send the query, read module output
|
|
413
|
+
print(f"\n{BOLD}[2] Stream{RESET}") # noqa: T201
|
|
414
|
+
received = await cmd_consume(stub, task_id, args.prompt, setup, args.verbose)
|
|
483
415
|
|
|
484
416
|
if tracker:
|
|
485
417
|
await asyncio.sleep(0.1)
|
|
486
|
-
await tracker.snapshot("
|
|
418
|
+
await tracker.snapshot("Stream", task_id)
|
|
487
419
|
|
|
488
420
|
# 3. SendSignal
|
|
489
421
|
print(f"\n{BOLD}[3] SendSignal (cancel){RESET}") # noqa: T201
|
|
490
|
-
await cmd_signal(stub, task_id
|
|
422
|
+
await cmd_signal(stub, task_id)
|
|
491
423
|
|
|
492
424
|
if tracker:
|
|
493
425
|
await asyncio.sleep(0.1)
|
|
@@ -513,61 +445,39 @@ async def run_full(args: argparse.Namespace) -> None:
|
|
|
513
445
|
async def run_start(args: argparse.Namespace) -> None:
|
|
514
446
|
"""StartStream only."""
|
|
515
447
|
task_id = args.task_id or str(uuid.uuid4())
|
|
516
|
-
setup = json.loads(args.setup) if args.setup else None
|
|
517
448
|
|
|
518
449
|
print(f"\n{BOLD}[StartStream]{RESET} gateway={args.gateway} task_id={task_id}") # noqa: T201
|
|
519
450
|
|
|
520
451
|
async with grpc.aio.insecure_channel(args.gateway, options=GRPC_OPTIONS) as channel:
|
|
521
452
|
stub = gateway_service_pb2_grpc.GatewayServiceStub(channel)
|
|
522
|
-
await cmd_start(stub, task_id
|
|
453
|
+
await cmd_start(stub, task_id)
|
|
523
454
|
|
|
524
455
|
|
|
525
456
|
async def run_consume(args: argparse.Namespace) -> None:
|
|
526
|
-
"""
|
|
457
|
+
"""Stream on existing task."""
|
|
527
458
|
if not args.task_id:
|
|
528
459
|
print(f"{RED}--task-id is required for consume{RESET}") # noqa: T201
|
|
529
460
|
sys.exit(1)
|
|
530
461
|
|
|
531
|
-
print(f"\n{BOLD}[ConsumeStream]{RESET} gateway={args.gateway} task_id={args.task_id}") # noqa: T201
|
|
532
|
-
|
|
533
|
-
async with grpc.aio.insecure_channel(args.gateway, options=GRPC_OPTIONS) as channel:
|
|
534
|
-
stub = gateway_service_pb2_grpc.GatewayServiceStub(channel)
|
|
535
|
-
await cmd_consume(stub, args.task_id, args.verbose)
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
async def run_produce(args: argparse.Namespace) -> None:
|
|
539
|
-
"""StartStream + ProduceStream (act as Module A)."""
|
|
540
|
-
task_id = args.task_id or str(uuid.uuid4())
|
|
541
462
|
setup = json.loads(args.setup) if args.setup else None
|
|
542
|
-
|
|
543
|
-
print(f"\n{BOLD}[Produce]{RESET} gateway={args.gateway} task_id={task_id}") # noqa: T201
|
|
463
|
+
print(f"\n{BOLD}[Stream]{RESET} gateway={args.gateway} task_id={args.task_id}") # noqa: T201
|
|
544
464
|
|
|
545
465
|
async with grpc.aio.insecure_channel(args.gateway, options=GRPC_OPTIONS) as channel:
|
|
546
466
|
stub = gateway_service_pb2_grpc.GatewayServiceStub(channel)
|
|
547
|
-
|
|
548
|
-
# StartStream first (registers the session)
|
|
549
|
-
print(f"\n {BOLD}StartStream{RESET}") # noqa: T201
|
|
550
|
-
accepted = await cmd_start(stub, task_id, args.prompt, setup)
|
|
551
|
-
if not accepted:
|
|
552
|
-
print(f" {RED}Rejected{RESET}") # noqa: T201
|
|
553
|
-
return
|
|
554
|
-
|
|
555
|
-
# ProduceStream (act as Module A)
|
|
556
|
-
print(f"\n {BOLD}ProduceStream ({args.chunks} chunks){RESET}") # noqa: T201
|
|
557
|
-
await cmd_produce(stub, task_id, args.prompt, args.chunks)
|
|
467
|
+
await cmd_consume(stub, args.task_id, args.prompt, setup, args.verbose)
|
|
558
468
|
|
|
559
469
|
|
|
560
470
|
async def run_signal(args: argparse.Namespace) -> None:
|
|
561
|
-
"""SendSignal on existing task."""
|
|
471
|
+
"""SendSignal(cancel) on existing task."""
|
|
562
472
|
if not args.task_id:
|
|
563
473
|
print(f"{RED}--task-id is required for signal{RESET}") # noqa: T201
|
|
564
474
|
sys.exit(1)
|
|
565
475
|
|
|
566
|
-
print(f"\n{BOLD}[SendSignal]{RESET} gateway={args.gateway} task_id={args.task_id}
|
|
476
|
+
print(f"\n{BOLD}[SendSignal]{RESET} gateway={args.gateway} task_id={args.task_id} signal=cancel") # noqa: T201
|
|
567
477
|
|
|
568
478
|
async with grpc.aio.insecure_channel(args.gateway, options=GRPC_OPTIONS) as channel:
|
|
569
479
|
stub = gateway_service_pb2_grpc.GatewayServiceStub(channel)
|
|
570
|
-
await cmd_signal(stub, args.task_id
|
|
480
|
+
await cmd_signal(stub, args.task_id)
|
|
571
481
|
|
|
572
482
|
|
|
573
483
|
async def run_inspect(args: argparse.Namespace) -> None:
|
|
@@ -613,8 +523,7 @@ examples:
|
|
|
613
523
|
%(prog)s full --prompt "Test" --setup '{"uppercase": true, "repeat": 5}'
|
|
614
524
|
%(prog)s start --prompt "Hello"
|
|
615
525
|
%(prog)s consume --task-id <uuid>
|
|
616
|
-
%(prog)s
|
|
617
|
-
%(prog)s signal --task-id <uuid> --action cancel
|
|
526
|
+
%(prog)s signal --task-id <uuid>
|
|
618
527
|
%(prog)s inspect --task-id <uuid>
|
|
619
528
|
""",
|
|
620
529
|
)
|
|
@@ -631,21 +540,16 @@ examples:
|
|
|
631
540
|
sub = p.add_subparsers(dest="command", help="Endpoint to test")
|
|
632
541
|
|
|
633
542
|
# full (default)
|
|
634
|
-
sub.add_parser("full", help="Full pipeline: StartStream ->
|
|
543
|
+
sub.add_parser("full", help="Full pipeline: StartStream -> Stream -> SendSignal")
|
|
635
544
|
|
|
636
545
|
# start
|
|
637
546
|
sub.add_parser("start", help="StartStream only (unary)")
|
|
638
547
|
|
|
639
548
|
# consume
|
|
640
|
-
sub.add_parser("consume", help="
|
|
641
|
-
|
|
642
|
-
# produce
|
|
643
|
-
sp_produce = sub.add_parser("produce", help="StartStream + ProduceStream (act as Module A)")
|
|
644
|
-
sp_produce.add_argument("--chunks", type=int, default=3, help="Number of chunks to produce (default: 3)")
|
|
549
|
+
sub.add_parser("consume", help="Stream on existing task (requires --task-id)")
|
|
645
550
|
|
|
646
551
|
# signal
|
|
647
|
-
|
|
648
|
-
sp_signal.add_argument("--action", choices=["cancel", "pause"], default="cancel", help="Signal action (default: cancel)")
|
|
552
|
+
sub.add_parser("signal", help="SendSignal(cancel) on existing task (requires --task-id)")
|
|
649
553
|
|
|
650
554
|
# inspect
|
|
651
555
|
sub.add_parser("inspect", help="Dump Redis keys for a task (no gRPC)")
|
|
@@ -662,17 +566,10 @@ async def main() -> None:
|
|
|
662
566
|
if not args.command:
|
|
663
567
|
args.command = "full"
|
|
664
568
|
|
|
665
|
-
# Set defaults for subcommand-specific args
|
|
666
|
-
if not hasattr(args, "chunks"):
|
|
667
|
-
args.chunks = 3
|
|
668
|
-
if not hasattr(args, "action"):
|
|
669
|
-
args.action = "cancel"
|
|
670
|
-
|
|
671
569
|
handlers = {
|
|
672
570
|
"full": run_full,
|
|
673
571
|
"start": run_start,
|
|
674
572
|
"consume": run_consume,
|
|
675
|
-
"produce": run_produce,
|
|
676
573
|
"signal": run_signal,
|
|
677
574
|
"inspect": run_inspect,
|
|
678
575
|
}
|
|
@@ -31,20 +31,22 @@
|
|
|
31
31
|
# which is how a nested run's output is attributed to its author. Pinned exactly
|
|
32
32
|
# because it is a dated prerelease; move to >=0.1.21 once that ships stable.
|
|
33
33
|
"ag-ui-protocol==0.1.21.dev1787220377",
|
|
34
|
-
"agentic-mesh-protocol==1.0
|
|
35
|
-
"agno>=
|
|
34
|
+
"agentic-mesh-protocol==1.2.0",
|
|
35
|
+
"agno>=3.1.1,<4",
|
|
36
36
|
"anyio>=4.13.0",
|
|
37
|
+
"cel-python>=0.5",
|
|
37
38
|
"grpcio-health-checking==1.82.1",
|
|
38
39
|
"grpcio-reflection==1.82.1",
|
|
39
40
|
"grpcio-status==1.82.1",
|
|
41
|
+
"protovalidate>=1.2.0,<2",
|
|
40
42
|
"pydantic-settings>=2.14.1",
|
|
41
43
|
"pydantic>=2.12.4",
|
|
42
44
|
"redis[hiredis]>=7.4.0,<9",
|
|
43
45
|
]
|
|
44
|
-
|
|
46
|
+
version = "1.0.5.dev6"
|
|
45
47
|
|
|
46
48
|
[project.optional-dependencies]
|
|
47
|
-
agno = [ "agno>=
|
|
49
|
+
agno = [ "agno>=3.1.1,<4" ]
|
|
48
50
|
performance = [ "uvloop>=0.21" ]
|
|
49
51
|
profiling = [
|
|
50
52
|
"pyinstrument>=5.1.2",
|
|
@@ -16,6 +16,7 @@ from pydantic import Field
|
|
|
16
16
|
from digitalkin.community.agno.toolkits.registry.base import RegistryAction
|
|
17
17
|
from digitalkin.logger import logger
|
|
18
18
|
from digitalkin.models.services.registry import (
|
|
19
|
+
RegistryModuleType,
|
|
19
20
|
RegistrySetupStatus,
|
|
20
21
|
RegistrySortBy,
|
|
21
22
|
RegistryVisibility,
|
|
@@ -36,7 +37,7 @@ class GetAction(RegistryAction):
|
|
|
36
37
|
"""Read the setup (always its current version), refusing a foreign object type.
|
|
37
38
|
|
|
38
39
|
Returns:
|
|
39
|
-
The setup with its current version, status and visibility.
|
|
40
|
+
The setup with its current version, status and visibility, and a service's key map.
|
|
40
41
|
"""
|
|
41
42
|
return await ctx.ensure_kind(self.setup_id)
|
|
42
43
|
|
|
@@ -55,7 +56,6 @@ class SearchAction(RegistryAction):
|
|
|
55
56
|
this manager's own kind. Filters combine with AND; within one filter the values are OR'd.
|
|
56
57
|
"""
|
|
57
58
|
|
|
58
|
-
_DOC_PREVIEW_CHARS: ClassVar[int] = 300
|
|
59
59
|
# The service ceiling itself (storage and registry both cap a page at 100), so the toolkit
|
|
60
60
|
# no longer imposes a tighter one of its own.
|
|
61
61
|
_MAX_RESULTS: ClassVar[int] = 100
|
|
@@ -125,14 +125,16 @@ class SearchAction(RegistryAction):
|
|
|
125
125
|
# would both contradict ``total_returned`` and, at exactly ``cap`` rows, promise an empty
|
|
126
126
|
# next page.
|
|
127
127
|
truncated = len(usable) > cap
|
|
128
|
-
rows = [self._row(setup) for setup in usable[:cap]]
|
|
128
|
+
rows = [self._row(setup, ctx.module_type) for setup in usable[:cap]]
|
|
129
129
|
return {"total_returned": len(rows), "truncated": truncated, "offset": self.offset, "setups": rows}
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
@staticmethod
|
|
132
|
+
def _row(setup: SetupSummary, module_type: RegistryModuleType) -> dict[str, Any]:
|
|
132
133
|
"""Trim one search hit to the fields a caller can act on.
|
|
133
134
|
|
|
134
135
|
Args:
|
|
135
136
|
setup: The summary returned by the registry.
|
|
137
|
+
module_type: The manager's object type; only services render a structure map.
|
|
136
138
|
|
|
137
139
|
Returns:
|
|
138
140
|
The rendered row.
|
|
@@ -147,11 +149,16 @@ class SearchAction(RegistryAction):
|
|
|
147
149
|
"tags": setup.tags,
|
|
148
150
|
"visibility": setup.visibility.value if setup.visibility else None,
|
|
149
151
|
"status": setup.status.value if setup.status else None,
|
|
150
|
-
"
|
|
152
|
+
"documentation": setup.documentation or None,
|
|
151
153
|
}
|
|
152
|
-
# Only service setups carry a map
|
|
153
|
-
#
|
|
154
|
-
if
|
|
154
|
+
# Only service setups carry a map, so tools and kins rows never show one. A service row
|
|
155
|
+
# always does, {} included: a caller iterating rows must not meet a missing key.
|
|
156
|
+
if module_type == RegistryModuleType.SERVICE:
|
|
157
|
+
if not setup.structure:
|
|
158
|
+
logger.info(
|
|
159
|
+
"[VALIDATE STRUCTROW] service row rendered with an empty structure: setup_id=%s",
|
|
160
|
+
setup.setup_id,
|
|
161
|
+
) # TODO(validate): remove after prod validation
|
|
155
162
|
row["structure"] = setup.structure
|
|
156
163
|
return row
|
|
157
164
|
|
|
@@ -182,9 +189,10 @@ class UpdateAction(RegistryAction):
|
|
|
182
189
|
)
|
|
183
190
|
documentation: str | None = Field(
|
|
184
191
|
default=None,
|
|
185
|
-
|
|
186
|
-
"
|
|
187
|
-
"
|
|
192
|
+
max_length=300,
|
|
193
|
+
description="Free text describing what this instance is for, indexed by ``search``, at "
|
|
194
|
+
"most 300 characters. Omit to keep the text the instance already has; pass a string to "
|
|
195
|
+
"replace it, or an empty string to clear it.",
|
|
188
196
|
)
|
|
189
197
|
|
|
190
198
|
def _type_payload(self) -> dict[str, Any]: # ruff: ignore[no-self-use]
|
|
@@ -158,6 +158,20 @@ class RegistryActionCtx(BaseActionCtx):
|
|
|
158
158
|
raise ValueError(msg)
|
|
159
159
|
return setup
|
|
160
160
|
|
|
161
|
+
async def structure_of(self, setup_id: str) -> dict[str, str]:
|
|
162
|
+
"""Read a setup's stored key map from the registry search.
|
|
163
|
+
|
|
164
|
+
Like every search, it follows the index, which may briefly lag right after a write.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
setup_id: The setup whose map to read.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
The map, or ``{}`` when the search summary carries none.
|
|
171
|
+
"""
|
|
172
|
+
found = await self.registry.search_setups(setup_ids=[setup_id], module_types=[self.module_type], limit=1)
|
|
173
|
+
return found[0].structure if found else {}
|
|
174
|
+
|
|
161
175
|
|
|
162
176
|
class RegistryAction(BaseAction[RegistryActionCtx], ABC):
|
|
163
177
|
"""Base for the discriminated registry actions shared across the three CRUD managers.
|
|
@@ -364,6 +378,14 @@ class RegistryObjectToolKit(DkToolkit):
|
|
|
364
378
|
visibility = data.get("visibility")
|
|
365
379
|
if isinstance(visibility, str) and visibility.startswith("VISIBILITY_"):
|
|
366
380
|
data["visibility"] = visibility.removeprefix("VISIBILITY_").lower()
|
|
381
|
+
# A None map means the version carries none, as on every tools and kins read.
|
|
382
|
+
# Rendering it would put the feature on their surface.
|
|
383
|
+
version = data.get("current_setup_version")
|
|
384
|
+
if isinstance(version, dict) and "structure" in version and version["structure"] is None:
|
|
385
|
+
logger.info(
|
|
386
|
+
"[VALIDATE STRUCTREAD] uncarried structure omitted: setup_id=%s", data.get("id")
|
|
387
|
+
) # TODO(validate): remove after prod validation
|
|
388
|
+
del version["structure"]
|
|
367
389
|
return data
|
|
368
390
|
if isinstance(value, ProtoMessage):
|
|
369
391
|
return ProtoUtils.proto_to_dict(value)
|
|
@@ -51,9 +51,10 @@ class CreateServiceAction(RegistryAction):
|
|
|
51
51
|
)
|
|
52
52
|
documentation: str = Field(
|
|
53
53
|
default="",
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
"
|
|
54
|
+
max_length=300,
|
|
55
|
+
description="Free text describing what this service is for and when to use it, at most "
|
|
56
|
+
"300 characters. It is what ``search`` matches on and returns, so a service created "
|
|
57
|
+
"without it is findable only by name.",
|
|
57
58
|
)
|
|
58
59
|
structure: dict[str, str] = Field(
|
|
59
60
|
...,
|
|
@@ -101,8 +102,7 @@ class StructureServiceAction(RegistryAction):
|
|
|
101
102
|
The key map, or an empty dict when the setup carries none.
|
|
102
103
|
"""
|
|
103
104
|
await ctx.ensure_kind(self.setup_id)
|
|
104
|
-
|
|
105
|
-
return found[0].structure if found else {}
|
|
105
|
+
return await ctx.structure_of(self.setup_id)
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
class LoadServiceAction(RegistryAction):
|
|
@@ -114,8 +114,8 @@ class LoadServiceAction(RegistryAction):
|
|
|
114
114
|
default=None,
|
|
115
115
|
description="One key path copied verbatim from the service's structure map, to read just "
|
|
116
116
|
"that part of the configuration. Copy it, do not compose it: a key the configuration "
|
|
117
|
-
"does not have
|
|
118
|
-
"
|
|
117
|
+
"does not have fails with not found. Omit the key to load everything deliberately, "
|
|
118
|
+
"when the configuration is small or genuinely needed in full.",
|
|
119
119
|
)
|
|
120
120
|
|
|
121
121
|
async def execute(self, ctx: RegistryActionCtx) -> Any:
|
|
@@ -125,11 +125,11 @@ class LoadServiceAction(RegistryAction):
|
|
|
125
125
|
internal configuration — the most dangerous type-confusion, since the response
|
|
126
126
|
carries no field the caller could use to notice it read the wrong kind. The read
|
|
127
127
|
itself passes ``key`` to the setup service, so the narrowing happens where the
|
|
128
|
-
document lives; a key the configuration does not have
|
|
129
|
-
|
|
128
|
+
document lives; a key the configuration does not have is refused as not found,
|
|
129
|
+
which is what the wire does.
|
|
130
130
|
|
|
131
131
|
Returns:
|
|
132
|
-
|
|
132
|
+
The part of the configuration ``key`` names, or the whole configuration without one.
|
|
133
133
|
"""
|
|
134
134
|
await ctx.ensure_kind(self.setup_id)
|
|
135
135
|
setup = await ctx.setup.get_setup({"setup_id": self.setup_id, "structure_key": self.key or ""})
|
|
@@ -44,7 +44,7 @@ class ServicesManager(RegistryObjectToolKit):
|
|
|
44
44
|
"result with a 'structure' map of key path -> what lives there ('structure' fetches "
|
|
45
45
|
"the same map for an id you already hold), then 'load' with a key copied verbatim "
|
|
46
46
|
"from it returns just that part. Copy the key, never invent one: a key the "
|
|
47
|
-
"configuration does not have
|
|
47
|
+
"configuration does not have fails with not found. Load without a key only when "
|
|
48
48
|
"the whole document is genuinely needed. On create and update you write that map "
|
|
49
49
|
"yourself, describing what "
|
|
50
50
|
"each key is for — it is how other agents find their way around the configuration."
|
{digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/profiling/task_profiler.py
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Per-task profiling wrapper for VizTracer, Yappi, and Pyinstrument."""
|
|
2
2
|
|
|
3
|
-
import datetime
|
|
3
|
+
import datetime as dt
|
|
4
4
|
import io
|
|
5
5
|
import os
|
|
6
6
|
from pathlib import Path
|
|
@@ -101,7 +101,7 @@ class TaskProfiler:
|
|
|
101
101
|
return
|
|
102
102
|
|
|
103
103
|
try: # ruff: ignore[too-many-statements-in-try-clause]
|
|
104
|
-
timestamp =
|
|
104
|
+
timestamp = dt.datetime.now(dt.timezone.utc).strftime("%Y%m%dT%H%M%S%f")
|
|
105
105
|
base = f"{self._task_id}_{timestamp}"
|
|
106
106
|
|
|
107
107
|
if self._mode == ProfilerMode.VIZTRACER:
|
{digitalkin-1.0.5.dev4 → digitalkin-1.0.5.dev6}/src/digitalkin/core/task_manager/module_runner.py
RENAMED
|
@@ -151,9 +151,13 @@ class ModuleRunner:
|
|
|
151
151
|
last_write_ns = time.monotonic_ns()
|
|
152
152
|
data = output_data.model_dump(mode="json")
|
|
153
153
|
if data.get("root", {}).get("protocol") == "stream.end":
|
|
154
|
+
if eos_written:
|
|
155
|
+
# TODO(validate): EOS-ONCE a stream gets a single end-of-stream marker
|
|
156
|
+
logger.info("[VALIDATE EOS-ONCE] duplicate stream.end skipped", extra=log_extra)
|
|
157
|
+
return
|
|
154
158
|
t_eos_write_start = time.perf_counter_ns()
|
|
155
|
-
eos_written = True
|
|
156
159
|
await self._redis_client.xadd(stream_key, {"eos": b"true"})
|
|
160
|
+
eos_written = True
|
|
157
161
|
await self._redis_client.expire(stream_key, stream_settings.redis_stream_ttl)
|
|
158
162
|
await self._redis_client.expire(idem_key, stream_settings.redis_stream_ttl)
|
|
159
163
|
# TODO(validate): IDEM-TTL-EOS idem TTL drops to redis_stream_ttl once EOS is written
|
|
@@ -372,6 +376,8 @@ class ModuleRunner:
|
|
|
372
376
|
logger.warning(
|
|
373
377
|
"[VALIDATE RUNNER-LEAK] task never created; stopping preloaded instance", extra=log_extra
|
|
374
378
|
)
|
|
379
|
+
# Only a failure path gets here, and on_fatal already wrote stream.error + EOS.
|
|
380
|
+
eos_written = True
|
|
375
381
|
try:
|
|
376
382
|
await module.stop(cancel_reason)
|
|
377
383
|
finally:
|