digitalkin 1.0.5.dev3__tar.gz → 1.0.5.dev5__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.dev3 → digitalkin-1.0.5.dev5}/PKG-INFO +2 -2
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/client.py +52 -155
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/pyproject.toml +2 -2
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/__version__.py +1 -1
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/agno_adapter.py +20 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/hitl.py +27 -5
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/module_toolkit.py +21 -4
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/action.py +19 -11
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/base.py +22 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/services/action.py +10 -10
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/services/kit.py +1 -1
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/module_runner.py +40 -2
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/redis_signal.py +2 -2
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/gateway_servicer.py +69 -75
- digitalkin-1.0.5.dev5/src/digitalkin/grpc_servers/interceptors/validation.py +81 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/m2m_call_registry.py +3 -3
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/module_server.py +39 -31
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/module_servicer.py +130 -140
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +43 -1
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/agui_mixin.py +175 -9
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/module_context.py +8 -1
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/tool_cache.py +1 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/utility.py +6 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/registry.py +13 -9
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/gateway.py +2 -2
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/module.py +8 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/_base_module.py +75 -5
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/communication_strategy.py +6 -1
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/default_communication.py +7 -6
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/exceptions.py +8 -1
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/grpc_communication.py +48 -38
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/cost_strategy.py +1 -1
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/default_cost.py +17 -24
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/grpc_cost.py +115 -66
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/filesystem_strategy.py +2 -2
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/grpc_filesystem.py +127 -81
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/__init__.py +0 -2
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/default_registry.py +2 -22
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/grpc_registry.py +111 -125
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/registry_strategy.py +2 -6
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/grpc_secret.py +7 -5
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/setup/default_setup.py +189 -46
- digitalkin-1.0.5.dev5/src/digitalkin/services/setup/grpc_setup.py +604 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/setup/setup_strategy.py +89 -18
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/default_storage.py +2 -5
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/grpc_storage.py +112 -62
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/storage_strategy.py +18 -16
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/default_user_profile.py +9 -3
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/grpc_user_profile.py +18 -12
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/user_profile_strategy.py +7 -3
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/setup_content_validator.py +24 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/PKG-INFO +2 -2
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/SOURCES.txt +1 -1
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/requires.txt +1 -1
- digitalkin-1.0.5.dev3/src/digitalkin/services/registry/registry_models.py +0 -15
- digitalkin-1.0.5.dev3/src/digitalkin/services/setup/grpc_setup.py +0 -406
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/LICENSE +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/README.md +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/base_server/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/echo_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/models/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/models/input.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/models/output.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/models/secret.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/models/setup.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/server.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/triggers/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/bench_module/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/modules/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/modules/archetype_with_tools_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/monitoring/tests/test_metrics.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/echo_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/input.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/output.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/secret.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/models/setup.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/server.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/triggers/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/redis_demo/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/services/filesystem_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/examples/services/storage_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/setup.cfg +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/agui_tools.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/models.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/base.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/chat_history.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/defaults.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/kins/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/kins/action.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/kins/kit.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/loader/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/loader/action.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/loader/kit.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/services/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/tools/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/tools/action.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/registry/tools/kit.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/toolkits/user_profile.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/common/factories.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/profiling/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/profiling/step_timer.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/profiling/task_profiler.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/resilience/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/resilience/bulkhead.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/task_executor.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/core/task_manager/task_session.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/stream_session.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/logger.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/cost_mixin.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/file_history_mixin.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/core/redis.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/core/task_monitor.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/events/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/events/agent_events.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/models.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/ag_ui.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/knowledge_files.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/loaded_tools.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/request_metadata.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/select_schema.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/setup_types.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/module/tool_reference.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/filesystem.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/services.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/certificate.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/channel.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/circuit_breaker.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/client.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/client/grpc.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/log.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/profiling.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/queue.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/redis.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/registry.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/resilience.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/channel.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/grpc.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/server.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/server/servicer.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/task_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/utils/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/settings/utils/channel.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/utils/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/archetype_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/tool_module.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/py.typed +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/cost/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/filesystem/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/default_secret.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/secret/secret_strategy.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/services_config.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/setup/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/storage/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/services/user_profile/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/conditional_schema.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/env_manager.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/env_template.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/exceptions.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/json_structure.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/proto_utils.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/utils/schema_splitter.py +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin.egg-info/top_level.txt +0 -0
- {digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/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.dev5
|
|
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.21.dev1787220377
|
|
456
|
-
Requires-Dist: agentic-mesh-protocol==1.0
|
|
456
|
+
Requires-Dist: agentic-mesh-protocol==1.2.0
|
|
457
457
|
Requires-Dist: agno<3,>=2.8.0
|
|
458
458
|
Requires-Dist: anyio>=4.13.0
|
|
459
459
|
Requires-Dist: grpcio-health-checking==1.82.1
|
|
@@ -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,7 +31,7 @@
|
|
|
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
|
|
34
|
+
"agentic-mesh-protocol==1.2.0",
|
|
35
35
|
"agno>=2.8.0,<3",
|
|
36
36
|
"anyio>=4.13.0",
|
|
37
37
|
"grpcio-health-checking==1.82.1",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"pydantic>=2.12.4",
|
|
42
42
|
"redis[hiredis]>=7.4.0,<9",
|
|
43
43
|
]
|
|
44
|
-
|
|
44
|
+
version = "1.0.5.dev5"
|
|
45
45
|
|
|
46
46
|
[project.optional-dependencies]
|
|
47
47
|
agno = [ "agno>=2.6" ]
|
{digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/agno_adapter.py
RENAMED
|
@@ -676,6 +676,26 @@ class AgnoStreamAdapter:
|
|
|
676
676
|
self._closed_tool_call_ids.add(tool_call_id)
|
|
677
677
|
|
|
678
678
|
content = agno_event.content
|
|
679
|
+
if tool is not None and tool.tool_call_error:
|
|
680
|
+
# Agno flags a raised tool on the completed event, then sends a tool_call_error
|
|
681
|
+
# that the closed-id check drops — so the failure is surfaced here.
|
|
682
|
+
# TODO(validate): AGUI-TOOL-FAILED-STATUS a raised tool surfaces as ToolCallError, not success
|
|
683
|
+
logger.info(
|
|
684
|
+
"[VALIDATE AGUI-TOOL-FAILED-STATUS] tool %s (id=%s) failed: %s",
|
|
685
|
+
tool.tool_name,
|
|
686
|
+
tool_call_id,
|
|
687
|
+
tool.result,
|
|
688
|
+
)
|
|
689
|
+
return [
|
|
690
|
+
ToolCallErrorEvent(
|
|
691
|
+
event=AgentRunEvent.TOOL_CALL_ERROR,
|
|
692
|
+
tool=tool_info,
|
|
693
|
+
error_message=str(tool.result) if tool.result else None,
|
|
694
|
+
subagent_run_id=self._subagent_of(self._run_key),
|
|
695
|
+
timestamp=timestamp,
|
|
696
|
+
metadata=self._last_metadata,
|
|
697
|
+
)
|
|
698
|
+
]
|
|
679
699
|
return [
|
|
680
700
|
ToolCallCompletedEvent(
|
|
681
701
|
event=AgentRunEvent.TOOL_CALL_COMPLETED,
|
|
@@ -11,6 +11,7 @@ import json
|
|
|
11
11
|
import logging
|
|
12
12
|
from typing import TYPE_CHECKING, Any, ClassVar
|
|
13
13
|
|
|
14
|
+
from ag_ui.core.events import Interrupt, RunFinishedInterruptOutcome
|
|
14
15
|
from pydantic import BaseModel, ConfigDict, Field
|
|
15
16
|
|
|
16
17
|
from digitalkin.community.agno.models import PauseInfo
|
|
@@ -268,13 +269,14 @@ class HitlEvents:
|
|
|
268
269
|
run_id: str,
|
|
269
270
|
pending_tool_call_ids: list[str],
|
|
270
271
|
) -> None:
|
|
271
|
-
"""Emit an AG-UI ``RunFinished`` with
|
|
272
|
+
"""Emit an AG-UI ``RunFinished`` with an interrupt outcome.
|
|
272
273
|
|
|
273
274
|
This is the protocol signal telling the front "the run paused on a
|
|
274
|
-
client-side tool; execute it and reply with a ``ToolMessage``".
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
275
|
+
client-side tool; execute it and reply with a ``ToolMessage``". The
|
|
276
|
+
standard ``outcome={type: "interrupt"}`` carries one interrupt per pending
|
|
277
|
+
tool; the legacy ``result.status="awaiting_tool_result"`` is kept for
|
|
278
|
+
existing clients. When an AG-UI run is open, its state first moves the
|
|
279
|
+
tools to ``awaiting_input`` and the run to ``interrupted``.
|
|
278
280
|
|
|
279
281
|
Args:
|
|
280
282
|
context: Current module context.
|
|
@@ -291,11 +293,31 @@ class HitlEvents:
|
|
|
291
293
|
AgUiRunFinishedOutput,
|
|
292
294
|
)
|
|
293
295
|
|
|
296
|
+
run = context.agui_run
|
|
297
|
+
tools = run.state["tools"] if run is not None else {}
|
|
298
|
+
interrupts = [
|
|
299
|
+
Interrupt(
|
|
300
|
+
id=tool_call_id,
|
|
301
|
+
reason="tool_call",
|
|
302
|
+
tool_call_id=tool_call_id,
|
|
303
|
+
message=f"Waiting for the result of {tools.get(tool_call_id, {}).get('name') or 'a frontend tool'}",
|
|
304
|
+
)
|
|
305
|
+
for tool_call_id in pending_tool_call_ids
|
|
306
|
+
]
|
|
307
|
+
if run is not None and run.open:
|
|
308
|
+
run.open = False
|
|
309
|
+
await run.update(
|
|
310
|
+
context,
|
|
311
|
+
*((("tools", tid, "status"), "awaiting_input") for tid in pending_tool_call_ids if tid in tools),
|
|
312
|
+
(("interrupts",), [i.model_dump(mode="json", by_alias=True, exclude_none=True) for i in interrupts]),
|
|
313
|
+
(("run", "status"), "interrupted"),
|
|
314
|
+
)
|
|
294
315
|
output = AgUiOutput(
|
|
295
316
|
root=AgUiRunFinishedOutput(
|
|
296
317
|
event=AgUiRunFinishedEvent(
|
|
297
318
|
thread_id=thread_id,
|
|
298
319
|
run_id=run_id,
|
|
320
|
+
outcome=RunFinishedInterruptOutcome(interrupts=interrupts) if interrupts else None,
|
|
299
321
|
result={
|
|
300
322
|
"status": _AWAITING_STATUS,
|
|
301
323
|
"pending_tool_call_ids": pending_tool_call_ids,
|
{digitalkin-1.0.5.dev3 → digitalkin-1.0.5.dev5}/src/digitalkin/community/agno/module_toolkit.py
RENAMED
|
@@ -25,6 +25,7 @@ from digitalkin.logger import logger
|
|
|
25
25
|
from digitalkin.models.module import ModuleContext
|
|
26
26
|
from digitalkin.models.module.ag_ui import AgUiCustomEventOutput, AgUiOutput
|
|
27
27
|
from digitalkin.models.module.tool_cache import ToolDefinition, ToolModuleInfo
|
|
28
|
+
from digitalkin.services.communication.exceptions import ToolCallError
|
|
28
29
|
|
|
29
30
|
# Default timeout for tool calls in seconds
|
|
30
31
|
DEFAULT_TOOL_TIMEOUT_SECONDS = 300
|
|
@@ -265,7 +266,14 @@ class ModuleToolkit(DkToolkit):
|
|
|
265
266
|
# callbacks is a dict-driven SimpleNamespace (module_context.py:168);
|
|
266
267
|
# send_message may legitimately be absent outside a running job.
|
|
267
268
|
send_message = vars(context.callbacks).get("send_message")
|
|
269
|
+
value = event.get("value")
|
|
270
|
+
url = value.get("url") if isinstance(value, dict) else None
|
|
268
271
|
if send_message is None:
|
|
272
|
+
logger.warning(
|
|
273
|
+
"Dropped custom event '%s' url=%s: no send_message on the agent context",
|
|
274
|
+
event["name"],
|
|
275
|
+
url,
|
|
276
|
+
)
|
|
269
277
|
return
|
|
270
278
|
|
|
271
279
|
try:
|
|
@@ -275,10 +283,15 @@ class ModuleToolkit(DkToolkit):
|
|
|
275
283
|
await send_message(
|
|
276
284
|
AgUiOutput(
|
|
277
285
|
root=AgUiCustomEventOutput(
|
|
278
|
-
event=AgUiCustomEvent(name=event["name"], value=
|
|
286
|
+
event=AgUiCustomEvent(name=event["name"], value=value),
|
|
279
287
|
)
|
|
280
288
|
)
|
|
281
289
|
)
|
|
290
|
+
logger.info(
|
|
291
|
+
"Relayed custom event '%s' url=%s to the agent stream",
|
|
292
|
+
event["name"],
|
|
293
|
+
url,
|
|
294
|
+
)
|
|
282
295
|
except Exception:
|
|
283
296
|
logger.exception("Failed to relay custom event '%s' to the agent stream", event["name"])
|
|
284
297
|
|
|
@@ -467,6 +480,10 @@ class ModuleToolkit(DkToolkit):
|
|
|
467
480
|
Wraps the SDK module's async generator function into an async function
|
|
468
481
|
that Agno can consume, with proper error handling and response formatting.
|
|
469
482
|
|
|
483
|
+
A failure raises ``ToolCallError`` carrying the same JSON body a success-path caller
|
|
484
|
+
would have read: Agno hands ``str(exc)`` to the model unchanged and flags the call
|
|
485
|
+
``tool_call_error``, which is what marks the tool failed for the front.
|
|
486
|
+
|
|
470
487
|
Returns:
|
|
471
488
|
Async function that calls the SDK tool and returns a JSON result, or a
|
|
472
489
|
ToolResult when the tool returned images alongside its text output.
|
|
@@ -509,14 +526,14 @@ class ModuleToolkit(DkToolkit):
|
|
|
509
526
|
duration_ms = round((time.perf_counter() - start_time) * 1000, 2)
|
|
510
527
|
error_msg = f"Tool '{tool_name}' timed out after {timeout}s"
|
|
511
528
|
logger.warning("%s task_id=%s", error_msg, task_id)
|
|
512
|
-
|
|
529
|
+
raise ToolCallError(handle_failure(tool_name, error_msg, duration_ms))
|
|
513
530
|
|
|
514
531
|
except Exception as e:
|
|
515
532
|
outcome = "error"
|
|
516
533
|
duration_ms = round((time.perf_counter() - start_time) * 1000, 2)
|
|
517
534
|
error_msg = f"Failed to call tool '{tool_name}': {e!s}"
|
|
518
535
|
logger.warning("%s task_id=%s", error_msg, task_id, exc_info=True)
|
|
519
|
-
|
|
536
|
+
raise ToolCallError(handle_failure(tool_name, error_msg, duration_ms))
|
|
520
537
|
|
|
521
538
|
else:
|
|
522
539
|
call_timer.mark("gen_consume")
|
|
@@ -536,7 +553,7 @@ class ModuleToolkit(DkToolkit):
|
|
|
536
553
|
|
|
537
554
|
outcome = "no_success"
|
|
538
555
|
error_msg = ModuleToolkit._extract_error_message(error_frame)
|
|
539
|
-
|
|
556
|
+
raise ToolCallError(handle_failure(tool_name, error_msg, duration_ms))
|
|
540
557
|
|
|
541
558
|
finally:
|
|
542
559
|
call_timer.mark("respond")
|
|
@@ -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]
|