agentmesh-platform 1.0.0a1__py3-none-any.whl → 1.0.0a2__py3-none-any.whl

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.
@@ -0,0 +1,203 @@
1
+ """
2
+ OpenTelemetry Tracing Integration.
3
+
4
+ Provides distributed tracing for AgentMesh operations.
5
+ """
6
+
7
+ from typing import Optional, Any
8
+ from functools import wraps
9
+ import os
10
+
11
+
12
+ def setup_tracing(
13
+ service_name: str = "agentmesh",
14
+ endpoint: Optional[str] = None,
15
+ insecure: bool = False,
16
+ ) -> None:
17
+ """
18
+ Setup OpenTelemetry tracing.
19
+
20
+ Args:
21
+ service_name: Service name for traces
22
+ endpoint: OTLP endpoint (default: from OTEL_EXPORTER_OTLP_ENDPOINT env)
23
+ insecure: Whether to use insecure connection (default: False, use TLS)
24
+ """
25
+ try:
26
+ from opentelemetry import trace
27
+ from opentelemetry.sdk.trace import TracerProvider
28
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
29
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
30
+ from opentelemetry.sdk.resources import Resource
31
+ except ImportError:
32
+ # OpenTelemetry not installed, skip setup
33
+ return
34
+
35
+ # Get endpoint from env or parameter
36
+ endpoint = endpoint or os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
37
+ if not endpoint:
38
+ # No endpoint configured, skip
39
+ return
40
+
41
+ # Create resource
42
+ resource = Resource.create({
43
+ "service.name": service_name,
44
+ "service.namespace": "agentmesh",
45
+ "deployment.environment": os.getenv("AGENTMESH_ENV", "development"),
46
+ })
47
+
48
+ # Create tracer provider
49
+ provider = TracerProvider(resource=resource)
50
+
51
+ # Create OTLP exporter
52
+ otlp_exporter = OTLPSpanExporter(endpoint=endpoint, insecure=insecure)
53
+
54
+ # Add span processor
55
+ provider.add_span_processor(BatchSpanProcessor(otlp_exporter))
56
+
57
+ # Set global tracer provider
58
+ trace.set_tracer_provider(provider)
59
+
60
+
61
+ def get_tracer(name: str = "agentmesh"):
62
+ """Get tracer instance."""
63
+ try:
64
+ from opentelemetry import trace
65
+ return trace.get_tracer(name)
66
+ except ImportError:
67
+ return None
68
+
69
+
70
+ def trace_operation(
71
+ operation_name: str,
72
+ agent_did: Optional[str] = None,
73
+ trust_score: Optional[int] = None,
74
+ policy_result: Optional[str] = None,
75
+ ):
76
+ """
77
+ Decorator to trace an operation.
78
+
79
+ Args:
80
+ operation_name: Name of the operation
81
+ agent_did: Optional agent DID
82
+ trust_score: Optional trust score
83
+ policy_result: Optional policy result (ALLOW/DENY)
84
+ """
85
+ def decorator(func):
86
+ @wraps(func)
87
+ async def async_wrapper(*args, **kwargs):
88
+ tracer = get_tracer()
89
+ if tracer is None:
90
+ # Tracing not available
91
+ return await func(*args, **kwargs)
92
+
93
+ with tracer.start_as_current_span(operation_name) as span:
94
+ # Set attributes
95
+ if agent_did:
96
+ span.set_attribute("agent.did", agent_did)
97
+ if trust_score is not None:
98
+ span.set_attribute("agent.trust_score", trust_score)
99
+ if policy_result:
100
+ span.set_attribute("policy.result", policy_result)
101
+
102
+ # Set standard attributes
103
+ span.set_attribute("operation.name", operation_name)
104
+
105
+ try:
106
+ result = await func(*args, **kwargs)
107
+ span.set_attribute("operation.status", "success")
108
+ return result
109
+ except Exception as e:
110
+ span.set_attribute("operation.status", "error")
111
+ span.set_attribute("error.type", type(e).__name__)
112
+ span.set_attribute("error.message", str(e))
113
+ span.record_exception(e)
114
+ raise
115
+
116
+ @wraps(func)
117
+ def sync_wrapper(*args, **kwargs):
118
+ tracer = get_tracer()
119
+ if tracer is None:
120
+ return func(*args, **kwargs)
121
+
122
+ with tracer.start_as_current_span(operation_name) as span:
123
+ if agent_did:
124
+ span.set_attribute("agent.did", agent_did)
125
+ if trust_score is not None:
126
+ span.set_attribute("agent.trust_score", trust_score)
127
+ if policy_result:
128
+ span.set_attribute("policy.result", policy_result)
129
+
130
+ span.set_attribute("operation.name", operation_name)
131
+
132
+ try:
133
+ result = func(*args, **kwargs)
134
+ span.set_attribute("operation.status", "success")
135
+ return result
136
+ except Exception as e:
137
+ span.set_attribute("operation.status", "error")
138
+ span.set_attribute("error.type", type(e).__name__)
139
+ span.set_attribute("error.message", str(e))
140
+ span.record_exception(e)
141
+ raise
142
+
143
+ # Return appropriate wrapper based on function type
144
+ import inspect
145
+ if inspect.iscoroutinefunction(func):
146
+ return async_wrapper
147
+ return sync_wrapper
148
+
149
+ return decorator
150
+
151
+
152
+ class TraceContext:
153
+ """Context manager for manual tracing."""
154
+
155
+ def __init__(
156
+ self,
157
+ operation_name: str,
158
+ agent_did: Optional[str] = None,
159
+ **attributes: Any,
160
+ ):
161
+ self.operation_name = operation_name
162
+ self.agent_did = agent_did
163
+ self.attributes = attributes
164
+ self.span = None
165
+
166
+ def __enter__(self):
167
+ tracer = get_tracer()
168
+ if tracer is None:
169
+ return self
170
+
171
+ self.span = tracer.start_span(self.operation_name)
172
+ self.span.__enter__()
173
+
174
+ # Set attributes
175
+ if self.agent_did:
176
+ self.span.set_attribute("agent.did", self.agent_did)
177
+
178
+ for key, value in self.attributes.items():
179
+ self.span.set_attribute(key, value)
180
+
181
+ return self
182
+
183
+ def __exit__(self, exc_type, exc_val, exc_tb):
184
+ if self.span:
185
+ if exc_type:
186
+ self.span.set_attribute("operation.status", "error")
187
+ self.span.set_attribute("error.type", exc_type.__name__)
188
+ self.span.set_attribute("error.message", str(exc_val))
189
+ self.span.record_exception(exc_val)
190
+ else:
191
+ self.span.set_attribute("operation.status", "success")
192
+
193
+ self.span.__exit__(exc_type, exc_val, exc_tb)
194
+
195
+ def set_attribute(self, key: str, value: Any):
196
+ """Set attribute on current span."""
197
+ if self.span:
198
+ self.span.set_attribute(key, value)
199
+
200
+ def add_event(self, name: str, attributes: Optional[dict] = None):
201
+ """Add event to current span."""
202
+ if self.span:
203
+ self.span.add_event(name, attributes or {})
@@ -0,0 +1,10 @@
1
+ """
2
+ Services Module
3
+
4
+ High-level services for AgentMesh:
5
+ - registry: Agent registry (Yellow Pages)
6
+ - reward_engine: Trust score processor
7
+ - audit: Merkle-chain logger
8
+ """
9
+
10
+ __all__ = []
@@ -0,0 +1,14 @@
1
+ """
2
+ Audit Service
3
+
4
+ Merkle-chained logger for tamper-evident audit trails.
5
+
6
+ This service wraps the core audit logging to provide:
7
+ - Immutable event history
8
+ - Cryptographic verification
9
+ - Compliance audit trails
10
+ - Query and export capabilities
11
+ """
12
+
13
+ # TODO: Implement service wrapper around governance.audit
14
+ # The core audit module is in src/agentmesh/governance/
@@ -0,0 +1,12 @@
1
+ """
2
+ Agent Registry Service
3
+
4
+ The "Yellow Pages" of agents with DIDs and reputation scores.
5
+ """
6
+
7
+ from .agent_registry import AgentRegistry, AgentRegistryEntry
8
+
9
+ __all__ = [
10
+ "AgentRegistry",
11
+ "AgentRegistryEntry",
12
+ ]
@@ -0,0 +1,249 @@
1
+ """
2
+ Agent Registry Service
3
+
4
+ The "Yellow Pages" of agents. Stores:
5
+ - Agent DIDs and identities
6
+ - Reputation scores
7
+ - Current status (active, suspended, revoked)
8
+ - Capabilities and protocols
9
+ """
10
+
11
+ import asyncio
12
+ from datetime import datetime, timezone
13
+ from typing import Literal
14
+
15
+ from pydantic import BaseModel, Field
16
+
17
+
18
+ class AgentRegistryEntry(BaseModel):
19
+ """Entry in the agent registry."""
20
+
21
+ # Identity
22
+ did: str
23
+ name: str
24
+ description: str | None = None
25
+ organization: str | None = None
26
+
27
+ # Sponsor
28
+ sponsor_email: str
29
+ sponsor_verified: bool = False
30
+
31
+ # Status
32
+ status: Literal["active", "suspended", "revoked"] = "active"
33
+ revocation_reason: str | None = None
34
+
35
+ # Capabilities
36
+ capabilities: list[str] = Field(default_factory=list)
37
+ supported_protocols: list[str] = Field(default_factory=list)
38
+
39
+ # Trust
40
+ trust_score: int = Field(default=500, ge=0, le=1000)
41
+ trust_tier: Literal[
42
+ "verified_partner",
43
+ "trusted",
44
+ "standard",
45
+ "probationary",
46
+ "untrusted"
47
+ ] = "standard"
48
+
49
+ # Credentials
50
+ public_key_fingerprint: str
51
+ svid_serial_number: str
52
+ current_credential_expires_at: datetime
53
+
54
+ # Timestamps
55
+ registered_at: datetime = Field(default_factory=datetime.utcnow)
56
+ last_seen_at: datetime | None = None
57
+ updated_at: datetime = Field(default_factory=datetime.utcnow)
58
+
59
+ # Delegation
60
+ parent_did: str | None = None
61
+ delegation_depth: int = 0
62
+
63
+ # Metadata
64
+ metadata: dict[str, str] = Field(default_factory=dict)
65
+
66
+
67
+ class AgentRegistry:
68
+ """
69
+ Agent Registry Service.
70
+
71
+ Maintains a registry of all agents in the mesh with their:
72
+ - Identity and credentials
73
+ - Trust scores and reputation
74
+ - Status and capabilities
75
+ """
76
+
77
+ def __init__(self):
78
+ """Initialize the agent registry."""
79
+ self._agents: dict[str, AgentRegistryEntry] = {}
80
+ self._lock = asyncio.Lock()
81
+
82
+ async def register(self, entry: AgentRegistryEntry) -> None:
83
+ """
84
+ Register a new agent.
85
+
86
+ Args:
87
+ entry: Agent registry entry
88
+
89
+ Raises:
90
+ ValueError: If agent is already registered
91
+ """
92
+ async with self._lock:
93
+ if entry.did in self._agents:
94
+ raise ValueError(f"Agent {entry.did} is already registered")
95
+
96
+ self._agents[entry.did] = entry
97
+
98
+ async def get(self, did: str) -> AgentRegistryEntry | None:
99
+ """
100
+ Get an agent by DID.
101
+
102
+ Args:
103
+ did: Agent's DID
104
+
105
+ Returns:
106
+ Agent entry or None if not found
107
+ """
108
+ return self._agents.get(did)
109
+
110
+ async def update_trust_score(self, did: str, new_score: int) -> None:
111
+ """
112
+ Update an agent's trust score.
113
+
114
+ Args:
115
+ did: Agent's DID
116
+ new_score: New trust score (0-1000)
117
+
118
+ Raises:
119
+ ValueError: If agent not found
120
+ """
121
+ async with self._lock:
122
+ entry = self._agents.get(did)
123
+ if entry is None:
124
+ raise ValueError(f"Agent {did} not found")
125
+
126
+ entry.trust_score = new_score
127
+ entry.updated_at = datetime.now(timezone.utc)
128
+
129
+ # Update trust tier based on score
130
+ if new_score >= 900:
131
+ entry.trust_tier = "verified_partner"
132
+ elif new_score >= 700:
133
+ entry.trust_tier = "trusted"
134
+ elif new_score >= 400:
135
+ entry.trust_tier = "standard"
136
+ elif new_score >= 200:
137
+ entry.trust_tier = "probationary"
138
+ else:
139
+ entry.trust_tier = "untrusted"
140
+
141
+ async def update_status(
142
+ self,
143
+ did: str,
144
+ status: Literal["active", "suspended", "revoked"],
145
+ reason: str | None = None,
146
+ ) -> None:
147
+ """
148
+ Update an agent's status.
149
+
150
+ Args:
151
+ did: Agent's DID
152
+ status: New status
153
+ reason: Optional reason for status change
154
+
155
+ Raises:
156
+ ValueError: If agent not found
157
+ """
158
+ async with self._lock:
159
+ entry = self._agents.get(did)
160
+ if entry is None:
161
+ raise ValueError(f"Agent {did} not found")
162
+
163
+ entry.status = status
164
+ entry.revocation_reason = reason
165
+ entry.updated_at = datetime.now(timezone.utc)
166
+
167
+ async def record_activity(self, did: str) -> None:
168
+ """
169
+ Record that an agent was seen (heartbeat).
170
+
171
+ Args:
172
+ did: Agent's DID
173
+ """
174
+ async with self._lock:
175
+ entry = self._agents.get(did)
176
+ if entry:
177
+ entry.last_seen_at = datetime.now(timezone.utc)
178
+
179
+ async def list_agents(
180
+ self,
181
+ status: Literal["active", "suspended", "revoked"] | None = None,
182
+ min_trust_score: int | None = None,
183
+ ) -> list[AgentRegistryEntry]:
184
+ """
185
+ List agents with optional filters.
186
+
187
+ Args:
188
+ status: Filter by status
189
+ min_trust_score: Filter by minimum trust score
190
+
191
+ Returns:
192
+ List of matching agent entries
193
+ """
194
+ agents = list(self._agents.values())
195
+
196
+ if status:
197
+ agents = [a for a in agents if a.status == status]
198
+
199
+ if min_trust_score is not None:
200
+ agents = [a for a in agents if a.trust_score >= min_trust_score]
201
+
202
+ return agents
203
+
204
+ async def count_agents(
205
+ self,
206
+ status: Literal["active", "suspended", "revoked"] | None = None,
207
+ ) -> int:
208
+ """
209
+ Count agents with optional status filter.
210
+
211
+ Args:
212
+ status: Filter by status
213
+
214
+ Returns:
215
+ Number of matching agents
216
+ """
217
+ if status is None:
218
+ return len(self._agents)
219
+
220
+ return sum(1 for a in self._agents.values() if a.status == status)
221
+
222
+ async def get_trust_statistics(self) -> dict:
223
+ """
224
+ Get aggregate trust statistics.
225
+
226
+ Returns:
227
+ Dictionary of trust statistics
228
+ """
229
+ if not self._agents:
230
+ return {
231
+ "total_agents": 0,
232
+ "average_trust_score": 0,
233
+ "tier_distribution": {},
234
+ }
235
+
236
+ scores = [a.trust_score for a in self._agents.values()]
237
+ tiers = {}
238
+
239
+ for agent in self._agents.values():
240
+ tier = agent.trust_tier
241
+ tiers[tier] = tiers.get(tier, 0) + 1
242
+
243
+ return {
244
+ "total_agents": len(self._agents),
245
+ "average_trust_score": sum(scores) / len(scores),
246
+ "min_trust_score": min(scores),
247
+ "max_trust_score": max(scores),
248
+ "tier_distribution": tiers,
249
+ }
@@ -0,0 +1,14 @@
1
+ """
2
+ Reward Engine Service
3
+
4
+ Async worker that processes Flight Recorder logs and updates trust scores.
5
+
6
+ This service wraps the core reward engine to provide:
7
+ - Continuous trust score updates
8
+ - Multi-dimensional scoring
9
+ - Auto-revocation triggers
10
+ - Behavioral pattern detection
11
+ """
12
+
13
+ # TODO: Implement service wrapper around reward.engine
14
+ # The core reward engine is in src/agentmesh/reward/
@@ -0,0 +1,18 @@
1
+ """
2
+ Storage providers for AgentMesh.
3
+
4
+ Provides abstract interfaces and implementations for scalable storage backends.
5
+ """
6
+
7
+ from .provider import AbstractStorageProvider, StorageConfig
8
+ from .memory_provider import MemoryStorageProvider
9
+ from .redis_provider import RedisStorageProvider
10
+ from .postgres_provider import PostgresStorageProvider
11
+
12
+ __all__ = [
13
+ "AbstractStorageProvider",
14
+ "StorageConfig",
15
+ "MemoryStorageProvider",
16
+ "RedisStorageProvider",
17
+ "PostgresStorageProvider",
18
+ ]