digitalkin 1.0.1.dev0__tar.gz → 1.0.2.dev0__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.1.dev0 → digitalkin-1.0.2.dev0}/PKG-INFO +6 -6
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/pyproject.toml +27 -28
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/__version__.py +1 -1
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/community/agno/__init__.py +5 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/community/agno/module_toolkit.py +3 -3
- digitalkin-1.0.2.dev0/src/digitalkin/community/agno/toolkits/__init__.py +20 -0
- digitalkin-1.0.2.dev0/src/digitalkin/community/agno/toolkits/base.py +91 -0
- digitalkin-1.0.2.dev0/src/digitalkin/community/agno/toolkits/chat_history.py +298 -0
- digitalkin-1.0.2.dev0/src/digitalkin/community/agno/toolkits/defaults.py +57 -0
- digitalkin-1.0.2.dev0/src/digitalkin/community/agno/toolkits/registry.py +166 -0
- digitalkin-1.0.2.dev0/src/digitalkin/community/agno/toolkits/user_profile.py +59 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/gateway_servicer.py +14 -8
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/module_server.py +2 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/module_context.py +9 -1
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/services/registry.py +23 -1
- digitalkin-1.0.2.dev0/src/digitalkin/models/settings/registry.py +29 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/_base_module.py +26 -1
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/archetype_module.py +2 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/tool_module.py +4 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/communication/exceptions.py +4 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/registry/default_registry.py +97 -12
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/registry/grpc_registry.py +176 -17
- digitalkin-1.0.2.dev0/src/digitalkin/services/registry/registry_strategy.py +215 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/storage/grpc_storage.py +28 -1
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin.egg-info/PKG-INFO +6 -6
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin.egg-info/SOURCES.txt +7 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin.egg-info/requires.txt +5 -5
- digitalkin-1.0.1.dev0/src/digitalkin/services/registry/registry_strategy.py +0 -128
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/LICENSE +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/README.md +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/base_server/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/base_server/mock/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/base_server/mock/mock_pb2.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/base_server/mock/mock_pb2_grpc.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/base_server/server_async_insecure.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/base_server/server_async_secure.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/base_server/server_sync_insecure.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/base_server/server_sync_secure.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/echo_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/models/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/models/input.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/models/output.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/models/secret.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/models/setup.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/server.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/triggers/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/bench_module/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/modules/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/modules/archetype_with_tools_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/modules/cpu_intensive_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/modules/dynamic_setup_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/modules/minimal_llm_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/modules/text_transform_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/monitoring/digitalkin_observability/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/monitoring/digitalkin_observability/http_server.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/monitoring/digitalkin_observability/interceptors.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/monitoring/digitalkin_observability/metrics.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/monitoring/digitalkin_observability/prometheus.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/monitoring/tests/test_metrics.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/client.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/echo_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/models/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/models/input.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/models/output.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/models/secret.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/models/setup.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/server.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/triggers/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/redis_demo/triggers/message_trigger.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/services/filesystem_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/examples/services/storage_module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/setup.cfg +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/community/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/community/agno/agno_adapter.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/community/agno/agui_tools.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/community/agno/hitl.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/community/agno/models.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/common/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/common/factories.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/job_manager/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/job_manager/base_job_manager.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/job_manager/single_job_manager.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/profiling/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/profiling/step_timer.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/profiling/task_profiler.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/resilience/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/resilience/bulkhead.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/resilience/task_supervisor.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/base_task_manager.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/local_task_manager.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/module_runner.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/redis/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/redis/proto_streams.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/redis/redis_client.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/redis/redis_idempotency.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/redis/redis_signal.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/redis/redis_state.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/remote_task_manager.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/task_executor.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/core/task_manager/task_session.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/_base_server.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/interceptors/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/interceptors/permission.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/interceptors/request_ids.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/m2m_call_registry.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/module_servicer.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/stream_registry.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/stream_session.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/utils/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/utils/circuit_breaker.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/utils/grpc_client_wrapper.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/utils/grpc_error_handler.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/utils/utility_schema_extender.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/grpc_servers/utils/validators.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/logger.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/mixins/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/mixins/agui_mixin.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/mixins/base_mixin.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/mixins/cost_mixin.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/mixins/file_history_mixin.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/mixins/filesystem_mixin.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/mixins/logger_mixin.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/mixins/storage_mixin.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/core/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/core/job_manager_models.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/core/redis.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/core/task_monitor.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/events/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/events/agent_events.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/grpc_servers/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/grpc_servers/circuit_breaker.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/grpc_servers/m2m.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/grpc_servers/models.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/grpc_servers/stream_error_codes.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/grpc_servers/types.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/ag_ui.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/base_types.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/module_types.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/request_metadata.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/select_schema.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/setup_types.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/tool_cache.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/tool_reference.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/module/utility.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/services/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/services/cost.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/services/services.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/services/storage.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/gateway.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/grpc_client.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/log.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/module.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/profiling.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/queue.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/redis.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/resilience.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/server/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/server/channel.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/server/grpc.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/server/server.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/server/servicer.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/task_manager.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/utils/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/settings/utils/channel.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/utils/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/models/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/trigger_handler.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/triggers/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/triggers/healthcheck_ping_trigger.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/triggers/healthcheck_services_trigger.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/modules/triggers/healthcheck_status_trigger.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/py.typed +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/base_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/communication/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/communication/communication_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/communication/default_communication.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/communication/grpc_communication.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/cost/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/cost/cost_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/cost/default_cost.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/cost/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/cost/grpc_cost.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/filesystem/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/filesystem/default_filesystem.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/filesystem/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/filesystem/filesystem_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/filesystem/grpc_filesystem.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/identity/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/identity/default_identity.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/identity/identity_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/registry/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/registry/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/registry/registry_models.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/secret/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/secret/default_secret.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/secret/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/secret/grpc_secret.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/secret/secret_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/services_config.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/services_models.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/setup/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/setup/default_setup.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/setup/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/setup/grpc_setup.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/setup/setup_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/storage/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/storage/default_storage.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/storage/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/storage/storage_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/task_manager/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/task_manager/default_task_manager.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/task_manager/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/task_manager/redis_task_manager.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/task_manager/task_manager_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/user_profile/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/user_profile/default_user_profile.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/user_profile/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/user_profile/grpc_user_profile.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/services/user_profile/user_profile_strategy.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/__init__.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/arg_parser.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/conditional_schema.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/development_mode_action.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/dynamic_schema.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/exceptions.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/llm_ready_schema.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/package_discover.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/proto_utils.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/utils/schema_splitter.py +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin.egg-info/dependency_links.txt +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin.egg-info/top_level.txt +0 -0
- {digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/tests/test_exceptions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalkin
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2.dev0
|
|
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,13 +453,13 @@ Requires-Python: >=3.10
|
|
|
453
453
|
Description-Content-Type: text/markdown
|
|
454
454
|
License-File: LICENSE
|
|
455
455
|
Requires-Dist: ag-ui-protocol>=0.1.18
|
|
456
|
-
Requires-Dist: agentic-mesh-protocol==1.0.
|
|
456
|
+
Requires-Dist: agentic-mesh-protocol==1.0.1.dev2
|
|
457
457
|
Requires-Dist: anyio>=4.13.0
|
|
458
|
-
Requires-Dist: grpcio-health-checking==1.
|
|
459
|
-
Requires-Dist: grpcio-reflection==1.
|
|
460
|
-
Requires-Dist: grpcio-status==1.
|
|
461
|
-
Requires-Dist: pydantic>=2.12.4
|
|
458
|
+
Requires-Dist: grpcio-health-checking==1.82.1
|
|
459
|
+
Requires-Dist: grpcio-reflection==1.82.1
|
|
460
|
+
Requires-Dist: grpcio-status==1.82.1
|
|
462
461
|
Requires-Dist: pydantic-settings>=2.14.1
|
|
462
|
+
Requires-Dist: pydantic>=2.12.4
|
|
463
463
|
Requires-Dist: redis[hiredis]<9,>=7.4.0
|
|
464
464
|
Provides-Extra: agno
|
|
465
465
|
Requires-Dist: agno>=2.6; extra == "agno"
|
|
@@ -28,19 +28,19 @@
|
|
|
28
28
|
|
|
29
29
|
dependencies = [
|
|
30
30
|
"ag-ui-protocol>=0.1.18",
|
|
31
|
-
"agentic-mesh-protocol==1.0.
|
|
31
|
+
"agentic-mesh-protocol==1.0.1.dev2",
|
|
32
32
|
"anyio>=4.13.0",
|
|
33
|
-
"grpcio-health-checking==1.
|
|
34
|
-
"grpcio-reflection==1.
|
|
35
|
-
"grpcio-status==1.
|
|
36
|
-
"pydantic>=2.12.4",
|
|
33
|
+
"grpcio-health-checking==1.82.1",
|
|
34
|
+
"grpcio-reflection==1.82.1",
|
|
35
|
+
"grpcio-status==1.82.1",
|
|
37
36
|
"pydantic-settings>=2.14.1",
|
|
37
|
+
"pydantic>=2.12.4",
|
|
38
38
|
"redis[hiredis]>=7.4.0,<9",
|
|
39
39
|
]
|
|
40
|
-
version = "1.0.
|
|
40
|
+
version = "1.0.2.dev0"
|
|
41
41
|
|
|
42
42
|
[project.optional-dependencies]
|
|
43
|
-
agno
|
|
43
|
+
agno = [ "agno>=2.6" ]
|
|
44
44
|
performance = [ "uvloop>=0.21" ]
|
|
45
45
|
profiling = [
|
|
46
46
|
"pyinstrument>=5.1.2",
|
|
@@ -57,6 +57,22 @@
|
|
|
57
57
|
name = "DigitalKin.ai"
|
|
58
58
|
|
|
59
59
|
[dependency-groups]
|
|
60
|
+
tests = [
|
|
61
|
+
"fakeredis[lua]>=2.35.1",
|
|
62
|
+
"freezegun>=1.5.5",
|
|
63
|
+
"grpcio-testing>=1.81.0",
|
|
64
|
+
"hdrhistogram>=0.10.3",
|
|
65
|
+
"hypothesis>=6.152.8",
|
|
66
|
+
"objgraph>=3.6",
|
|
67
|
+
"psutil>=7.2.2",
|
|
68
|
+
"pytest-asyncio>=1.3.0",
|
|
69
|
+
"pytest-benchmark>=5.2.3",
|
|
70
|
+
"pytest-cov>=7.1.0",
|
|
71
|
+
"pytest-html>=4.2.0",
|
|
72
|
+
"pytest-json-report>=1.5.0",
|
|
73
|
+
"pytest-timeout>=2.4.0",
|
|
74
|
+
"pytest>=9.0.3",
|
|
75
|
+
]
|
|
60
76
|
dev = [
|
|
61
77
|
"build>=1.5.0",
|
|
62
78
|
"bump-my-version>=1.3.0",
|
|
@@ -68,7 +84,7 @@
|
|
|
68
84
|
"twine>=6.2.0",
|
|
69
85
|
"types-grpcio-health-checking>=1.0.0.20260518",
|
|
70
86
|
"types-grpcio-reflection>=1.0.0.20260508",
|
|
71
|
-
"types-grpcio>=1.
|
|
87
|
+
"types-grpcio>=1.82.1.20260711",
|
|
72
88
|
"types-protobuf>=7.34.1.20260518",
|
|
73
89
|
"typos>=1.48.0",
|
|
74
90
|
]
|
|
@@ -96,23 +112,6 @@
|
|
|
96
112
|
"mkdocstrings>=1.0.4",
|
|
97
113
|
"tomli>=2.4.1",
|
|
98
114
|
]
|
|
99
|
-
tests = [
|
|
100
|
-
"agno>=2.6",
|
|
101
|
-
"fakeredis[lua]>=2.35.1",
|
|
102
|
-
"freezegun>=1.5.5",
|
|
103
|
-
"grpcio-testing>=1.81.0",
|
|
104
|
-
"hdrhistogram>=0.10.3",
|
|
105
|
-
"hypothesis>=6.152.8",
|
|
106
|
-
"objgraph>=3.6",
|
|
107
|
-
"psutil>=7.2.2",
|
|
108
|
-
"pytest-asyncio>=1.3.0",
|
|
109
|
-
"pytest-benchmark>=4.0",
|
|
110
|
-
"pytest-cov>=7.1.0",
|
|
111
|
-
"pytest-html>=4.2.0",
|
|
112
|
-
"pytest-json-report>=1.5.0",
|
|
113
|
-
"pytest-timeout>=2.4.0",
|
|
114
|
-
"pytest>=9.0.3",
|
|
115
|
-
]
|
|
116
115
|
[tool.setuptools]
|
|
117
116
|
package-dir = { "" = "src" }
|
|
118
117
|
|
|
@@ -148,12 +147,12 @@
|
|
|
148
147
|
"buck-out",
|
|
149
148
|
"build",
|
|
150
149
|
"dist",
|
|
151
|
-
"scripts",
|
|
152
150
|
"docs/*",
|
|
153
151
|
"examples/*",
|
|
154
152
|
"factory.py",
|
|
155
153
|
"generate_certificates.py",
|
|
156
154
|
"node_modules",
|
|
155
|
+
"scripts",
|
|
157
156
|
"tests/*",
|
|
158
157
|
"venv",
|
|
159
158
|
]
|
|
@@ -270,10 +269,10 @@
|
|
|
270
269
|
skip-magic-trailing-comma = false
|
|
271
270
|
|
|
272
271
|
[tool.mypy]
|
|
273
|
-
exclude = [ "examples", "
|
|
272
|
+
exclude = [ "examples", "scripts", "tests" ]
|
|
274
273
|
ignore_missing_imports = true
|
|
275
|
-
warn_unused_ignores = true
|
|
276
274
|
warn_redundant_casts = true
|
|
275
|
+
warn_unused_ignores = true
|
|
277
276
|
|
|
278
277
|
[tool.pytest.ini_options]
|
|
279
278
|
|
|
@@ -20,6 +20,11 @@ optional ``agno`` dependency at import time and is therefore NOT exported here;
|
|
|
20
20
|
import it directly::
|
|
21
21
|
|
|
22
22
|
from digitalkin.community.agno.module_toolkit import ModuleToolkit
|
|
23
|
+
|
|
24
|
+
Default agent toolkits (``ChatHistoryTools``, ``UserProfileTools``,
|
|
25
|
+
``RegistryTools``, ``DefaultToolkits``) live in
|
|
26
|
+
:mod:`digitalkin.community.agno.toolkits` — imported separately because they
|
|
27
|
+
require the optional ``agno`` dependency at import time.
|
|
23
28
|
"""
|
|
24
29
|
|
|
25
30
|
from digitalkin.community.agno.agno_adapter import AgnoStreamAdapter
|
{digitalkin-1.0.1.dev0 → digitalkin-1.0.2.dev0}/src/digitalkin/community/agno/module_toolkit.py
RENAMED
|
@@ -16,10 +16,10 @@ from typing import Any
|
|
|
16
16
|
|
|
17
17
|
from ag_ui.core.events import CustomEvent as AgUiCustomEvent
|
|
18
18
|
from agno.media import Image
|
|
19
|
-
from agno.tools import Toolkit
|
|
20
19
|
from agno.tools.function import Function, ToolResult
|
|
21
20
|
|
|
22
21
|
from digitalkin.community.agno.models import ToolCallMetadata, ToolOutputMetadata
|
|
22
|
+
from digitalkin.community.agno.toolkits.base import DkToolkit
|
|
23
23
|
from digitalkin.core.profiling.step_timer import StepTimer
|
|
24
24
|
from digitalkin.logger import logger
|
|
25
25
|
from digitalkin.models.module import ModuleContext
|
|
@@ -38,7 +38,7 @@ TOOL_CONTENT_PROTOCOL = "tool_content"
|
|
|
38
38
|
AGUI_CUSTOM_PROTOCOL = "agui_custom"
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
class ModuleToolkit(
|
|
41
|
+
class ModuleToolkit(DkToolkit):
|
|
42
42
|
"""Agno Toolkit wrapper for SDK module tools.
|
|
43
43
|
|
|
44
44
|
Wraps a ToolModuleInfo containing multiple ToolDefinitions into
|
|
@@ -170,7 +170,7 @@ class ModuleToolkit(Toolkit):
|
|
|
170
170
|
or tool_module_info.module_name
|
|
171
171
|
or tool_module_info.slug.replace(":", "_").replace(".", "_")
|
|
172
172
|
)
|
|
173
|
-
super().__init__(name=f"{toolkit_name}_toolkit", tools=agno_functions)
|
|
173
|
+
super().__init__(name=f"{toolkit_name}_toolkit", tools=agno_functions, context=self._context)
|
|
174
174
|
|
|
175
175
|
@property
|
|
176
176
|
def module_id(self) -> str:
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Default Agno toolkits for DigitalKin modules.
|
|
2
|
+
|
|
3
|
+
Requires the optional ``agno`` dependency — importing this subpackage without
|
|
4
|
+
``agno`` installed raises ModuleNotFoundError. The parent
|
|
5
|
+
``digitalkin.community.agno`` package stays importable without agno.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from digitalkin.community.agno.toolkits.base import DkToolkit
|
|
9
|
+
from digitalkin.community.agno.toolkits.chat_history import ChatHistoryTools
|
|
10
|
+
from digitalkin.community.agno.toolkits.defaults import DefaultToolkits
|
|
11
|
+
from digitalkin.community.agno.toolkits.registry import RegistryTools
|
|
12
|
+
from digitalkin.community.agno.toolkits.user_profile import UserProfileTools
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"ChatHistoryTools",
|
|
16
|
+
"DefaultToolkits",
|
|
17
|
+
"DkToolkit",
|
|
18
|
+
"RegistryTools",
|
|
19
|
+
"UserProfileTools",
|
|
20
|
+
]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Shared base for DigitalKin agno toolkits.
|
|
2
|
+
|
|
3
|
+
Codifies the format/return conventions established by
|
|
4
|
+
:class:`~digitalkin.community.agno.module_toolkit.ModuleToolkit`: a canonical
|
|
5
|
+
``{"output"|"error", "metadata"}`` JSON envelope (:meth:`_ok`/:meth:`_fail`) and
|
|
6
|
+
best-effort AG-UI custom-event notifications on the agent's own stream
|
|
7
|
+
(:meth:`_notify`). Every toolkit returns consistently and never raises into the
|
|
8
|
+
agent loop.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
from typing import TYPE_CHECKING, Any
|
|
15
|
+
|
|
16
|
+
from ag_ui.core.events import CustomEvent as AgUiCustomEvent
|
|
17
|
+
from agno.tools import Toolkit
|
|
18
|
+
|
|
19
|
+
from digitalkin.logger import logger
|
|
20
|
+
from digitalkin.models.module.ag_ui import AgUiCustomEventOutput, AgUiOutput
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from digitalkin.models.module import ModuleContext
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class DkToolkit(Toolkit):
|
|
27
|
+
"""Base class for DigitalKin agno toolkits.
|
|
28
|
+
|
|
29
|
+
Subclasses register bound async tool methods and return via :meth:`_ok`/
|
|
30
|
+
:meth:`_fail` so the agent always receives the same envelope and the tool
|
|
31
|
+
never raises. Passing a :class:`ModuleContext` enables :meth:`_notify`,
|
|
32
|
+
which pushes AG-UI custom events onto the caller's gRPC stream.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self, name: str, tools: list[Any], context: ModuleContext | None = None) -> None:
|
|
36
|
+
"""Initialize the toolkit.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
name: Toolkit name registered with Agno.
|
|
40
|
+
tools: Bound tool callables to expose to the agent.
|
|
41
|
+
context: Module context; when present, :meth:`_notify` can emit AG-UI events.
|
|
42
|
+
"""
|
|
43
|
+
self._ctx = context
|
|
44
|
+
super().__init__(name=name, tools=tools)
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def _ok(output: Any, **metadata: Any) -> str:
|
|
48
|
+
"""Build the canonical success envelope.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
output: The tool result payload (JSON-serializable).
|
|
52
|
+
metadata: Extra metadata fields (e.g. ``tool``).
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
JSON string ``{"output": ..., "metadata": {"success": true, ...}}``.
|
|
56
|
+
"""
|
|
57
|
+
return json.dumps({"output": output, "metadata": {"success": True, **metadata}}, ensure_ascii=False)
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def _fail(error: str, **metadata: Any) -> str:
|
|
61
|
+
"""Build the canonical error envelope.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
error: Human/LLM-readable error message.
|
|
65
|
+
metadata: Extra metadata fields (e.g. ``tool``).
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
JSON string ``{"error": ..., "metadata": {"success": false, ...}}``.
|
|
69
|
+
"""
|
|
70
|
+
return json.dumps({"error": error, "metadata": {"success": False, **metadata}}, ensure_ascii=False)
|
|
71
|
+
|
|
72
|
+
async def _notify(self, name: str, value: Any) -> None:
|
|
73
|
+
"""Emit an AG-UI custom event on the agent's output stream (best-effort).
|
|
74
|
+
|
|
75
|
+
No-op when there is no context or ``send_message`` is not installed (e.g. outside a
|
|
76
|
+
running job). Never raises — a notification failure must not fail the tool call.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
name: Custom event name.
|
|
80
|
+
value: Custom event payload (JSON-serializable).
|
|
81
|
+
"""
|
|
82
|
+
if self._ctx is None:
|
|
83
|
+
return
|
|
84
|
+
# callbacks is a dict-driven SimpleNamespace; send_message is attached during prepare().
|
|
85
|
+
send_message = vars(self._ctx.callbacks).get("send_message")
|
|
86
|
+
if send_message is None:
|
|
87
|
+
return
|
|
88
|
+
try:
|
|
89
|
+
await send_message(AgUiOutput(root=AgUiCustomEventOutput(event=AgUiCustomEvent(name=name, value=value))))
|
|
90
|
+
except Exception:
|
|
91
|
+
logger.exception("Failed to emit custom event '%s' to the agent stream", name)
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"""Toolkit for progressive chat-history access (outline first, then read by id).
|
|
2
|
+
|
|
3
|
+
Replaces Agno's built-in ``get_chat_history`` (which dumps every message in full)
|
|
4
|
+
with a two-step, token-cheap surface:
|
|
5
|
+
|
|
6
|
+
1. ``outline_chat_history`` — a metadata-only index (role, who, size, preview) so the
|
|
7
|
+
agent can see *what* exists before loading anything.
|
|
8
|
+
2. ``read_chat_messages`` — fetch full content only for the message ids that matter.
|
|
9
|
+
|
|
10
|
+
The toolkit is leader-only: it is attached to the head agent / team leader and its
|
|
11
|
+
underlying ``aget_session_messages`` call skips team-member sub-conversations.
|
|
12
|
+
|
|
13
|
+
Note: the tools intentionally take NO ``run_context`` parameter. The session id is
|
|
14
|
+
captured at construction and the runtime Agent/Team is late-bound as ``host`` — so
|
|
15
|
+
every tool parameter is a plain builtin type, which keeps the LLM-facing JSON schema
|
|
16
|
+
correct under ``from __future__ import annotations``.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from itertools import starmap
|
|
22
|
+
from typing import TYPE_CHECKING, Any, ClassVar
|
|
23
|
+
|
|
24
|
+
from digitalkin.community.agno.toolkits.base import DkToolkit
|
|
25
|
+
from digitalkin.logger import logger
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from collections.abc import Callable
|
|
29
|
+
|
|
30
|
+
from agno.media import Audio, File, Image, Video
|
|
31
|
+
from agno.models.message import Message
|
|
32
|
+
|
|
33
|
+
from digitalkin.models.module import ModuleContext
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ChatHistoryTools(DkToolkit):
|
|
37
|
+
"""Two-tool chat-history surface bound to a constructed Agent or Team.
|
|
38
|
+
|
|
39
|
+
``host`` is late-bound after the agent/team is created (the same pattern Agno uses
|
|
40
|
+
for its own history tools, which close over the agent + session). Until bound, the
|
|
41
|
+
tools report that history is unavailable rather than raising.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
# Agno message roles -> the labels surfaced to the LLM.
|
|
45
|
+
_ROLE_TO_LABEL: ClassVar[dict[str, str]] = {"user": "human", "assistant": "ai", "tool": "tool", "system": "system"}
|
|
46
|
+
|
|
47
|
+
# Requested label -> Agno ``skip_roles`` (which roles to exclude). ``system`` is special-cased.
|
|
48
|
+
_LABEL_TO_SKIP: ClassVar[dict[str, list[str]]] = {
|
|
49
|
+
"human": ["system", "assistant", "tool"],
|
|
50
|
+
"ai": ["system", "user", "tool"],
|
|
51
|
+
"tool": ["system", "user", "assistant"],
|
|
52
|
+
"system": [],
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
def __init__(self, session_id: str | None = None, context: ModuleContext | None = None) -> None:
|
|
56
|
+
"""Register the outline + read tools.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
session_id: The session whose history to read. Captured here (it is known at
|
|
60
|
+
agent-construction time) so the tools need no ``run_context`` parameter.
|
|
61
|
+
context: Module context; enables AG-UI notifications via the base toolkit.
|
|
62
|
+
"""
|
|
63
|
+
super().__init__(
|
|
64
|
+
name="chat_history_tools",
|
|
65
|
+
tools=[self.outline_chat_history, self.read_chat_messages],
|
|
66
|
+
context=context,
|
|
67
|
+
)
|
|
68
|
+
self._session_id = session_id
|
|
69
|
+
# Late-bound to the runtime Agent (single mode) or Team (team mode).
|
|
70
|
+
self.host: Any = None
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def bind_host(tools: list[Any] | Callable[..., list[Any]] | None, host: Any) -> None:
|
|
74
|
+
"""Late-bind the runtime Agent/Team into the ChatHistoryTools instance, if present.
|
|
75
|
+
|
|
76
|
+
The toolkit needs a handle to call ``aget_session_messages``, which only exists once
|
|
77
|
+
the agent/team is constructed. In team mode call this again with the ``Team`` so
|
|
78
|
+
history reads target the team session rather than the bare head agent.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
tools: The head tools — either the raw list or an
|
|
82
|
+
:meth:`AguiTools.make_tools_factory` callable (calling it without a
|
|
83
|
+
RunContext returns the base list). Binds the first ChatHistoryTools
|
|
84
|
+
found; no-op if absent.
|
|
85
|
+
host: The constructed Agent or Team to bind as the history source.
|
|
86
|
+
"""
|
|
87
|
+
if callable(tools) and not isinstance(tools, list):
|
|
88
|
+
tools = tools(None)
|
|
89
|
+
if not isinstance(tools, list):
|
|
90
|
+
return
|
|
91
|
+
for tool in tools:
|
|
92
|
+
if isinstance(tool, ChatHistoryTools):
|
|
93
|
+
tool.host = host
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
async def outline_chat_history(
|
|
97
|
+
self,
|
|
98
|
+
role: str | None = None,
|
|
99
|
+
first: int | None = None,
|
|
100
|
+
last: int | None = None,
|
|
101
|
+
offset: int = 0,
|
|
102
|
+
) -> str:
|
|
103
|
+
"""List the conversation as a cheap metadata index — call this FIRST.
|
|
104
|
+
|
|
105
|
+
Returns one lightweight row per message (role, who, timestamp, size and a short
|
|
106
|
+
preview) WITHOUT the full content, so it is safe to scan a long thread. Once you
|
|
107
|
+
know which messages you need, call ``read_chat_messages`` with their ids to get
|
|
108
|
+
full content. Prefer this over loading everything.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
role: Filter by message type: "human", "ai", "tool", or "system".
|
|
112
|
+
Omit to get all messages except the system prompt.
|
|
113
|
+
first: Return only the first N messages (oldest). Use this to reach the start
|
|
114
|
+
of the conversation, e.g. the user's first request.
|
|
115
|
+
last: Return only the last N messages (most recent). Mutually exclusive with first.
|
|
116
|
+
offset: Skip this many messages from the relevant end (for pagination).
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
JSON string: {"total", "returned", "offset", "messages": [{"ord", "id", "role",
|
|
120
|
+
"ts", "chars", "preview", ...}]}. "total" is the full count after filtering, so
|
|
121
|
+
an empty "messages" with "total": 0 means the thread is genuinely empty.
|
|
122
|
+
"""
|
|
123
|
+
if role is not None and role not in self._LABEL_TO_SKIP:
|
|
124
|
+
msg = f"invalid role '{role}'; use one of: human, ai, tool, system"
|
|
125
|
+
return self._fail(msg, tool="outline_chat_history")
|
|
126
|
+
|
|
127
|
+
skip_roles = self._LABEL_TO_SKIP[role] if role is not None else ["system"]
|
|
128
|
+
messages = await self._fetch(skip_roles)
|
|
129
|
+
if messages is None:
|
|
130
|
+
return self._fail("chat history is not available", tool="outline_chat_history")
|
|
131
|
+
if role == "system":
|
|
132
|
+
messages = [m for m in messages if m.role == "system"]
|
|
133
|
+
|
|
134
|
+
rows = list(starmap(self._index_row, enumerate(messages)))
|
|
135
|
+
total = len(rows)
|
|
136
|
+
|
|
137
|
+
if first is not None:
|
|
138
|
+
sliced = rows[offset : offset + max(first, 0)]
|
|
139
|
+
elif last is not None:
|
|
140
|
+
end = max(total - offset, 0)
|
|
141
|
+
start = max(end - max(last, 0), 0)
|
|
142
|
+
sliced = rows[start:end]
|
|
143
|
+
else:
|
|
144
|
+
sliced = rows[offset:]
|
|
145
|
+
|
|
146
|
+
return self._ok(
|
|
147
|
+
{"total": total, "returned": len(sliced), "offset": offset, "messages": sliced},
|
|
148
|
+
tool="outline_chat_history",
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
async def read_chat_messages(
|
|
152
|
+
self,
|
|
153
|
+
ids: list[str],
|
|
154
|
+
max_content_chars: int = 4000,
|
|
155
|
+
) -> str:
|
|
156
|
+
"""Fetch the full content of specific messages by id (from ``outline_chat_history``).
|
|
157
|
+
|
|
158
|
+
Use the "id" values returned by ``outline_chat_history`` — they are stable even as
|
|
159
|
+
the conversation grows (unlike the "ord" position). Long bodies are truncated to
|
|
160
|
+
``max_content_chars``; attached media is returned as a reference, never inlined.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
ids: The message ids to read, taken from an earlier ``outline_chat_history`` call.
|
|
164
|
+
max_content_chars: Truncate each message body to this many characters (default 4000).
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
JSON string: {"messages": [{"id", "role", "ts", "content", ...}], "missing": [...]}.
|
|
168
|
+
Any requested id that no longer exists is listed under "missing".
|
|
169
|
+
"""
|
|
170
|
+
if not ids:
|
|
171
|
+
return self._ok({"messages": [], "missing": []}, tool="read_chat_messages")
|
|
172
|
+
|
|
173
|
+
messages = await self._fetch(skip_roles=[])
|
|
174
|
+
if messages is None:
|
|
175
|
+
return self._fail("chat history is not available", tool="read_chat_messages")
|
|
176
|
+
|
|
177
|
+
by_id = {message.id: message for message in messages}
|
|
178
|
+
out: list[dict[str, Any]] = []
|
|
179
|
+
missing: list[str] = []
|
|
180
|
+
for message_id in ids:
|
|
181
|
+
message = by_id.get(message_id)
|
|
182
|
+
if message is None:
|
|
183
|
+
missing.append(message_id)
|
|
184
|
+
else:
|
|
185
|
+
out.append(self._full_row(message, max_content_chars))
|
|
186
|
+
|
|
187
|
+
return self._ok({"messages": out, "missing": missing}, tool="read_chat_messages")
|
|
188
|
+
|
|
189
|
+
async def _fetch(self, skip_roles: list[str]) -> list[Message] | None:
|
|
190
|
+
"""Load session messages via the bound agent/team, or None if unavailable.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
skip_roles: Roles to exclude (passed to Agno's ``aget_session_messages``).
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
The deduplicated session messages, or None if no host is bound or the call fails.
|
|
197
|
+
"""
|
|
198
|
+
if self.host is None:
|
|
199
|
+
logger.warning("ChatHistoryTools called before host was bound")
|
|
200
|
+
return None
|
|
201
|
+
try:
|
|
202
|
+
return await self.host.aget_session_messages(
|
|
203
|
+
session_id=self._session_id,
|
|
204
|
+
skip_roles=skip_roles,
|
|
205
|
+
skip_history_messages=True,
|
|
206
|
+
)
|
|
207
|
+
except Exception as error:
|
|
208
|
+
logger.warning("ChatHistoryTools: failed to load session messages: %s", error)
|
|
209
|
+
return None
|
|
210
|
+
|
|
211
|
+
def _index_row(self, ordinal: int, message: Message) -> dict[str, Any]:
|
|
212
|
+
"""Build a metadata-only index row for one message.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
ordinal: Position of the message in the filtered list (display-only).
|
|
216
|
+
message: The Agno message.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
A compact dict with role, id, timestamp, size and a short preview.
|
|
220
|
+
"""
|
|
221
|
+
content = message.get_content_string() or ""
|
|
222
|
+
row: dict[str, Any] = {
|
|
223
|
+
"ord": ordinal,
|
|
224
|
+
"id": message.id,
|
|
225
|
+
"role": self._ROLE_TO_LABEL.get(message.role, message.role),
|
|
226
|
+
"ts": message.created_at,
|
|
227
|
+
"chars": len(content),
|
|
228
|
+
"preview": content[:120],
|
|
229
|
+
}
|
|
230
|
+
if message.images or message.files or message.videos or message.audio:
|
|
231
|
+
row["has_media"] = True
|
|
232
|
+
if message.from_history:
|
|
233
|
+
row["from_history"] = True
|
|
234
|
+
if message.role == "tool":
|
|
235
|
+
row["name"] = message.tool_name
|
|
236
|
+
if message.tool_call_error:
|
|
237
|
+
row["error"] = True
|
|
238
|
+
return row
|
|
239
|
+
|
|
240
|
+
def _full_row(self, message: Message, max_content_chars: int) -> dict[str, Any]:
|
|
241
|
+
"""Build a full-content row for one message, truncating the body if needed.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
message: The Agno message.
|
|
245
|
+
max_content_chars: Maximum body length before truncation.
|
|
246
|
+
|
|
247
|
+
Returns:
|
|
248
|
+
A dict with the (possibly truncated) content plus media references.
|
|
249
|
+
"""
|
|
250
|
+
content = message.get_content_string() or ""
|
|
251
|
+
truncated = len(content) > max_content_chars
|
|
252
|
+
if truncated:
|
|
253
|
+
content = content[:max_content_chars] + " […truncated]"
|
|
254
|
+
|
|
255
|
+
row: dict[str, Any] = {
|
|
256
|
+
"id": message.id,
|
|
257
|
+
"role": self._ROLE_TO_LABEL.get(message.role, message.role),
|
|
258
|
+
"ts": message.created_at,
|
|
259
|
+
"content": content,
|
|
260
|
+
}
|
|
261
|
+
if truncated:
|
|
262
|
+
row["truncated"] = True
|
|
263
|
+
if message.role == "tool":
|
|
264
|
+
row["name"] = message.tool_name
|
|
265
|
+
if message.tool_call_error:
|
|
266
|
+
row["error"] = True
|
|
267
|
+
media = self._media_refs(message)
|
|
268
|
+
if media:
|
|
269
|
+
row["media"] = media
|
|
270
|
+
return row
|
|
271
|
+
|
|
272
|
+
@staticmethod
|
|
273
|
+
def _media_refs(message: Message) -> list[dict[str, Any]]:
|
|
274
|
+
"""Build reference descriptors for attached media — never the raw bytes.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
message: The Agno message.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
A list of {"kind", "id", "mime_type", "format"} descriptors.
|
|
281
|
+
"""
|
|
282
|
+
groups: tuple[tuple[str, Any], ...] = (
|
|
283
|
+
("image", message.images),
|
|
284
|
+
("audio", message.audio),
|
|
285
|
+
("video", message.videos),
|
|
286
|
+
("file", message.files),
|
|
287
|
+
)
|
|
288
|
+
refs: list[dict[str, Any]] = []
|
|
289
|
+
for kind, items in groups:
|
|
290
|
+
for item in items or []:
|
|
291
|
+
media_item: Image | Audio | Video | File = item
|
|
292
|
+
refs.append({
|
|
293
|
+
"kind": kind,
|
|
294
|
+
"id": media_item.id,
|
|
295
|
+
"mime_type": media_item.mime_type,
|
|
296
|
+
"format": media_item.format,
|
|
297
|
+
})
|
|
298
|
+
return refs
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""One-call assembler for the default DigitalKin toolkits."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
from digitalkin.community.agno.toolkits.chat_history import ChatHistoryTools
|
|
8
|
+
from digitalkin.community.agno.toolkits.registry import RegistryTools
|
|
9
|
+
from digitalkin.community.agno.toolkits.user_profile import UserProfileTools
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
|
|
14
|
+
from agno.tools import Toolkit
|
|
15
|
+
|
|
16
|
+
from digitalkin.models.module.module_context import ModuleContext
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DefaultToolkits:
|
|
20
|
+
"""Assemble the default DigitalKin toolkits (chat history, user profile, registry).
|
|
21
|
+
|
|
22
|
+
Two-phase usage — ChatHistoryTools needs the constructed Agent/Team::
|
|
23
|
+
|
|
24
|
+
tools = DefaultToolkits.build(context, session_id=sid)
|
|
25
|
+
agent = Agent(tools=AguiTools.make_tools_factory(tools), cache_callables=False, ...)
|
|
26
|
+
DefaultToolkits.bind_host(tools, agent)
|
|
27
|
+
|
|
28
|
+
In team mode call :meth:`bind_host` again with the ``Team`` so history reads
|
|
29
|
+
target the team session rather than the bare head agent.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def build(context: ModuleContext, session_id: str | None = None) -> list[Toolkit]:
|
|
34
|
+
"""Build the default toolkits from a module context.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
context: The module context carrying the user_profile and registry services.
|
|
38
|
+
session_id: The Agno session whose chat history should be readable.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
[ChatHistoryTools, UserProfileTools, RegistryTools].
|
|
42
|
+
"""
|
|
43
|
+
return [
|
|
44
|
+
ChatHistoryTools(session_id=session_id, context=context),
|
|
45
|
+
UserProfileTools(context.user_profile, context=context),
|
|
46
|
+
RegistryTools(context.registry, context=context),
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def bind_host(tools: list[Any] | Callable[..., list[Any]] | None, host: Any) -> None:
|
|
51
|
+
"""Late-bind the constructed Agent/Team into ChatHistoryTools (delegates).
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
tools: The tools list (or a make_tools_factory callable) containing the toolkits.
|
|
55
|
+
host: The constructed Agent or Team to bind as the history source.
|
|
56
|
+
"""
|
|
57
|
+
ChatHistoryTools.bind_host(tools, host)
|