agent_os_kernel 3.1.0__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.
- agent_control_plane/__init__.py +662 -0
- agent_control_plane/a2a_adapter.py +543 -0
- agent_control_plane/adapter.py +417 -0
- agent_control_plane/agent_hibernation.py +394 -0
- agent_control_plane/agent_kernel.py +470 -0
- agent_control_plane/compliance.py +720 -0
- agent_control_plane/constraint_graphs.py +478 -0
- agent_control_plane/control_plane.py +854 -0
- agent_control_plane/example_executors.py +195 -0
- agent_control_plane/execution_engine.py +231 -0
- agent_control_plane/flight_recorder.py +846 -0
- agent_control_plane/governance_layer.py +435 -0
- agent_control_plane/hf_utils.py +563 -0
- agent_control_plane/interfaces/__init__.py +55 -0
- agent_control_plane/interfaces/kernel_interface.py +361 -0
- agent_control_plane/interfaces/plugin_interface.py +497 -0
- agent_control_plane/interfaces/protocol_interfaces.py +387 -0
- agent_control_plane/kernel_space.py +1009 -0
- agent_control_plane/langchain_adapter.py +424 -0
- agent_control_plane/lifecycle.py +3113 -0
- agent_control_plane/mcp_adapter.py +653 -0
- agent_control_plane/ml_safety.py +563 -0
- agent_control_plane/multimodal.py +727 -0
- agent_control_plane/mute_agent.py +422 -0
- agent_control_plane/observability.py +787 -0
- agent_control_plane/orchestrator.py +482 -0
- agent_control_plane/plugin_registry.py +750 -0
- agent_control_plane/policy_engine.py +954 -0
- agent_control_plane/process_isolation.py +777 -0
- agent_control_plane/shadow_mode.py +310 -0
- agent_control_plane/signals.py +493 -0
- agent_control_plane/supervisor_agents.py +430 -0
- agent_control_plane/time_travel_debugger.py +557 -0
- agent_control_plane/tool_registry.py +452 -0
- agent_control_plane/vfs.py +697 -0
- agent_kernel/__init__.py +69 -0
- agent_kernel/analyzer.py +435 -0
- agent_kernel/auditor.py +36 -0
- agent_kernel/completeness_auditor.py +237 -0
- agent_kernel/detector.py +203 -0
- agent_kernel/kernel.py +744 -0
- agent_kernel/memory_manager.py +85 -0
- agent_kernel/models.py +374 -0
- agent_kernel/nudge_mechanism.py +263 -0
- agent_kernel/outcome_analyzer.py +338 -0
- agent_kernel/patcher.py +582 -0
- agent_kernel/semantic_analyzer.py +316 -0
- agent_kernel/semantic_purge.py +349 -0
- agent_kernel/simulator.py +449 -0
- agent_kernel/teacher.py +85 -0
- agent_kernel/triage.py +152 -0
- agent_os/__init__.py +409 -0
- agent_os/_adversarial_impl.py +200 -0
- agent_os/_circuit_breaker_impl.py +232 -0
- agent_os/_mcp_metrics.py +193 -0
- agent_os/adversarial.py +20 -0
- agent_os/agents_compat.py +490 -0
- agent_os/audit_logger.py +135 -0
- agent_os/base_agent.py +651 -0
- agent_os/circuit_breaker.py +34 -0
- agent_os/cli/__init__.py +659 -0
- agent_os/cli/cmd_audit.py +128 -0
- agent_os/cli/cmd_init.py +152 -0
- agent_os/cli/cmd_policy.py +41 -0
- agent_os/cli/cmd_policy_gen.py +180 -0
- agent_os/cli/cmd_validate.py +258 -0
- agent_os/cli/mcp_scan.py +265 -0
- agent_os/cli/output.py +192 -0
- agent_os/cli/policy_checker.py +330 -0
- agent_os/compat.py +74 -0
- agent_os/constraint_graph.py +234 -0
- agent_os/content_governance.py +140 -0
- agent_os/context_budget.py +305 -0
- agent_os/credential_redactor.py +224 -0
- agent_os/diff_policy.py +89 -0
- agent_os/egress_policy.py +159 -0
- agent_os/escalation.py +276 -0
- agent_os/event_bus.py +124 -0
- agent_os/exceptions.py +180 -0
- agent_os/execution_context_policy.py +141 -0
- agent_os/github_enterprise.py +96 -0
- agent_os/health.py +20 -0
- agent_os/integrations/__init__.py +279 -0
- agent_os/integrations/a2a_adapter.py +279 -0
- agent_os/integrations/agent_lightning/__init__.py +30 -0
- agent_os/integrations/anthropic_adapter.py +420 -0
- agent_os/integrations/autogen_adapter.py +620 -0
- agent_os/integrations/base.py +1137 -0
- agent_os/integrations/compat.py +229 -0
- agent_os/integrations/config.py +98 -0
- agent_os/integrations/conversation_guardian.py +957 -0
- agent_os/integrations/crewai_adapter.py +467 -0
- agent_os/integrations/drift_detector.py +425 -0
- agent_os/integrations/dry_run.py +124 -0
- agent_os/integrations/escalation.py +582 -0
- agent_os/integrations/gemini_adapter.py +364 -0
- agent_os/integrations/google_adk_adapter.py +633 -0
- agent_os/integrations/guardrails_adapter.py +394 -0
- agent_os/integrations/health.py +197 -0
- agent_os/integrations/langchain_adapter.py +654 -0
- agent_os/integrations/llamafirewall.py +343 -0
- agent_os/integrations/llamaindex_adapter.py +188 -0
- agent_os/integrations/logging.py +191 -0
- agent_os/integrations/maf_adapter.py +631 -0
- agent_os/integrations/mistral_adapter.py +365 -0
- agent_os/integrations/openai_adapter.py +816 -0
- agent_os/integrations/openai_agents_sdk.py +406 -0
- agent_os/integrations/policy_compose.py +171 -0
- agent_os/integrations/profiling.py +144 -0
- agent_os/integrations/pydantic_ai_adapter.py +420 -0
- agent_os/integrations/rate_limiter.py +130 -0
- agent_os/integrations/rbac.py +143 -0
- agent_os/integrations/registry.py +113 -0
- agent_os/integrations/scope_guard.py +303 -0
- agent_os/integrations/semantic_kernel_adapter.py +769 -0
- agent_os/integrations/smolagents_adapter.py +629 -0
- agent_os/integrations/templates.py +178 -0
- agent_os/integrations/token_budget.py +134 -0
- agent_os/integrations/tool_aliases.py +190 -0
- agent_os/integrations/webhooks.py +177 -0
- agent_os/lite.py +208 -0
- agent_os/mcp_gateway.py +385 -0
- agent_os/mcp_message_signer.py +273 -0
- agent_os/mcp_protocols.py +161 -0
- agent_os/mcp_response_scanner.py +232 -0
- agent_os/mcp_security.py +924 -0
- agent_os/mcp_session_auth.py +231 -0
- agent_os/mcp_sliding_rate_limiter.py +184 -0
- agent_os/memory_guard.py +409 -0
- agent_os/metrics.py +134 -0
- agent_os/mute.py +428 -0
- agent_os/mute_agent.py +209 -0
- agent_os/policies/__init__.py +77 -0
- agent_os/policies/async_evaluator.py +275 -0
- agent_os/policies/backends.py +670 -0
- agent_os/policies/bridge.py +169 -0
- agent_os/policies/budget.py +85 -0
- agent_os/policies/cli.py +294 -0
- agent_os/policies/conflict_resolution.py +270 -0
- agent_os/policies/data_classification.py +252 -0
- agent_os/policies/evaluator.py +239 -0
- agent_os/policies/policy_schema.json +228 -0
- agent_os/policies/rate_limiting.py +145 -0
- agent_os/policies/schema.py +115 -0
- agent_os/policies/shared.py +331 -0
- agent_os/prompt_injection.py +694 -0
- agent_os/providers.py +182 -0
- agent_os/py.typed +0 -0
- agent_os/retry.py +81 -0
- agent_os/reversibility.py +251 -0
- agent_os/sandbox.py +432 -0
- agent_os/sandbox_provider.py +140 -0
- agent_os/secure_codegen.py +525 -0
- agent_os/security_skills.py +538 -0
- agent_os/semantic_policy.py +422 -0
- agent_os/server/__init__.py +15 -0
- agent_os/server/__main__.py +25 -0
- agent_os/server/app.py +277 -0
- agent_os/server/models.py +104 -0
- agent_os/shift_left_metrics.py +130 -0
- agent_os/stateless.py +742 -0
- agent_os/supervisor.py +148 -0
- agent_os/task_outcome.py +148 -0
- agent_os/transparency.py +181 -0
- agent_os/trust_root.py +128 -0
- agent_os_kernel-3.1.0.dist-info/METADATA +1269 -0
- agent_os_kernel-3.1.0.dist-info/RECORD +337 -0
- agent_os_kernel-3.1.0.dist-info/WHEEL +4 -0
- agent_os_kernel-3.1.0.dist-info/entry_points.txt +2 -0
- agent_os_kernel-3.1.0.dist-info/licenses/LICENSE +21 -0
- agent_os_observability/__init__.py +27 -0
- agent_os_observability/dashboards.py +898 -0
- agent_os_observability/metrics.py +398 -0
- agent_os_observability/server.py +223 -0
- agent_os_observability/tracer.py +232 -0
- agent_primitives/__init__.py +24 -0
- agent_primitives/failures.py +84 -0
- agent_primitives/py.typed +0 -0
- amb_core/__init__.py +177 -0
- amb_core/adapters/__init__.py +57 -0
- amb_core/adapters/aws_sqs_broker.py +376 -0
- amb_core/adapters/azure_servicebus_broker.py +340 -0
- amb_core/adapters/kafka_broker.py +260 -0
- amb_core/adapters/nats_broker.py +285 -0
- amb_core/adapters/rabbitmq_broker.py +235 -0
- amb_core/adapters/redis_broker.py +262 -0
- amb_core/broker.py +145 -0
- amb_core/bus.py +481 -0
- amb_core/cloudevents.py +509 -0
- amb_core/dlq.py +345 -0
- amb_core/hf_utils.py +536 -0
- amb_core/memory_broker.py +410 -0
- amb_core/models.py +141 -0
- amb_core/persistence.py +529 -0
- amb_core/schema.py +294 -0
- amb_core/tracing.py +358 -0
- atr/__init__.py +640 -0
- atr/access.py +348 -0
- atr/composition.py +645 -0
- atr/decorator.py +357 -0
- atr/executor.py +384 -0
- atr/health.py +557 -0
- atr/hf_utils.py +449 -0
- atr/injection.py +422 -0
- atr/metrics.py +440 -0
- atr/policies.py +403 -0
- atr/py.typed +2 -0
- atr/registry.py +452 -0
- atr/schema.py +480 -0
- atr/tools/safe/__init__.py +75 -0
- atr/tools/safe/calculator.py +467 -0
- atr/tools/safe/datetime_tool.py +443 -0
- atr/tools/safe/file_reader.py +402 -0
- atr/tools/safe/http_client.py +316 -0
- atr/tools/safe/json_parser.py +374 -0
- atr/tools/safe/text_tool.py +537 -0
- atr/tools/safe/toolkit.py +175 -0
- caas/__init__.py +162 -0
- caas/api/__init__.py +7 -0
- caas/api/server.py +1328 -0
- caas/caching.py +834 -0
- caas/cli.py +210 -0
- caas/conversation.py +223 -0
- caas/decay.py +72 -0
- caas/detection/__init__.py +9 -0
- caas/detection/detector.py +238 -0
- caas/enrichment.py +130 -0
- caas/gateway/__init__.py +27 -0
- caas/gateway/trust_gateway.py +474 -0
- caas/hf_utils.py +479 -0
- caas/ingestion/__init__.py +23 -0
- caas/ingestion/processors.py +253 -0
- caas/ingestion/structure_parser.py +188 -0
- caas/models.py +356 -0
- caas/pragmatic_truth.py +444 -0
- caas/routing/__init__.py +10 -0
- caas/routing/heuristic_router.py +58 -0
- caas/storage/__init__.py +9 -0
- caas/storage/store.py +389 -0
- caas/triad.py +213 -0
- caas/tuning/__init__.py +9 -0
- caas/tuning/tuner.py +329 -0
- caas/vfs/__init__.py +14 -0
- caas/vfs/filesystem.py +452 -0
- cmvk/__init__.py +218 -0
- cmvk/audit.py +402 -0
- cmvk/benchmarks.py +478 -0
- cmvk/constitutional.py +904 -0
- cmvk/hf_utils.py +301 -0
- cmvk/metrics.py +473 -0
- cmvk/profiles.py +300 -0
- cmvk/py.typed +0 -0
- cmvk/types.py +12 -0
- cmvk/verification.py +956 -0
- emk/__init__.py +89 -0
- emk/causal.py +352 -0
- emk/hf_utils.py +421 -0
- emk/indexer.py +83 -0
- emk/py.typed +0 -0
- emk/schema.py +204 -0
- emk/sleep_cycle.py +347 -0
- emk/store.py +281 -0
- iatp/__init__.py +166 -0
- iatp/attestation.py +461 -0
- iatp/cli.py +317 -0
- iatp/hf_utils.py +472 -0
- iatp/ipc_pipes.py +580 -0
- iatp/main.py +412 -0
- iatp/models/__init__.py +447 -0
- iatp/policy_engine.py +337 -0
- iatp/py.typed +2 -0
- iatp/recovery.py +321 -0
- iatp/security/__init__.py +270 -0
- iatp/sidecar/__init__.py +519 -0
- iatp/telemetry/__init__.py +164 -0
- iatp/tests/__init__.py +1 -0
- iatp/tests/test_attestation.py +370 -0
- iatp/tests/test_cli.py +131 -0
- iatp/tests/test_ed25519_attestation.py +211 -0
- iatp/tests/test_models.py +130 -0
- iatp/tests/test_policy_engine.py +347 -0
- iatp/tests/test_recovery.py +281 -0
- iatp/tests/test_security.py +222 -0
- iatp/tests/test_sidecar.py +167 -0
- iatp/tests/test_telemetry.py +175 -0
- mcp_kernel_server/__init__.py +28 -0
- mcp_kernel_server/cli.py +274 -0
- mcp_kernel_server/resources.py +217 -0
- mcp_kernel_server/server.py +564 -0
- mcp_kernel_server/tools.py +1174 -0
- mute_agent/__init__.py +68 -0
- mute_agent/core/__init__.py +1 -0
- mute_agent/core/execution_agent.py +166 -0
- mute_agent/core/handshake_protocol.py +201 -0
- mute_agent/core/reasoning_agent.py +238 -0
- mute_agent/knowledge_graph/__init__.py +1 -0
- mute_agent/knowledge_graph/graph_elements.py +65 -0
- mute_agent/knowledge_graph/multidimensional_graph.py +170 -0
- mute_agent/knowledge_graph/subgraph.py +224 -0
- mute_agent/listener/__init__.py +43 -0
- mute_agent/listener/adapters/__init__.py +31 -0
- mute_agent/listener/adapters/base_adapter.py +189 -0
- mute_agent/listener/adapters/caas_adapter.py +344 -0
- mute_agent/listener/adapters/control_plane_adapter.py +436 -0
- mute_agent/listener/adapters/iatp_adapter.py +332 -0
- mute_agent/listener/adapters/scak_adapter.py +251 -0
- mute_agent/listener/listener.py +610 -0
- mute_agent/listener/state_observer.py +436 -0
- mute_agent/listener/threshold_config.py +313 -0
- mute_agent/super_system/__init__.py +1 -0
- mute_agent/super_system/router.py +204 -0
- mute_agent/visualization/__init__.py +10 -0
- mute_agent/visualization/graph_debugger.py +502 -0
- nexus/README.md +60 -0
- nexus/__init__.py +51 -0
- nexus/arbiter.py +359 -0
- nexus/client.py +466 -0
- nexus/dmz.py +444 -0
- nexus/escrow.py +430 -0
- nexus/exceptions.py +286 -0
- nexus/pyproject.toml +36 -0
- nexus/registry.py +393 -0
- nexus/reputation.py +425 -0
- nexus/schemas/__init__.py +51 -0
- nexus/schemas/compliance.py +276 -0
- nexus/schemas/escrow.py +251 -0
- nexus/schemas/manifest.py +225 -0
- nexus/schemas/receipt.py +208 -0
- nexus/tests/__init__.py +0 -0
- nexus/tests/conftest.py +146 -0
- nexus/tests/test_arbiter.py +192 -0
- nexus/tests/test_dmz.py +194 -0
- nexus/tests/test_escrow.py +276 -0
- nexus/tests/test_exceptions.py +225 -0
- nexus/tests/test_registry.py +232 -0
- nexus/tests/test_reputation.py +328 -0
- nexus/tests/test_schemas.py +295 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
A2A Protocol Adapter for Agent-OS
|
|
5
|
+
==================================
|
|
6
|
+
|
|
7
|
+
Provides kernel-level governance for A2A (Agent-to-Agent) protocol tasks.
|
|
8
|
+
|
|
9
|
+
Enforces Agent-OS policies on incoming A2A task negotiations:
|
|
10
|
+
- Skill-level access control (which skills are allowed/blocked)
|
|
11
|
+
- Content filtering on task messages
|
|
12
|
+
- Rate limiting per source agent
|
|
13
|
+
- Audit trail of all A2A interactions
|
|
14
|
+
|
|
15
|
+
Works with or without the ``a2a-agentmesh`` package — accepts plain dicts
|
|
16
|
+
from JSON-RPC endpoints as well as typed objects.
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
>>> from agent_os.integrations.a2a_adapter import A2AGovernanceAdapter
|
|
20
|
+
>>>
|
|
21
|
+
>>> adapter = A2AGovernanceAdapter(
|
|
22
|
+
... allowed_skills=["search", "translate"],
|
|
23
|
+
... blocked_patterns=["DROP TABLE", "rm -rf"],
|
|
24
|
+
... min_trust_score=300,
|
|
25
|
+
... )
|
|
26
|
+
>>>
|
|
27
|
+
>>> # Evaluate incoming A2A task request
|
|
28
|
+
>>> result = adapter.evaluate_task({
|
|
29
|
+
... "skill_id": "search",
|
|
30
|
+
... "x-agentmesh-trust": {
|
|
31
|
+
... "source_did": "did:mesh:agent-a",
|
|
32
|
+
... "source_trust_score": 500,
|
|
33
|
+
... },
|
|
34
|
+
... "messages": [{"role": "user", "parts": [{"text": "Find weather"}]}],
|
|
35
|
+
... })
|
|
36
|
+
>>> assert result["allowed"]
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
from __future__ import annotations
|
|
40
|
+
|
|
41
|
+
import logging
|
|
42
|
+
import time
|
|
43
|
+
from dataclasses import dataclass, field
|
|
44
|
+
from typing import Any
|
|
45
|
+
|
|
46
|
+
logger = logging.getLogger(__name__)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass
|
|
50
|
+
class A2APolicy:
|
|
51
|
+
"""Policy for A2A task governance."""
|
|
52
|
+
|
|
53
|
+
allowed_skills: list[str] = field(default_factory=list)
|
|
54
|
+
blocked_skills: list[str] = field(default_factory=list)
|
|
55
|
+
blocked_patterns: list[str] = field(default_factory=list)
|
|
56
|
+
min_trust_score: int = 0
|
|
57
|
+
max_requests_per_minute: int = 100
|
|
58
|
+
require_trust_metadata: bool = False
|
|
59
|
+
log_all: bool = True
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class A2AEvaluation:
|
|
64
|
+
"""Result of evaluating an A2A task request."""
|
|
65
|
+
|
|
66
|
+
allowed: bool
|
|
67
|
+
reason: str = ""
|
|
68
|
+
source_did: str = ""
|
|
69
|
+
skill_id: str = ""
|
|
70
|
+
trust_score: int = 0
|
|
71
|
+
conversation_alert: Any | None = None
|
|
72
|
+
timestamp: float = field(default_factory=time.time)
|
|
73
|
+
|
|
74
|
+
def to_dict(self) -> dict[str, Any]:
|
|
75
|
+
d = {
|
|
76
|
+
"allowed": self.allowed,
|
|
77
|
+
"reason": self.reason,
|
|
78
|
+
"source_did": self.source_did,
|
|
79
|
+
"skill_id": self.skill_id,
|
|
80
|
+
"trust_score": self.trust_score,
|
|
81
|
+
}
|
|
82
|
+
if self.conversation_alert is not None:
|
|
83
|
+
d["conversation_alert"] = self.conversation_alert.to_dict()
|
|
84
|
+
return d
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class A2AGovernanceAdapter:
|
|
88
|
+
"""
|
|
89
|
+
Agent-OS governance adapter for A2A protocol tasks.
|
|
90
|
+
|
|
91
|
+
Evaluates incoming A2A task requests (as dicts or typed objects)
|
|
92
|
+
against Agent-OS policies. Optionally runs a ConversationGuardian
|
|
93
|
+
to detect escalation, offensive intent, and feedback loops in
|
|
94
|
+
inter-agent message content.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def __init__(
|
|
98
|
+
self,
|
|
99
|
+
policy: A2APolicy | None = None,
|
|
100
|
+
*,
|
|
101
|
+
allowed_skills: list[str] | None = None,
|
|
102
|
+
blocked_skills: list[str] | None = None,
|
|
103
|
+
blocked_patterns: list[str] | None = None,
|
|
104
|
+
min_trust_score: int = 0,
|
|
105
|
+
max_requests_per_minute: int = 100,
|
|
106
|
+
conversation_guardian: Any | None = None,
|
|
107
|
+
):
|
|
108
|
+
if policy is not None:
|
|
109
|
+
self.policy = policy
|
|
110
|
+
else:
|
|
111
|
+
self.policy = A2APolicy(
|
|
112
|
+
allowed_skills=allowed_skills or [],
|
|
113
|
+
blocked_skills=blocked_skills or [],
|
|
114
|
+
blocked_patterns=blocked_patterns or [],
|
|
115
|
+
min_trust_score=min_trust_score,
|
|
116
|
+
max_requests_per_minute=max_requests_per_minute,
|
|
117
|
+
)
|
|
118
|
+
self._rate_tracker: dict[str, list[float]] = {}
|
|
119
|
+
self._evaluations: list[A2AEvaluation] = []
|
|
120
|
+
self._guardian = conversation_guardian
|
|
121
|
+
|
|
122
|
+
def _extract_fields(self, task: Any) -> dict[str, Any]:
|
|
123
|
+
"""Extract fields from a dict or typed object."""
|
|
124
|
+
if isinstance(task, dict):
|
|
125
|
+
trust = task.get("x-agentmesh-trust", {})
|
|
126
|
+
messages_raw = task.get("messages", [])
|
|
127
|
+
texts: list[str] = []
|
|
128
|
+
for m in messages_raw:
|
|
129
|
+
if isinstance(m, dict):
|
|
130
|
+
for part in m.get("parts", []):
|
|
131
|
+
if isinstance(part, dict) and "text" in part:
|
|
132
|
+
texts.append(part["text"])
|
|
133
|
+
return {
|
|
134
|
+
"skill_id": task.get("skill_id", ""),
|
|
135
|
+
"source_did": trust.get("source_did", ""),
|
|
136
|
+
"trust_score": trust.get("source_trust_score", 0),
|
|
137
|
+
"texts": texts,
|
|
138
|
+
}
|
|
139
|
+
# Typed object (e.g. TaskEnvelope)
|
|
140
|
+
texts = []
|
|
141
|
+
for m in getattr(task, "messages", []):
|
|
142
|
+
content = getattr(m, "content", "")
|
|
143
|
+
if content:
|
|
144
|
+
texts.append(content)
|
|
145
|
+
return {
|
|
146
|
+
"skill_id": getattr(task, "skill_id", ""),
|
|
147
|
+
"source_did": getattr(task, "source_did", ""),
|
|
148
|
+
"trust_score": getattr(task, "source_trust_score", 0),
|
|
149
|
+
"texts": texts,
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
def _check_content(self, texts: list[str]) -> tuple[bool, str]:
|
|
153
|
+
for text in texts:
|
|
154
|
+
text_lower = text.lower()
|
|
155
|
+
for pattern in self.policy.blocked_patterns:
|
|
156
|
+
if pattern.lower() in text_lower:
|
|
157
|
+
return False, f"Content matches blocked pattern: '{pattern}'"
|
|
158
|
+
return True, ""
|
|
159
|
+
|
|
160
|
+
def evaluate_task(
|
|
161
|
+
self,
|
|
162
|
+
task: Any,
|
|
163
|
+
*,
|
|
164
|
+
conversation_id: str = "",
|
|
165
|
+
sender: str = "",
|
|
166
|
+
receiver: str = "",
|
|
167
|
+
) -> A2AEvaluation:
|
|
168
|
+
"""
|
|
169
|
+
Evaluate an A2A task request against policies.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
task: Dict (from JSON-RPC) or typed TaskEnvelope object.
|
|
173
|
+
conversation_id: Optional conversation ID for guardian analysis.
|
|
174
|
+
sender: Optional sender agent ID for guardian analysis.
|
|
175
|
+
receiver: Optional receiver agent ID for guardian analysis.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
A2AEvaluation with allowed/denied and reason.
|
|
179
|
+
"""
|
|
180
|
+
fields = self._extract_fields(task)
|
|
181
|
+
skill_id = fields["skill_id"]
|
|
182
|
+
source_did = fields["source_did"]
|
|
183
|
+
trust_score = fields["trust_score"]
|
|
184
|
+
|
|
185
|
+
def deny(reason: str) -> A2AEvaluation:
|
|
186
|
+
e = A2AEvaluation(
|
|
187
|
+
allowed=False,
|
|
188
|
+
reason=reason,
|
|
189
|
+
source_did=source_did,
|
|
190
|
+
skill_id=skill_id,
|
|
191
|
+
trust_score=trust_score,
|
|
192
|
+
)
|
|
193
|
+
self._evaluations.append(e)
|
|
194
|
+
return e
|
|
195
|
+
|
|
196
|
+
# 1. Trust metadata required
|
|
197
|
+
if self.policy.require_trust_metadata and not source_did:
|
|
198
|
+
return deny("Trust metadata (source DID) required")
|
|
199
|
+
|
|
200
|
+
# 2. Skill blocked
|
|
201
|
+
if skill_id in self.policy.blocked_skills:
|
|
202
|
+
return deny(f"Skill '{skill_id}' is blocked")
|
|
203
|
+
|
|
204
|
+
# 3. Skill not in allow list
|
|
205
|
+
if self.policy.allowed_skills and skill_id not in self.policy.allowed_skills:
|
|
206
|
+
return deny(f"Skill '{skill_id}' not in allowed list")
|
|
207
|
+
|
|
208
|
+
# 4. Trust score
|
|
209
|
+
if trust_score < self.policy.min_trust_score:
|
|
210
|
+
return deny(
|
|
211
|
+
f"Trust score {trust_score} below minimum {self.policy.min_trust_score}"
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# 5. Content check
|
|
215
|
+
ok, reason = self._check_content(fields["texts"])
|
|
216
|
+
if not ok:
|
|
217
|
+
return deny(reason)
|
|
218
|
+
|
|
219
|
+
# 5.5 Conversation guardian analysis
|
|
220
|
+
conversation_alert = None
|
|
221
|
+
if self._guardian and fields["texts"]:
|
|
222
|
+
from .conversation_guardian import AlertAction
|
|
223
|
+
|
|
224
|
+
conv_id = conversation_id or task.get("id", "") if isinstance(task, dict) else getattr(task, "id", "")
|
|
225
|
+
src = sender or source_did
|
|
226
|
+
dst = receiver or skill_id
|
|
227
|
+
combined_text = " ".join(fields["texts"])
|
|
228
|
+
conversation_alert = self._guardian.analyze_message(
|
|
229
|
+
conversation_id=conv_id or "unknown",
|
|
230
|
+
sender=src or "unknown",
|
|
231
|
+
receiver=dst or "unknown",
|
|
232
|
+
content=combined_text,
|
|
233
|
+
)
|
|
234
|
+
if conversation_alert.action in (AlertAction.BREAK, AlertAction.QUARANTINE):
|
|
235
|
+
return deny(
|
|
236
|
+
f"Conversation guardian: {conversation_alert.action.value} — "
|
|
237
|
+
+ "; ".join(conversation_alert.reasons)
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# 6. Rate limit
|
|
241
|
+
if source_did:
|
|
242
|
+
now = time.time()
|
|
243
|
+
timestamps = self._rate_tracker.get(source_did, [])
|
|
244
|
+
timestamps = [t for t in timestamps if t > now - 60]
|
|
245
|
+
if len(timestamps) >= self.policy.max_requests_per_minute:
|
|
246
|
+
return deny(f"Rate limit exceeded ({self.policy.max_requests_per_minute}/min)")
|
|
247
|
+
timestamps.append(now)
|
|
248
|
+
self._rate_tracker[source_did] = timestamps
|
|
249
|
+
|
|
250
|
+
# Allowed
|
|
251
|
+
e = A2AEvaluation(
|
|
252
|
+
allowed=True,
|
|
253
|
+
reason="Allowed",
|
|
254
|
+
source_did=source_did,
|
|
255
|
+
skill_id=skill_id,
|
|
256
|
+
trust_score=trust_score,
|
|
257
|
+
conversation_alert=conversation_alert,
|
|
258
|
+
)
|
|
259
|
+
self._evaluations.append(e)
|
|
260
|
+
return e
|
|
261
|
+
|
|
262
|
+
def get_evaluations(self) -> list[A2AEvaluation]:
|
|
263
|
+
return list(self._evaluations)
|
|
264
|
+
|
|
265
|
+
def get_stats(self) -> dict[str, Any]:
|
|
266
|
+
total = len(self._evaluations)
|
|
267
|
+
allowed = sum(1 for e in self._evaluations if e.allowed)
|
|
268
|
+
return {
|
|
269
|
+
"total": total,
|
|
270
|
+
"allowed": allowed,
|
|
271
|
+
"denied": total - allowed,
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
__all__ = [
|
|
276
|
+
"A2AGovernanceAdapter",
|
|
277
|
+
"A2APolicy",
|
|
278
|
+
"A2AEvaluation",
|
|
279
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
Agent-Lightning Integration — backward-compatibility shim.
|
|
5
|
+
|
|
6
|
+
The integration has moved to the **agent-lightning** package
|
|
7
|
+
(``agent_lightning_gov``). All symbols are re-exported here so
|
|
8
|
+
existing ``from agent_os.integrations.agent_lightning …`` imports
|
|
9
|
+
continue to work.
|
|
10
|
+
|
|
11
|
+
.. deprecated::
|
|
12
|
+
Import directly from ``agent_lightning_gov`` instead.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# ruff: noqa: F401
|
|
16
|
+
from agent_lightning_gov import ( # noqa: F401 – re-export
|
|
17
|
+
FlightRecorderEmitter,
|
|
18
|
+
GovernedEnvironment,
|
|
19
|
+
GovernedRunner,
|
|
20
|
+
PolicyReward,
|
|
21
|
+
policy_penalty,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"GovernedRunner",
|
|
26
|
+
"PolicyReward",
|
|
27
|
+
"policy_penalty",
|
|
28
|
+
"FlightRecorderEmitter",
|
|
29
|
+
"GovernedEnvironment",
|
|
30
|
+
]
|