neuroglia-python 0.7.10__tar.gz → 0.8.0__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.
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/PKG-INFO +1 -1
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/pyproject.toml +1 -1
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/__init__.py +91 -1
- neuroglia_python-0.8.0/src/neuroglia/a2a/__init__.py +76 -0
- neuroglia_python-0.8.0/src/neuroglia/a2a/protocol.py +354 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/__init__.py +31 -1
- neuroglia_python-0.8.0/src/neuroglia/data/agent/__init__.py +97 -0
- neuroglia_python-0.8.0/src/neuroglia/data/agent/agent_events.py +572 -0
- neuroglia_python-0.8.0/src/neuroglia/data/agent/agent_state.py +345 -0
- neuroglia_python-0.8.0/src/neuroglia/data/conversation/__init__.py +76 -0
- neuroglia_python-0.8.0/src/neuroglia/data/conversation/execution_context.py +247 -0
- neuroglia_python-0.8.0/src/neuroglia/data/conversation/message.py +333 -0
- neuroglia_python-0.8.0/src/neuroglia/data/conversation/session.py +149 -0
- neuroglia_python-0.8.0/src/neuroglia/data/conversation/tool_call.py +229 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/LICENSE +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/README.md +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/application/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/application/background_scheduler.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/coordination/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/coordination/abstractions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/coordination/leader_election.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/coordination/redis_backend.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/core/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/core/module_loader.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/core/operation_result.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/core/problem_details.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/core/type_extensions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/core/type_finder.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/core/type_registry.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/abstractions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/exceptions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/abstractions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/event_sourcing/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/event_sourcing/abstractions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/event_sourcing/event_sourcing_repository.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/event_sourcing/event_store/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/event_sourcing/event_store/event_store.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/event_sourcing/read_model_reconciliator.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/filesystem/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/filesystem/filesystem_repository.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/memory/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/memory/memory_repository.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/mongo/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/mongo/enhanced_mongo_repository.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/mongo/mongo_repository.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/mongo/motor_query.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/mongo/motor_repository.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/mongo/serialization_helper.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/mongo/typed_mongo_query.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/resources/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/resources/in_memory_storage_backend.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/resources/postgres_resource_store.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/resources/redis_resource_store.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/resources/resource_repository.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/infrastructure/tracing_mixin.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/queries/generic/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/queries/generic/get_by_id_query.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/queries/generic/list_query.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/queryable.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/resources/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/resources/abstractions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/resources/controller.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/resources/serializers/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/resources/serializers/xml_serializer.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/resources/serializers/yaml_serializer.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/resources/state_machine.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/resources/watcher.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/data/unit_of_work.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/dependency_injection/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/dependency_injection/service_provider.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/dependency_injection/service_provider_backup.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/cloud_events/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/cloud_events/cloud_event.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/cloud_events/decorators.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/cloud_events/infrastructure/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_bus.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_ingestor.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_middleware.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_publisher.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/eventing/tracing.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/expressions/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/expressions/javascript_expression_translator.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/extensions/cqrs_metrics_extensions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/extensions/mediator_extensions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/extensions/state_persistence_extensions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/hosting/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/hosting/abstractions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/hosting/configuration/data_access_layer.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/hosting/web.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/integration/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/integration/cache_repository.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/integration/http_service_client.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/integration/models.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/logging/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/logging/logger.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mapping/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mapping/mapper.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mediation/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mediation/behaviors/domain_event_cloudevent_behavior.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mediation/behaviors/domain_event_dispatching_middleware.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mediation/mediator.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mediation/metrics_middleware.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mediation/pipeline_behavior.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mediation/simple.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mediation/tracing_middleware.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mvc/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/mvc/controller_base.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/observability/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/observability/framework.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/observability/logging.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/observability/metrics.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/observability/otel_sdk.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/observability/settings.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/observability/tracing.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/py.typed +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/reactive/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/reactive/rx_async.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/serialization/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/serialization/abstractions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/serialization/aggregate_serializer.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/serialization/json.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/utils/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/utils/camel_model.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/utils/case_conversion.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/validation/__init__.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/validation/business_rules.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/validation/exceptions.py +0 -0
- {neuroglia_python-0.7.10 → neuroglia_python-0.8.0}/src/neuroglia/validation/validators.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "neuroglia-python"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.8.0"
|
|
4
4
|
description = "Port from .NET to Python of the Neuroglia Framework"
|
|
5
5
|
authors = ["Charles d'Avernas <charles.davernas@neuroglia.io>", "Bruno van de Werve <bvandewe@gmail.com>"]
|
|
6
6
|
license = "Apache"
|
|
@@ -32,6 +32,24 @@ __all__ = [
|
|
|
32
32
|
"Entity",
|
|
33
33
|
"DomainEvent",
|
|
34
34
|
"Repository",
|
|
35
|
+
# Agent module (new in 0.8.0)
|
|
36
|
+
"BaseAgentState",
|
|
37
|
+
"TeamMembership",
|
|
38
|
+
"KnowledgeScope",
|
|
39
|
+
"AgentCapability",
|
|
40
|
+
# A2A protocol (new in 0.8.0)
|
|
41
|
+
"TaskRequest",
|
|
42
|
+
"TaskResponse",
|
|
43
|
+
"AgentIdentity",
|
|
44
|
+
"TaskPriority",
|
|
45
|
+
"TaskStatus",
|
|
46
|
+
# Conversation building blocks (new in 0.8.0)
|
|
47
|
+
"Message",
|
|
48
|
+
"MessageRole",
|
|
49
|
+
"ToolCall",
|
|
50
|
+
"ToolResult",
|
|
51
|
+
"ExecutionContext",
|
|
52
|
+
"Session",
|
|
35
53
|
# Optional components (import may fail)
|
|
36
54
|
"ControllerBase",
|
|
37
55
|
"EventStore",
|
|
@@ -62,7 +80,7 @@ __all__ = [
|
|
|
62
80
|
]
|
|
63
81
|
|
|
64
82
|
# Framework metadata
|
|
65
|
-
__version__ = "0.
|
|
83
|
+
__version__ = "0.8.0"
|
|
66
84
|
__author__ = "Neuroglia Team"
|
|
67
85
|
__email__ = "team@neuroglia.io"
|
|
68
86
|
__license__ = "Apache"
|
|
@@ -141,6 +159,78 @@ def __getattr__(name: str):
|
|
|
141
159
|
except ImportError:
|
|
142
160
|
pass
|
|
143
161
|
|
|
162
|
+
# Agent module (new in 0.8.0)
|
|
163
|
+
elif name in ["BaseAgentState", "TeamMembership", "KnowledgeScope", "AgentCapability"]:
|
|
164
|
+
try:
|
|
165
|
+
from .data.agent import (
|
|
166
|
+
AgentCapability,
|
|
167
|
+
BaseAgentState,
|
|
168
|
+
KnowledgeScope,
|
|
169
|
+
TeamMembership,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
if name == "BaseAgentState":
|
|
173
|
+
return BaseAgentState
|
|
174
|
+
elif name == "TeamMembership":
|
|
175
|
+
return TeamMembership
|
|
176
|
+
elif name == "KnowledgeScope":
|
|
177
|
+
return KnowledgeScope
|
|
178
|
+
elif name == "AgentCapability":
|
|
179
|
+
return AgentCapability
|
|
180
|
+
except ImportError:
|
|
181
|
+
pass
|
|
182
|
+
|
|
183
|
+
# A2A protocol (new in 0.8.0)
|
|
184
|
+
elif name in ["TaskRequest", "TaskResponse", "AgentIdentity", "TaskPriority", "TaskStatus"]:
|
|
185
|
+
try:
|
|
186
|
+
from .a2a import (
|
|
187
|
+
AgentIdentity,
|
|
188
|
+
TaskPriority,
|
|
189
|
+
TaskRequest,
|
|
190
|
+
TaskResponse,
|
|
191
|
+
TaskStatus,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
if name == "TaskRequest":
|
|
195
|
+
return TaskRequest
|
|
196
|
+
elif name == "TaskResponse":
|
|
197
|
+
return TaskResponse
|
|
198
|
+
elif name == "AgentIdentity":
|
|
199
|
+
return AgentIdentity
|
|
200
|
+
elif name == "TaskPriority":
|
|
201
|
+
return TaskPriority
|
|
202
|
+
elif name == "TaskStatus":
|
|
203
|
+
return TaskStatus
|
|
204
|
+
except ImportError:
|
|
205
|
+
pass
|
|
206
|
+
|
|
207
|
+
# Conversation building blocks (new in 0.8.0)
|
|
208
|
+
elif name in ["Message", "MessageRole", "ToolCall", "ToolResult", "ExecutionContext", "Session"]:
|
|
209
|
+
try:
|
|
210
|
+
from .data.conversation import (
|
|
211
|
+
ExecutionContext,
|
|
212
|
+
Message,
|
|
213
|
+
MessageRole,
|
|
214
|
+
Session,
|
|
215
|
+
ToolCall,
|
|
216
|
+
ToolResult,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
if name == "Message":
|
|
220
|
+
return Message
|
|
221
|
+
elif name == "MessageRole":
|
|
222
|
+
return MessageRole
|
|
223
|
+
elif name == "ToolCall":
|
|
224
|
+
return ToolCall
|
|
225
|
+
elif name == "ToolResult":
|
|
226
|
+
return ToolResult
|
|
227
|
+
elif name == "ExecutionContext":
|
|
228
|
+
return ExecutionContext
|
|
229
|
+
elif name == "Session":
|
|
230
|
+
return Session
|
|
231
|
+
except ImportError:
|
|
232
|
+
pass
|
|
233
|
+
|
|
144
234
|
# Domain abstractions
|
|
145
235
|
elif name in ["Entity", "DomainEvent"]:
|
|
146
236
|
try:
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Agent-to-Agent (A2A) protocol module.
|
|
2
|
+
|
|
3
|
+
Provides types and utilities for inter-agent communication
|
|
4
|
+
in the AIX distributed agent ecosystem.
|
|
5
|
+
|
|
6
|
+
This module defines:
|
|
7
|
+
- TaskPriority, TaskStatus: Enums for task lifecycle
|
|
8
|
+
- AgentIdentity: Identity for A2A routing
|
|
9
|
+
- TaskRequest: Delegation request from source to target agent
|
|
10
|
+
- TaskResponse: Response from target back to source
|
|
11
|
+
|
|
12
|
+
The protocol supports:
|
|
13
|
+
- Capability-based routing (via target_team_id + required_capabilities)
|
|
14
|
+
- Direct agent addressing (via target_agent_id)
|
|
15
|
+
- Synchronous and asynchronous delegation patterns
|
|
16
|
+
- Context sharing between agents
|
|
17
|
+
|
|
18
|
+
Examples:
|
|
19
|
+
```python
|
|
20
|
+
from neuroglia.a2a import (
|
|
21
|
+
TaskRequest,
|
|
22
|
+
TaskResponse,
|
|
23
|
+
AgentIdentity,
|
|
24
|
+
TaskPriority,
|
|
25
|
+
TaskStatus,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Create delegation request
|
|
29
|
+
request = TaskRequest(
|
|
30
|
+
task_id="task-123",
|
|
31
|
+
correlation_id="corr-456",
|
|
32
|
+
source=AgentIdentity(
|
|
33
|
+
agent_id="personal-agent",
|
|
34
|
+
agent_type="personal",
|
|
35
|
+
owner_id="user-789"
|
|
36
|
+
),
|
|
37
|
+
target_team_id="research-team",
|
|
38
|
+
intent="analyze_document",
|
|
39
|
+
description="Analyze quarterly report",
|
|
40
|
+
priority=TaskPriority.HIGH
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# Handle response
|
|
44
|
+
response = TaskResponse(
|
|
45
|
+
task_id="task-123",
|
|
46
|
+
correlation_id="corr-456",
|
|
47
|
+
responder=AgentIdentity(
|
|
48
|
+
agent_id="team-agent",
|
|
49
|
+
agent_type="team_member",
|
|
50
|
+
team_id="research-team"
|
|
51
|
+
),
|
|
52
|
+
status=TaskStatus.COMPLETED,
|
|
53
|
+
result={"insights": [...]}
|
|
54
|
+
)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
See Also:
|
|
58
|
+
- Agent Module: neuroglia.data.agent
|
|
59
|
+
- Implementation Plan: /docs/specs/personal-agent-implementation-plan.md
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
from neuroglia.a2a.protocol import (
|
|
63
|
+
AgentIdentity,
|
|
64
|
+
TaskPriority,
|
|
65
|
+
TaskRequest,
|
|
66
|
+
TaskResponse,
|
|
67
|
+
TaskStatus,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
__all__ = [
|
|
71
|
+
"TaskPriority",
|
|
72
|
+
"TaskStatus",
|
|
73
|
+
"AgentIdentity",
|
|
74
|
+
"TaskRequest",
|
|
75
|
+
"TaskResponse",
|
|
76
|
+
]
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"""Agent-to-Agent (A2A) protocol types.
|
|
2
|
+
|
|
3
|
+
Defines the message types for inter-agent communication in the AIX
|
|
4
|
+
distributed agent ecosystem. Used for task delegation between:
|
|
5
|
+
- Personal Agents (in Agent-Host)
|
|
6
|
+
- Team Agents (in Agent-Runtime)
|
|
7
|
+
|
|
8
|
+
The protocol supports both synchronous and asynchronous delegation
|
|
9
|
+
patterns with full context sharing and result routing.
|
|
10
|
+
|
|
11
|
+
Examples:
|
|
12
|
+
```python
|
|
13
|
+
from neuroglia.a2a import TaskRequest, TaskResponse, AgentIdentity
|
|
14
|
+
|
|
15
|
+
# Create a delegation request
|
|
16
|
+
source = AgentIdentity(
|
|
17
|
+
agent_id="personal-agent-123",
|
|
18
|
+
agent_type="personal",
|
|
19
|
+
owner_id="user-456"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
request = TaskRequest(
|
|
23
|
+
task_id="task-789",
|
|
24
|
+
correlation_id="corr-abc",
|
|
25
|
+
source=source,
|
|
26
|
+
target_team_id="research-team",
|
|
27
|
+
intent="analyze_document",
|
|
28
|
+
description="Analyze the attached document for key insights",
|
|
29
|
+
payload={"document_id": "doc-xyz"}
|
|
30
|
+
)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
See Also:
|
|
34
|
+
- Personal Agent Architecture: /docs/specs/personal-agent-architecture.md
|
|
35
|
+
- Implementation Plan: /docs/specs/personal-agent-implementation-plan.md
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
from dataclasses import dataclass, field
|
|
39
|
+
from datetime import datetime
|
|
40
|
+
from enum import Enum
|
|
41
|
+
from typing import Any
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class TaskPriority(str, Enum):
|
|
45
|
+
"""Priority level for A2A task requests.
|
|
46
|
+
|
|
47
|
+
Affects queue ordering and timeout handling in Agent-Runtime.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
LOW = "low"
|
|
51
|
+
NORMAL = "normal"
|
|
52
|
+
HIGH = "high"
|
|
53
|
+
CRITICAL = "critical"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class TaskStatus(str, Enum):
|
|
57
|
+
"""Execution status for A2A tasks.
|
|
58
|
+
|
|
59
|
+
Tracks the lifecycle of a delegated task from request to completion.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
PENDING = "pending"
|
|
63
|
+
QUEUED = "queued"
|
|
64
|
+
RUNNING = "running"
|
|
65
|
+
WAITING_DELEGATION = "waiting_delegation"
|
|
66
|
+
COMPLETED = "completed"
|
|
67
|
+
FAILED = "failed"
|
|
68
|
+
CANCELLED = "cancelled"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class AgentIdentity:
|
|
73
|
+
"""Identity of an agent in A2A communication.
|
|
74
|
+
|
|
75
|
+
Provides the minimum information needed to identify and route
|
|
76
|
+
messages to/from an agent.
|
|
77
|
+
|
|
78
|
+
Attributes:
|
|
79
|
+
agent_id: Unique identifier for the agent
|
|
80
|
+
agent_type: Type of agent ("personal" | "team_member" | "autonomous")
|
|
81
|
+
owner_id: ID of the owning user, if applicable
|
|
82
|
+
team_id: ID of the agent's team, if applicable
|
|
83
|
+
|
|
84
|
+
Examples:
|
|
85
|
+
```python
|
|
86
|
+
# Personal agent identity
|
|
87
|
+
personal = AgentIdentity(
|
|
88
|
+
agent_id="agent-123",
|
|
89
|
+
agent_type="personal",
|
|
90
|
+
owner_id="user-456"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Team agent identity
|
|
94
|
+
team_agent = AgentIdentity(
|
|
95
|
+
agent_id="agent-789",
|
|
96
|
+
agent_type="team_member",
|
|
97
|
+
team_id="research-team"
|
|
98
|
+
)
|
|
99
|
+
```
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
agent_id: str
|
|
103
|
+
agent_type: str
|
|
104
|
+
owner_id: str | None = None
|
|
105
|
+
team_id: str | None = None
|
|
106
|
+
|
|
107
|
+
def to_dict(self) -> dict[str, Any]:
|
|
108
|
+
"""Serialize to dictionary for transport."""
|
|
109
|
+
return {
|
|
110
|
+
"agent_id": self.agent_id,
|
|
111
|
+
"agent_type": self.agent_type,
|
|
112
|
+
"owner_id": self.owner_id,
|
|
113
|
+
"team_id": self.team_id,
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
def from_dict(cls, data: dict[str, Any]) -> "AgentIdentity":
|
|
118
|
+
"""Deserialize from dictionary."""
|
|
119
|
+
return cls(
|
|
120
|
+
agent_id=data["agent_id"],
|
|
121
|
+
agent_type=data["agent_type"],
|
|
122
|
+
owner_id=data.get("owner_id"),
|
|
123
|
+
team_id=data.get("team_id"),
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@dataclass
|
|
128
|
+
class TaskRequest:
|
|
129
|
+
"""A2A delegation request from one agent to another.
|
|
130
|
+
|
|
131
|
+
Encapsulates all information needed for an agent to delegate
|
|
132
|
+
a task to another agent or team.
|
|
133
|
+
|
|
134
|
+
Routing:
|
|
135
|
+
- Set target_team_id for capability-based routing (recommended)
|
|
136
|
+
- Set target_agent_id for direct agent addressing
|
|
137
|
+
- Set required_capabilities for capability matching
|
|
138
|
+
|
|
139
|
+
Attributes:
|
|
140
|
+
task_id: Unique identifier for this task
|
|
141
|
+
correlation_id: ID for response routing back to requester
|
|
142
|
+
source: Identity of the requesting agent
|
|
143
|
+
target_team_id: Target team for capability-based routing
|
|
144
|
+
target_agent_id: Target agent for direct addressing
|
|
145
|
+
required_capabilities: Capabilities needed to handle this task
|
|
146
|
+
intent: Short description of the task intent
|
|
147
|
+
description: Detailed task description
|
|
148
|
+
payload: Task-specific data
|
|
149
|
+
shared_context: Context to share with the target agent
|
|
150
|
+
user_identity: User context for authorization
|
|
151
|
+
priority: Task priority level
|
|
152
|
+
timeout_seconds: Maximum execution time
|
|
153
|
+
max_iterations: Maximum ReAct iterations allowed
|
|
154
|
+
callback_mode: Response mode ("sync" | "async" | "webhook")
|
|
155
|
+
webhook_url: URL for webhook callback (if callback_mode="webhook")
|
|
156
|
+
requested_at: Timestamp when request was created
|
|
157
|
+
|
|
158
|
+
Examples:
|
|
159
|
+
```python
|
|
160
|
+
request = TaskRequest(
|
|
161
|
+
task_id="task-123",
|
|
162
|
+
correlation_id="corr-456",
|
|
163
|
+
source=AgentIdentity(
|
|
164
|
+
agent_id="personal-agent",
|
|
165
|
+
agent_type="personal",
|
|
166
|
+
owner_id="user-789"
|
|
167
|
+
),
|
|
168
|
+
target_team_id="research-team",
|
|
169
|
+
required_capabilities=["document_analysis"],
|
|
170
|
+
intent="analyze_document",
|
|
171
|
+
description="Extract key insights from quarterly report",
|
|
172
|
+
payload={"document_id": "doc-abc"},
|
|
173
|
+
priority=TaskPriority.HIGH,
|
|
174
|
+
timeout_seconds=600
|
|
175
|
+
)
|
|
176
|
+
```
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
# Identity
|
|
180
|
+
task_id: str
|
|
181
|
+
correlation_id: str # For response routing
|
|
182
|
+
|
|
183
|
+
# Source
|
|
184
|
+
source: AgentIdentity
|
|
185
|
+
|
|
186
|
+
# Target
|
|
187
|
+
target_team_id: str | None = None
|
|
188
|
+
target_agent_id: str | None = None
|
|
189
|
+
required_capabilities: list[str] = field(default_factory=list)
|
|
190
|
+
|
|
191
|
+
# Task Definition
|
|
192
|
+
intent: str = ""
|
|
193
|
+
description: str = ""
|
|
194
|
+
payload: dict[str, Any] = field(default_factory=dict)
|
|
195
|
+
|
|
196
|
+
# Context
|
|
197
|
+
shared_context: dict[str, Any] = field(default_factory=dict)
|
|
198
|
+
user_identity: dict[str, Any] | None = None
|
|
199
|
+
|
|
200
|
+
# Constraints
|
|
201
|
+
priority: TaskPriority = TaskPriority.NORMAL
|
|
202
|
+
timeout_seconds: int = 300
|
|
203
|
+
max_iterations: int = 50
|
|
204
|
+
|
|
205
|
+
# Callback
|
|
206
|
+
callback_mode: str = "sync" # "sync" | "async" | "webhook"
|
|
207
|
+
webhook_url: str | None = None
|
|
208
|
+
|
|
209
|
+
# Timestamps
|
|
210
|
+
requested_at: datetime | None = None
|
|
211
|
+
|
|
212
|
+
def to_dict(self) -> dict[str, Any]:
|
|
213
|
+
"""Serialize to dictionary for transport."""
|
|
214
|
+
return {
|
|
215
|
+
"task_id": self.task_id,
|
|
216
|
+
"correlation_id": self.correlation_id,
|
|
217
|
+
"source": self.source.to_dict(),
|
|
218
|
+
"target_team_id": self.target_team_id,
|
|
219
|
+
"target_agent_id": self.target_agent_id,
|
|
220
|
+
"required_capabilities": self.required_capabilities,
|
|
221
|
+
"intent": self.intent,
|
|
222
|
+
"description": self.description,
|
|
223
|
+
"payload": self.payload,
|
|
224
|
+
"shared_context": self.shared_context,
|
|
225
|
+
"user_identity": self.user_identity,
|
|
226
|
+
"priority": self.priority.value,
|
|
227
|
+
"timeout_seconds": self.timeout_seconds,
|
|
228
|
+
"max_iterations": self.max_iterations,
|
|
229
|
+
"callback_mode": self.callback_mode,
|
|
230
|
+
"webhook_url": self.webhook_url,
|
|
231
|
+
"requested_at": self.requested_at.isoformat() if self.requested_at else None,
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@classmethod
|
|
235
|
+
def from_dict(cls, data: dict[str, Any]) -> "TaskRequest":
|
|
236
|
+
"""Deserialize from dictionary."""
|
|
237
|
+
return cls(
|
|
238
|
+
task_id=data["task_id"],
|
|
239
|
+
correlation_id=data["correlation_id"],
|
|
240
|
+
source=AgentIdentity.from_dict(data["source"]),
|
|
241
|
+
target_team_id=data.get("target_team_id"),
|
|
242
|
+
target_agent_id=data.get("target_agent_id"),
|
|
243
|
+
required_capabilities=data.get("required_capabilities", []),
|
|
244
|
+
intent=data.get("intent", ""),
|
|
245
|
+
description=data.get("description", ""),
|
|
246
|
+
payload=data.get("payload", {}),
|
|
247
|
+
shared_context=data.get("shared_context", {}),
|
|
248
|
+
user_identity=data.get("user_identity"),
|
|
249
|
+
priority=TaskPriority(data.get("priority", "normal")),
|
|
250
|
+
timeout_seconds=data.get("timeout_seconds", 300),
|
|
251
|
+
max_iterations=data.get("max_iterations", 50),
|
|
252
|
+
callback_mode=data.get("callback_mode", "sync"),
|
|
253
|
+
webhook_url=data.get("webhook_url"),
|
|
254
|
+
requested_at=(datetime.fromisoformat(data["requested_at"]) if data.get("requested_at") else None),
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@dataclass
|
|
259
|
+
class TaskResponse:
|
|
260
|
+
"""A2A delegation response from target agent.
|
|
261
|
+
|
|
262
|
+
Encapsulates the result of a delegated task, including
|
|
263
|
+
execution metadata for observability.
|
|
264
|
+
|
|
265
|
+
Attributes:
|
|
266
|
+
task_id: Original task identifier
|
|
267
|
+
correlation_id: Original correlation ID for routing
|
|
268
|
+
responder: Identity of the responding agent
|
|
269
|
+
status: Final task status
|
|
270
|
+
result: Task result data (if successful)
|
|
271
|
+
error: Error details (if failed)
|
|
272
|
+
iterations_used: Number of ReAct iterations used
|
|
273
|
+
tools_called: Total number of tool calls made
|
|
274
|
+
duration_ms: Total execution time in milliseconds
|
|
275
|
+
completed_at: Timestamp when task completed
|
|
276
|
+
|
|
277
|
+
Examples:
|
|
278
|
+
```python
|
|
279
|
+
response = TaskResponse(
|
|
280
|
+
task_id="task-123",
|
|
281
|
+
correlation_id="corr-456",
|
|
282
|
+
responder=AgentIdentity(
|
|
283
|
+
agent_id="team-agent-789",
|
|
284
|
+
agent_type="team_member",
|
|
285
|
+
team_id="research-team"
|
|
286
|
+
),
|
|
287
|
+
status=TaskStatus.COMPLETED,
|
|
288
|
+
result={"insights": ["Key insight 1", "Key insight 2"]},
|
|
289
|
+
iterations_used=5,
|
|
290
|
+
tools_called=3,
|
|
291
|
+
duration_ms=15000,
|
|
292
|
+
completed_at=datetime.now(UTC)
|
|
293
|
+
)
|
|
294
|
+
```
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
# Identity
|
|
298
|
+
task_id: str
|
|
299
|
+
correlation_id: str
|
|
300
|
+
|
|
301
|
+
# Source (responding agent)
|
|
302
|
+
responder: AgentIdentity
|
|
303
|
+
|
|
304
|
+
# Result
|
|
305
|
+
status: TaskStatus
|
|
306
|
+
result: dict[str, Any] | None = None
|
|
307
|
+
error: dict[str, Any] | None = None
|
|
308
|
+
|
|
309
|
+
# Execution Metadata
|
|
310
|
+
iterations_used: int = 0
|
|
311
|
+
tools_called: int = 0
|
|
312
|
+
duration_ms: int = 0
|
|
313
|
+
|
|
314
|
+
# Timestamps
|
|
315
|
+
completed_at: datetime | None = None
|
|
316
|
+
|
|
317
|
+
def is_successful(self) -> bool:
|
|
318
|
+
"""Check if the task completed successfully."""
|
|
319
|
+
return self.status == TaskStatus.COMPLETED
|
|
320
|
+
|
|
321
|
+
def is_failed(self) -> bool:
|
|
322
|
+
"""Check if the task failed."""
|
|
323
|
+
return self.status in (TaskStatus.FAILED, TaskStatus.CANCELLED)
|
|
324
|
+
|
|
325
|
+
def to_dict(self) -> dict[str, Any]:
|
|
326
|
+
"""Serialize to dictionary for transport."""
|
|
327
|
+
return {
|
|
328
|
+
"task_id": self.task_id,
|
|
329
|
+
"correlation_id": self.correlation_id,
|
|
330
|
+
"responder": self.responder.to_dict(),
|
|
331
|
+
"status": self.status.value,
|
|
332
|
+
"result": self.result,
|
|
333
|
+
"error": self.error,
|
|
334
|
+
"iterations_used": self.iterations_used,
|
|
335
|
+
"tools_called": self.tools_called,
|
|
336
|
+
"duration_ms": self.duration_ms,
|
|
337
|
+
"completed_at": self.completed_at.isoformat() if self.completed_at else None,
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
@classmethod
|
|
341
|
+
def from_dict(cls, data: dict[str, Any]) -> "TaskResponse":
|
|
342
|
+
"""Deserialize from dictionary."""
|
|
343
|
+
return cls(
|
|
344
|
+
task_id=data["task_id"],
|
|
345
|
+
correlation_id=data["correlation_id"],
|
|
346
|
+
responder=AgentIdentity.from_dict(data["responder"]),
|
|
347
|
+
status=TaskStatus(data["status"]),
|
|
348
|
+
result=data.get("result"),
|
|
349
|
+
error=data.get("error"),
|
|
350
|
+
iterations_used=data.get("iterations_used", 0),
|
|
351
|
+
tools_called=data.get("tools_called", 0),
|
|
352
|
+
duration_ms=data.get("duration_ms", 0),
|
|
353
|
+
completed_at=(datetime.fromisoformat(data["completed_at"]) if data.get("completed_at") else None),
|
|
354
|
+
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Data access layer for Neuroglia.
|
|
3
3
|
|
|
4
|
-
Provides domain modeling, repository patterns,
|
|
4
|
+
Provides domain modeling, repository patterns, queryable data access,
|
|
5
|
+
agent building blocks, and conversation value objects.
|
|
5
6
|
"""
|
|
6
7
|
|
|
7
8
|
# Domain abstractions
|
|
@@ -14,6 +15,21 @@ from .abstractions import (
|
|
|
14
15
|
VersionedState,
|
|
15
16
|
)
|
|
16
17
|
|
|
18
|
+
# Agent module (new in 0.9.0)
|
|
19
|
+
from .agent import AgentCapability, BaseAgentState, KnowledgeScope, TeamMembership
|
|
20
|
+
|
|
21
|
+
# Conversation building blocks (new in 0.9.0)
|
|
22
|
+
from .conversation import (
|
|
23
|
+
ExecutionContext,
|
|
24
|
+
LlmMessageSnapshot,
|
|
25
|
+
Message,
|
|
26
|
+
MessageRole,
|
|
27
|
+
MessageStatus,
|
|
28
|
+
Session,
|
|
29
|
+
ToolCall,
|
|
30
|
+
ToolResult,
|
|
31
|
+
)
|
|
32
|
+
|
|
17
33
|
# Exceptions
|
|
18
34
|
from .exceptions import (
|
|
19
35
|
DataAccessException,
|
|
@@ -51,6 +67,20 @@ __all__ = [
|
|
|
51
67
|
"DataAccessException",
|
|
52
68
|
"OptimisticConcurrencyException",
|
|
53
69
|
"EntityNotFoundException",
|
|
70
|
+
# Agent module (new in 0.9.0)
|
|
71
|
+
"BaseAgentState",
|
|
72
|
+
"TeamMembership",
|
|
73
|
+
"KnowledgeScope",
|
|
74
|
+
"AgentCapability",
|
|
75
|
+
# Conversation building blocks (new in 0.9.0)
|
|
76
|
+
"Message",
|
|
77
|
+
"MessageRole",
|
|
78
|
+
"MessageStatus",
|
|
79
|
+
"ToolCall",
|
|
80
|
+
"ToolResult",
|
|
81
|
+
"ExecutionContext",
|
|
82
|
+
"LlmMessageSnapshot",
|
|
83
|
+
"Session",
|
|
54
84
|
# Resource-oriented architecture (commented out to avoid circular imports)
|
|
55
85
|
# "resources"
|
|
56
86
|
]
|