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,430 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Supervisor Agents - Recursive Governance
|
|
6
|
+
|
|
7
|
+
Eventually, the Control Plane itself will be too complex for humans to manage
|
|
8
|
+
manually. We need Supervisor Agents - specialized, highly constrained agents
|
|
9
|
+
whose only job is to watch the logs of worker agents and flag violations to
|
|
10
|
+
a human.
|
|
11
|
+
|
|
12
|
+
Agents watching agents, bound by a constitution of code.
|
|
13
|
+
|
|
14
|
+
Research Foundations:
|
|
15
|
+
- Hierarchical control patterns from "Multi-Agent Systems: A Survey"
|
|
16
|
+
(arXiv:2308.05391, 2023) - supervision hierarchies, cascade failure prevention
|
|
17
|
+
- Anomaly detection patterns for monitoring agent behavior
|
|
18
|
+
- Recursive governance inspired by "MAESTRO: A Threat Modeling Framework"
|
|
19
|
+
(CSA, 2025) - multi-agent security monitoring
|
|
20
|
+
- Human-in-the-loop patterns for escalation and intervention
|
|
21
|
+
|
|
22
|
+
See docs/RESEARCH_FOUNDATION.md for complete references.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from typing import Any, Dict, List, Optional, Callable
|
|
26
|
+
from dataclasses import dataclass, field
|
|
27
|
+
from datetime import datetime, timedelta
|
|
28
|
+
from enum import Enum
|
|
29
|
+
from .agent_kernel import ActionType, ExecutionStatus
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ViolationType(Enum):
|
|
33
|
+
"""Types of violations a supervisor can detect"""
|
|
34
|
+
EXCESSIVE_RISK = "excessive_risk"
|
|
35
|
+
RATE_LIMIT_APPROACHING = "rate_limit_approaching"
|
|
36
|
+
REPEATED_FAILURES = "repeated_failures"
|
|
37
|
+
POLICY_CIRCUMVENTION = "policy_circumvention"
|
|
38
|
+
ANOMALOUS_BEHAVIOR = "anomalous_behavior"
|
|
39
|
+
RESOURCE_EXHAUSTION = "resource_exhaustion"
|
|
40
|
+
SUSPICIOUS_PATTERN = "suspicious_pattern"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class Violation:
|
|
45
|
+
"""A violation detected by a supervisor"""
|
|
46
|
+
violation_id: str
|
|
47
|
+
violation_type: ViolationType
|
|
48
|
+
agent_id: str
|
|
49
|
+
severity: str # "low", "medium", "high", "critical"
|
|
50
|
+
description: str
|
|
51
|
+
evidence: Dict[str, Any]
|
|
52
|
+
detected_at: datetime
|
|
53
|
+
requires_human_review: bool = False
|
|
54
|
+
auto_remediation: Optional[str] = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class SupervisorConfig:
|
|
59
|
+
"""Configuration for a supervisor agent"""
|
|
60
|
+
supervisor_id: str
|
|
61
|
+
name: str
|
|
62
|
+
watches: List[str] # Agent IDs to watch
|
|
63
|
+
detection_rules: List[Callable] = field(default_factory=list)
|
|
64
|
+
escalation_threshold: int = 3 # Number of violations before escalation
|
|
65
|
+
auto_remediate: bool = False # Can supervisor take automatic action?
|
|
66
|
+
notification_channels: List[str] = field(default_factory=list)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class SupervisorAgent:
|
|
70
|
+
"""
|
|
71
|
+
A supervisor agent that watches worker agents and flags violations.
|
|
72
|
+
|
|
73
|
+
Supervisors are highly constrained agents that:
|
|
74
|
+
1. Only read logs and metrics
|
|
75
|
+
2. Cannot execute actions
|
|
76
|
+
3. Only flag violations to humans
|
|
77
|
+
4. Optionally suggest remediations
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
def __init__(self, config: SupervisorConfig):
|
|
81
|
+
self.config = config
|
|
82
|
+
self.violations: List[Violation] = []
|
|
83
|
+
self.violation_count_by_agent: Dict[str, int] = {}
|
|
84
|
+
self.last_check: datetime = datetime.now()
|
|
85
|
+
|
|
86
|
+
def watch_execution_logs(self, execution_log: List[Dict[str, Any]]) -> List[Violation]:
|
|
87
|
+
"""
|
|
88
|
+
Watch execution logs and detect violations.
|
|
89
|
+
|
|
90
|
+
Returns list of new violations detected.
|
|
91
|
+
"""
|
|
92
|
+
new_violations = []
|
|
93
|
+
|
|
94
|
+
# Filter logs for watched agents
|
|
95
|
+
relevant_logs = [
|
|
96
|
+
log for log in execution_log
|
|
97
|
+
if log.get('agent_id') in self.config.watches
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
# Apply detection rules
|
|
101
|
+
for rule in self.config.detection_rules:
|
|
102
|
+
violations = rule(relevant_logs, self)
|
|
103
|
+
new_violations.extend(violations)
|
|
104
|
+
|
|
105
|
+
# Store violations
|
|
106
|
+
self.violations.extend(new_violations)
|
|
107
|
+
|
|
108
|
+
# Update counts
|
|
109
|
+
for violation in new_violations:
|
|
110
|
+
agent_id = violation.agent_id
|
|
111
|
+
self.violation_count_by_agent[agent_id] = \
|
|
112
|
+
self.violation_count_by_agent.get(agent_id, 0) + 1
|
|
113
|
+
|
|
114
|
+
# Check for escalation
|
|
115
|
+
self._check_escalation()
|
|
116
|
+
|
|
117
|
+
self.last_check = datetime.now()
|
|
118
|
+
return new_violations
|
|
119
|
+
|
|
120
|
+
def watch_audit_logs(self, audit_log: List[Dict[str, Any]]) -> List[Violation]:
|
|
121
|
+
"""
|
|
122
|
+
Watch audit logs for policy violations and suspicious patterns.
|
|
123
|
+
"""
|
|
124
|
+
new_violations = []
|
|
125
|
+
|
|
126
|
+
# Filter for watched agents
|
|
127
|
+
relevant_logs = [
|
|
128
|
+
log for log in audit_log
|
|
129
|
+
if log.get('details', {}).get('agent_id') in self.config.watches
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
# Look for denied requests
|
|
133
|
+
denials = [log for log in relevant_logs if 'denied' in log.get('event_type', '')]
|
|
134
|
+
if len(denials) > 5: # Threshold for suspicious behavior
|
|
135
|
+
new_violations.append(Violation(
|
|
136
|
+
violation_id=f"v_{datetime.now().timestamp()}",
|
|
137
|
+
violation_type=ViolationType.POLICY_CIRCUMVENTION,
|
|
138
|
+
agent_id=self.config.watches[0] if self.config.watches else "unknown",
|
|
139
|
+
severity="high",
|
|
140
|
+
description=f"Agent has {len(denials)} denied requests, possible circumvention attempt",
|
|
141
|
+
evidence={"denials": denials},
|
|
142
|
+
detected_at=datetime.now(),
|
|
143
|
+
requires_human_review=True
|
|
144
|
+
))
|
|
145
|
+
|
|
146
|
+
self.violations.extend(new_violations)
|
|
147
|
+
return new_violations
|
|
148
|
+
|
|
149
|
+
def analyze_risk_patterns(self, execution_log: List[Dict[str, Any]]) -> List[Violation]:
|
|
150
|
+
"""
|
|
151
|
+
Analyze execution patterns for risk trends.
|
|
152
|
+
"""
|
|
153
|
+
new_violations = []
|
|
154
|
+
|
|
155
|
+
# Group by agent
|
|
156
|
+
for agent_id in self.config.watches:
|
|
157
|
+
agent_logs = [log for log in execution_log if log.get('agent_id') == agent_id]
|
|
158
|
+
|
|
159
|
+
# Calculate average risk
|
|
160
|
+
risks = [log.get('risk_score', 0) for log in agent_logs if log.get('success')]
|
|
161
|
+
if risks:
|
|
162
|
+
avg_risk = sum(risks) / len(risks)
|
|
163
|
+
|
|
164
|
+
# Flag if average risk is increasing
|
|
165
|
+
if avg_risk > 0.6:
|
|
166
|
+
new_violations.append(Violation(
|
|
167
|
+
violation_id=f"v_{datetime.now().timestamp()}",
|
|
168
|
+
violation_type=ViolationType.EXCESSIVE_RISK,
|
|
169
|
+
agent_id=agent_id,
|
|
170
|
+
severity="medium",
|
|
171
|
+
description=f"Agent average risk score is {avg_risk:.2f}, exceeds safe threshold",
|
|
172
|
+
evidence={"average_risk": avg_risk, "sample_size": len(risks)},
|
|
173
|
+
detected_at=datetime.now(),
|
|
174
|
+
auto_remediation="reduce_agent_permissions"
|
|
175
|
+
))
|
|
176
|
+
|
|
177
|
+
self.violations.extend(new_violations)
|
|
178
|
+
return new_violations
|
|
179
|
+
|
|
180
|
+
def _check_escalation(self):
|
|
181
|
+
"""Check if any agent needs escalation to human"""
|
|
182
|
+
for agent_id, count in self.violation_count_by_agent.items():
|
|
183
|
+
if count >= self.config.escalation_threshold:
|
|
184
|
+
# Create escalation violation
|
|
185
|
+
escalation = Violation(
|
|
186
|
+
violation_id=f"escalation_{agent_id}_{datetime.now().timestamp()}",
|
|
187
|
+
violation_type=ViolationType.ANOMALOUS_BEHAVIOR,
|
|
188
|
+
agent_id=agent_id,
|
|
189
|
+
severity="critical",
|
|
190
|
+
description=f"Agent has {count} violations, exceeds escalation threshold",
|
|
191
|
+
evidence={"violation_count": count, "threshold": self.config.escalation_threshold},
|
|
192
|
+
detected_at=datetime.now(),
|
|
193
|
+
requires_human_review=True
|
|
194
|
+
)
|
|
195
|
+
self.violations.append(escalation)
|
|
196
|
+
|
|
197
|
+
# Reset count after escalation
|
|
198
|
+
self.violation_count_by_agent[agent_id] = 0
|
|
199
|
+
|
|
200
|
+
def get_violations(
|
|
201
|
+
self,
|
|
202
|
+
agent_id: Optional[str] = None,
|
|
203
|
+
severity: Optional[str] = None,
|
|
204
|
+
requires_human: Optional[bool] = None
|
|
205
|
+
) -> List[Violation]:
|
|
206
|
+
"""Get violations with optional filters"""
|
|
207
|
+
violations = self.violations
|
|
208
|
+
|
|
209
|
+
if agent_id:
|
|
210
|
+
violations = [v for v in violations if v.agent_id == agent_id]
|
|
211
|
+
|
|
212
|
+
if severity:
|
|
213
|
+
violations = [v for v in violations if v.severity == severity]
|
|
214
|
+
|
|
215
|
+
if requires_human is not None:
|
|
216
|
+
violations = [v for v in violations if v.requires_human_review == requires_human]
|
|
217
|
+
|
|
218
|
+
return violations
|
|
219
|
+
|
|
220
|
+
def get_summary(self) -> Dict[str, Any]:
|
|
221
|
+
"""Get summary of supervisor activity"""
|
|
222
|
+
return {
|
|
223
|
+
"supervisor_id": self.config.supervisor_id,
|
|
224
|
+
"watching": self.config.watches,
|
|
225
|
+
"total_violations": len(self.violations),
|
|
226
|
+
"violations_by_type": self._count_by_type(),
|
|
227
|
+
"violations_by_severity": self._count_by_severity(),
|
|
228
|
+
"requires_human_review": len([v for v in self.violations if v.requires_human_review]),
|
|
229
|
+
"last_check": self.last_check.isoformat()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
def _count_by_type(self) -> Dict[str, int]:
|
|
233
|
+
"""Count violations by type"""
|
|
234
|
+
counts = {}
|
|
235
|
+
for v in self.violations:
|
|
236
|
+
vtype = v.violation_type.value
|
|
237
|
+
counts[vtype] = counts.get(vtype, 0) + 1
|
|
238
|
+
return counts
|
|
239
|
+
|
|
240
|
+
def _count_by_severity(self) -> Dict[str, int]:
|
|
241
|
+
"""Count violations by severity"""
|
|
242
|
+
counts = {}
|
|
243
|
+
for v in self.violations:
|
|
244
|
+
counts[v.severity] = counts.get(v.severity, 0) + 1
|
|
245
|
+
return counts
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
# Detection rule functions
|
|
249
|
+
|
|
250
|
+
def detect_repeated_failures(logs: List[Dict[str, Any]], supervisor: SupervisorAgent) -> List[Violation]:
|
|
251
|
+
"""Detect agents with repeated failures"""
|
|
252
|
+
violations = []
|
|
253
|
+
|
|
254
|
+
for agent_id in supervisor.config.watches:
|
|
255
|
+
agent_logs = [log for log in logs if log.get('agent_id') == agent_id]
|
|
256
|
+
failures = [log for log in agent_logs if not log.get('success', True)]
|
|
257
|
+
|
|
258
|
+
if len(failures) >= 5:
|
|
259
|
+
violations.append(Violation(
|
|
260
|
+
violation_id=f"v_{datetime.now().timestamp()}",
|
|
261
|
+
violation_type=ViolationType.REPEATED_FAILURES,
|
|
262
|
+
agent_id=agent_id,
|
|
263
|
+
severity="medium",
|
|
264
|
+
description=f"Agent has {len(failures)} failures in recent history",
|
|
265
|
+
evidence={"failure_count": len(failures), "sample": failures[:3]},
|
|
266
|
+
detected_at=datetime.now(),
|
|
267
|
+
auto_remediation="review_agent_configuration"
|
|
268
|
+
))
|
|
269
|
+
|
|
270
|
+
return violations
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def detect_rate_limit_approaching(logs: List[Dict[str, Any]], supervisor: SupervisorAgent) -> List[Violation]:
|
|
274
|
+
"""Detect agents approaching rate limits"""
|
|
275
|
+
violations = []
|
|
276
|
+
|
|
277
|
+
# This would need access to quota information
|
|
278
|
+
# Simplified version here
|
|
279
|
+
for agent_id in supervisor.config.watches:
|
|
280
|
+
agent_logs = [log for log in logs if log.get('agent_id') == agent_id]
|
|
281
|
+
|
|
282
|
+
# Check recent activity
|
|
283
|
+
recent_window = datetime.now() - timedelta(minutes=1)
|
|
284
|
+
recent_logs = []
|
|
285
|
+
for log in agent_logs:
|
|
286
|
+
timestamp_str = log.get('timestamp')
|
|
287
|
+
if timestamp_str:
|
|
288
|
+
try:
|
|
289
|
+
log_time = datetime.fromisoformat(timestamp_str)
|
|
290
|
+
if log_time > recent_window:
|
|
291
|
+
recent_logs.append(log)
|
|
292
|
+
except (ValueError, TypeError):
|
|
293
|
+
# Skip logs with invalid timestamps
|
|
294
|
+
continue
|
|
295
|
+
|
|
296
|
+
if len(recent_logs) > 50: # High activity
|
|
297
|
+
violations.append(Violation(
|
|
298
|
+
violation_id=f"v_{datetime.now().timestamp()}",
|
|
299
|
+
violation_type=ViolationType.RATE_LIMIT_APPROACHING,
|
|
300
|
+
agent_id=agent_id,
|
|
301
|
+
severity="low",
|
|
302
|
+
description=f"Agent has {len(recent_logs)} requests in last minute, approaching limits",
|
|
303
|
+
evidence={"recent_requests": len(recent_logs)},
|
|
304
|
+
detected_at=datetime.now(),
|
|
305
|
+
auto_remediation="throttle_agent"
|
|
306
|
+
))
|
|
307
|
+
|
|
308
|
+
return violations
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def detect_suspicious_patterns(logs: List[Dict[str, Any]], supervisor: SupervisorAgent) -> List[Violation]:
|
|
312
|
+
"""Detect suspicious behavioral patterns"""
|
|
313
|
+
violations = []
|
|
314
|
+
|
|
315
|
+
for agent_id in supervisor.config.watches:
|
|
316
|
+
agent_logs = [log for log in logs if log.get('agent_id') == agent_id]
|
|
317
|
+
|
|
318
|
+
# Look for unusual action patterns
|
|
319
|
+
action_types = [log.get('action_type') for log in agent_logs]
|
|
320
|
+
|
|
321
|
+
# If agent suddenly starts doing different types of actions
|
|
322
|
+
unique_actions = set(action_types)
|
|
323
|
+
if len(unique_actions) > 5: # Agent doing many different things
|
|
324
|
+
violations.append(Violation(
|
|
325
|
+
violation_id=f"v_{datetime.now().timestamp()}",
|
|
326
|
+
violation_type=ViolationType.SUSPICIOUS_PATTERN,
|
|
327
|
+
agent_id=agent_id,
|
|
328
|
+
severity="medium",
|
|
329
|
+
description=f"Agent performing {len(unique_actions)} different action types, possible anomaly",
|
|
330
|
+
evidence={"action_types": list(unique_actions)},
|
|
331
|
+
detected_at=datetime.now(),
|
|
332
|
+
requires_human_review=True
|
|
333
|
+
))
|
|
334
|
+
|
|
335
|
+
return violations
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class SupervisorNetwork:
|
|
339
|
+
"""
|
|
340
|
+
Network of supervisor agents with hierarchical oversight.
|
|
341
|
+
|
|
342
|
+
Enables recursive governance where supervisors can watch other supervisors.
|
|
343
|
+
"""
|
|
344
|
+
|
|
345
|
+
def __init__(self):
|
|
346
|
+
self.supervisors: Dict[str, SupervisorAgent] = {}
|
|
347
|
+
self.hierarchy: Dict[str, List[str]] = {} # supervisor -> list of watched supervisors
|
|
348
|
+
|
|
349
|
+
def add_supervisor(self, supervisor: SupervisorAgent):
|
|
350
|
+
"""Add a supervisor to the network"""
|
|
351
|
+
self.supervisors[supervisor.config.supervisor_id] = supervisor
|
|
352
|
+
|
|
353
|
+
def add_supervisor_hierarchy(self, parent_supervisor_id: str, child_supervisor_ids: List[str]):
|
|
354
|
+
"""Create hierarchical supervision (supervisors watching supervisors)"""
|
|
355
|
+
self.hierarchy[parent_supervisor_id] = child_supervisor_ids
|
|
356
|
+
|
|
357
|
+
def run_supervision_cycle(
|
|
358
|
+
self,
|
|
359
|
+
execution_log: List[Dict[str, Any]],
|
|
360
|
+
audit_log: List[Dict[str, Any]]
|
|
361
|
+
) -> Dict[str, List[Violation]]:
|
|
362
|
+
"""
|
|
363
|
+
Run a complete supervision cycle across all supervisors.
|
|
364
|
+
|
|
365
|
+
Returns violations by supervisor ID.
|
|
366
|
+
"""
|
|
367
|
+
all_violations = {}
|
|
368
|
+
|
|
369
|
+
# First level: Watch worker agents
|
|
370
|
+
for supervisor_id, supervisor in self.supervisors.items():
|
|
371
|
+
violations = []
|
|
372
|
+
violations.extend(supervisor.watch_execution_logs(execution_log))
|
|
373
|
+
violations.extend(supervisor.watch_audit_logs(audit_log))
|
|
374
|
+
violations.extend(supervisor.analyze_risk_patterns(execution_log))
|
|
375
|
+
all_violations[supervisor_id] = violations
|
|
376
|
+
|
|
377
|
+
# Second level: Supervisors watching supervisors (if hierarchy exists)
|
|
378
|
+
for parent_id, child_ids in self.hierarchy.items():
|
|
379
|
+
parent = self.supervisors.get(parent_id)
|
|
380
|
+
if parent:
|
|
381
|
+
# Collect violations from child supervisors
|
|
382
|
+
child_violations = []
|
|
383
|
+
for child_id in child_ids:
|
|
384
|
+
child_violations.extend(all_violations.get(child_id, []))
|
|
385
|
+
|
|
386
|
+
# Parent supervisor analyzes if children are working correctly
|
|
387
|
+
# (Simplified - in reality would have sophisticated checks)
|
|
388
|
+
if len(child_violations) > 100:
|
|
389
|
+
all_violations[parent_id] = all_violations.get(parent_id, []) + [
|
|
390
|
+
Violation(
|
|
391
|
+
violation_id=f"meta_v_{datetime.now().timestamp()}",
|
|
392
|
+
violation_type=ViolationType.ANOMALOUS_BEHAVIOR,
|
|
393
|
+
agent_id="supervisor_network",
|
|
394
|
+
severity="critical",
|
|
395
|
+
description=f"Child supervisors detected {len(child_violations)} violations",
|
|
396
|
+
evidence={"child_violations": len(child_violations)},
|
|
397
|
+
detected_at=datetime.now(),
|
|
398
|
+
requires_human_review=True
|
|
399
|
+
)
|
|
400
|
+
]
|
|
401
|
+
|
|
402
|
+
return all_violations
|
|
403
|
+
|
|
404
|
+
def get_network_summary(self) -> Dict[str, Any]:
|
|
405
|
+
"""Get summary of entire supervisor network"""
|
|
406
|
+
return {
|
|
407
|
+
"total_supervisors": len(self.supervisors),
|
|
408
|
+
"hierarchy_levels": len(self.hierarchy),
|
|
409
|
+
"supervisors": {
|
|
410
|
+
sid: supervisor.get_summary()
|
|
411
|
+
for sid, supervisor in self.supervisors.items()
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def create_default_supervisor(agent_ids: List[str]) -> SupervisorAgent:
|
|
417
|
+
"""Create a supervisor with default detection rules"""
|
|
418
|
+
config = SupervisorConfig(
|
|
419
|
+
supervisor_id=f"supervisor_{datetime.now().timestamp()}",
|
|
420
|
+
name="Default Supervisor",
|
|
421
|
+
watches=agent_ids,
|
|
422
|
+
detection_rules=[
|
|
423
|
+
detect_repeated_failures,
|
|
424
|
+
detect_rate_limit_approaching,
|
|
425
|
+
detect_suspicious_patterns
|
|
426
|
+
],
|
|
427
|
+
escalation_threshold=3,
|
|
428
|
+
auto_remediate=False
|
|
429
|
+
)
|
|
430
|
+
return SupervisorAgent(config)
|