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,313 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
Threshold Configuration for Listener Agent
|
|
5
|
+
|
|
6
|
+
Defines the configurable thresholds that determine when the Listener
|
|
7
|
+
should intervene in graph state changes.
|
|
8
|
+
|
|
9
|
+
This module provides:
|
|
10
|
+
- ThresholdType: Categories of monitored conditions
|
|
11
|
+
- InterventionLevel: Severity levels for responses
|
|
12
|
+
- ThresholdConfig: Configuration container
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import Dict, Any, Optional, List, Callable
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from enum import Enum, auto
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ThresholdType(Enum):
|
|
21
|
+
"""Categories of conditions the Listener monitors."""
|
|
22
|
+
|
|
23
|
+
# Graph state thresholds
|
|
24
|
+
CONSTRAINT_VIOLATION_COUNT = auto()
|
|
25
|
+
DIMENSION_CONFLICT_RATIO = auto()
|
|
26
|
+
ACTION_REJECTION_RATE = auto()
|
|
27
|
+
|
|
28
|
+
# Security thresholds (from iatp)
|
|
29
|
+
TRUST_SCORE_MINIMUM = auto()
|
|
30
|
+
PERMISSION_ESCALATION_COUNT = auto()
|
|
31
|
+
ANOMALY_SCORE_MAXIMUM = auto()
|
|
32
|
+
|
|
33
|
+
# Context thresholds (from caas)
|
|
34
|
+
CONTEXT_DRIFT_MAXIMUM = auto()
|
|
35
|
+
STALE_CONTEXT_AGE_SECONDS = auto()
|
|
36
|
+
AMBIGUITY_SCORE_MAXIMUM = auto()
|
|
37
|
+
|
|
38
|
+
# Performance thresholds
|
|
39
|
+
GRAPH_TRAVERSAL_LATENCY_MS = auto()
|
|
40
|
+
HANDSHAKE_TIMEOUT_MS = auto()
|
|
41
|
+
QUEUE_DEPTH_MAXIMUM = auto()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class InterventionLevel(Enum):
|
|
45
|
+
"""Severity levels for Listener intervention responses."""
|
|
46
|
+
|
|
47
|
+
# Passive observation only - log and continue
|
|
48
|
+
OBSERVE = "observe"
|
|
49
|
+
|
|
50
|
+
# Warning - emit event but allow action to proceed
|
|
51
|
+
WARN = "warn"
|
|
52
|
+
|
|
53
|
+
# Soft block - require confirmation before proceeding
|
|
54
|
+
SOFT_BLOCK = "soft_block"
|
|
55
|
+
|
|
56
|
+
# Hard block - prevent action entirely
|
|
57
|
+
HARD_BLOCK = "hard_block"
|
|
58
|
+
|
|
59
|
+
# Emergency - trigger system-wide alert/shutdown
|
|
60
|
+
EMERGENCY = "emergency"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class ThresholdRule:
|
|
65
|
+
"""A single threshold rule configuration."""
|
|
66
|
+
|
|
67
|
+
threshold_type: ThresholdType
|
|
68
|
+
value: float
|
|
69
|
+
intervention_level: InterventionLevel
|
|
70
|
+
description: str = ""
|
|
71
|
+
enabled: bool = True
|
|
72
|
+
|
|
73
|
+
# Optional custom evaluation function
|
|
74
|
+
# Signature: (current_value: float, threshold: float, context: Dict) -> bool
|
|
75
|
+
custom_evaluator: Optional[Callable[[float, float, Dict], bool]] = None
|
|
76
|
+
|
|
77
|
+
def evaluate(self, current_value: float, context: Optional[Dict[str, Any]] = None) -> bool:
|
|
78
|
+
"""
|
|
79
|
+
Evaluate if the threshold has been exceeded.
|
|
80
|
+
|
|
81
|
+
Returns True if threshold is exceeded (intervention needed).
|
|
82
|
+
"""
|
|
83
|
+
if not self.enabled:
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
if self.custom_evaluator:
|
|
87
|
+
return self.custom_evaluator(current_value, self.value, context or {})
|
|
88
|
+
|
|
89
|
+
# Default evaluation: current exceeds threshold
|
|
90
|
+
# For MINIMUM thresholds, we check if current is below
|
|
91
|
+
if "MINIMUM" in self.threshold_type.name:
|
|
92
|
+
return current_value < self.value
|
|
93
|
+
else:
|
|
94
|
+
return current_value > self.value
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass
|
|
98
|
+
class ThresholdConfig:
|
|
99
|
+
"""
|
|
100
|
+
Complete threshold configuration for the Listener Agent.
|
|
101
|
+
|
|
102
|
+
This configuration determines when the Listener transitions from
|
|
103
|
+
passive observation to active intervention.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
rules: Dict[ThresholdType, ThresholdRule] = field(default_factory=dict)
|
|
107
|
+
|
|
108
|
+
# Global settings
|
|
109
|
+
global_intervention_level: InterventionLevel = InterventionLevel.OBSERVE
|
|
110
|
+
escalation_enabled: bool = True
|
|
111
|
+
cooldown_seconds: float = 5.0
|
|
112
|
+
|
|
113
|
+
# Aggregation settings
|
|
114
|
+
window_size_seconds: float = 60.0
|
|
115
|
+
sample_rate_hz: float = 1.0
|
|
116
|
+
|
|
117
|
+
def add_rule(self, rule: ThresholdRule) -> None:
|
|
118
|
+
"""Add or update a threshold rule."""
|
|
119
|
+
self.rules[rule.threshold_type] = rule
|
|
120
|
+
|
|
121
|
+
def remove_rule(self, threshold_type: ThresholdType) -> None:
|
|
122
|
+
"""Remove a threshold rule."""
|
|
123
|
+
self.rules.pop(threshold_type, None)
|
|
124
|
+
|
|
125
|
+
def get_rule(self, threshold_type: ThresholdType) -> Optional[ThresholdRule]:
|
|
126
|
+
"""Get a threshold rule by type."""
|
|
127
|
+
return self.rules.get(threshold_type)
|
|
128
|
+
|
|
129
|
+
def enable_rule(self, threshold_type: ThresholdType) -> None:
|
|
130
|
+
"""Enable a specific rule."""
|
|
131
|
+
if threshold_type in self.rules:
|
|
132
|
+
self.rules[threshold_type].enabled = True
|
|
133
|
+
|
|
134
|
+
def disable_rule(self, threshold_type: ThresholdType) -> None:
|
|
135
|
+
"""Disable a specific rule."""
|
|
136
|
+
if threshold_type in self.rules:
|
|
137
|
+
self.rules[threshold_type].enabled = False
|
|
138
|
+
|
|
139
|
+
def evaluate_all(
|
|
140
|
+
self,
|
|
141
|
+
metrics: Dict[ThresholdType, float],
|
|
142
|
+
context: Optional[Dict[str, Any]] = None
|
|
143
|
+
) -> List[ThresholdRule]:
|
|
144
|
+
"""
|
|
145
|
+
Evaluate all rules against current metrics.
|
|
146
|
+
|
|
147
|
+
Returns list of rules that were triggered (threshold exceeded).
|
|
148
|
+
"""
|
|
149
|
+
triggered = []
|
|
150
|
+
for threshold_type, value in metrics.items():
|
|
151
|
+
rule = self.rules.get(threshold_type)
|
|
152
|
+
if rule and rule.evaluate(value, context):
|
|
153
|
+
triggered.append(rule)
|
|
154
|
+
return triggered
|
|
155
|
+
|
|
156
|
+
def get_maximum_intervention_level(
|
|
157
|
+
self,
|
|
158
|
+
triggered_rules: List[ThresholdRule]
|
|
159
|
+
) -> InterventionLevel:
|
|
160
|
+
"""
|
|
161
|
+
Get the highest intervention level from triggered rules.
|
|
162
|
+
|
|
163
|
+
Intervention levels ordered: OBSERVE < WARN < SOFT_BLOCK < HARD_BLOCK < EMERGENCY
|
|
164
|
+
"""
|
|
165
|
+
if not triggered_rules:
|
|
166
|
+
return self.global_intervention_level
|
|
167
|
+
|
|
168
|
+
level_order = [
|
|
169
|
+
InterventionLevel.OBSERVE,
|
|
170
|
+
InterventionLevel.WARN,
|
|
171
|
+
InterventionLevel.SOFT_BLOCK,
|
|
172
|
+
InterventionLevel.HARD_BLOCK,
|
|
173
|
+
InterventionLevel.EMERGENCY,
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
max_level = self.global_intervention_level
|
|
177
|
+
for rule in triggered_rules:
|
|
178
|
+
if level_order.index(rule.intervention_level) > level_order.index(max_level):
|
|
179
|
+
max_level = rule.intervention_level
|
|
180
|
+
|
|
181
|
+
return max_level
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
# Default threshold configuration for production use
|
|
185
|
+
DEFAULT_THRESHOLDS = ThresholdConfig(
|
|
186
|
+
rules={
|
|
187
|
+
ThresholdType.CONSTRAINT_VIOLATION_COUNT: ThresholdRule(
|
|
188
|
+
threshold_type=ThresholdType.CONSTRAINT_VIOLATION_COUNT,
|
|
189
|
+
value=3.0,
|
|
190
|
+
intervention_level=InterventionLevel.WARN,
|
|
191
|
+
description="Warn after 3 constraint violations in observation window",
|
|
192
|
+
),
|
|
193
|
+
ThresholdType.DIMENSION_CONFLICT_RATIO: ThresholdRule(
|
|
194
|
+
threshold_type=ThresholdType.DIMENSION_CONFLICT_RATIO,
|
|
195
|
+
value=0.5,
|
|
196
|
+
intervention_level=InterventionLevel.SOFT_BLOCK,
|
|
197
|
+
description="Soft block when >50% of dimensions conflict",
|
|
198
|
+
),
|
|
199
|
+
ThresholdType.ACTION_REJECTION_RATE: ThresholdRule(
|
|
200
|
+
threshold_type=ThresholdType.ACTION_REJECTION_RATE,
|
|
201
|
+
value=0.8,
|
|
202
|
+
intervention_level=InterventionLevel.HARD_BLOCK,
|
|
203
|
+
description="Hard block when >80% of actions are rejected",
|
|
204
|
+
),
|
|
205
|
+
ThresholdType.TRUST_SCORE_MINIMUM: ThresholdRule(
|
|
206
|
+
threshold_type=ThresholdType.TRUST_SCORE_MINIMUM,
|
|
207
|
+
value=0.3,
|
|
208
|
+
intervention_level=InterventionLevel.HARD_BLOCK,
|
|
209
|
+
description="Hard block when trust score falls below 0.3",
|
|
210
|
+
),
|
|
211
|
+
ThresholdType.PERMISSION_ESCALATION_COUNT: ThresholdRule(
|
|
212
|
+
threshold_type=ThresholdType.PERMISSION_ESCALATION_COUNT,
|
|
213
|
+
value=2.0,
|
|
214
|
+
intervention_level=InterventionLevel.EMERGENCY,
|
|
215
|
+
description="Emergency alert on 2+ permission escalation attempts",
|
|
216
|
+
),
|
|
217
|
+
ThresholdType.ANOMALY_SCORE_MAXIMUM: ThresholdRule(
|
|
218
|
+
threshold_type=ThresholdType.ANOMALY_SCORE_MAXIMUM,
|
|
219
|
+
value=0.9,
|
|
220
|
+
intervention_level=InterventionLevel.EMERGENCY,
|
|
221
|
+
description="Emergency alert on anomaly score >0.9",
|
|
222
|
+
),
|
|
223
|
+
ThresholdType.CONTEXT_DRIFT_MAXIMUM: ThresholdRule(
|
|
224
|
+
threshold_type=ThresholdType.CONTEXT_DRIFT_MAXIMUM,
|
|
225
|
+
value=0.7,
|
|
226
|
+
intervention_level=InterventionLevel.WARN,
|
|
227
|
+
description="Warn when context drift exceeds 0.7",
|
|
228
|
+
),
|
|
229
|
+
ThresholdType.STALE_CONTEXT_AGE_SECONDS: ThresholdRule(
|
|
230
|
+
threshold_type=ThresholdType.STALE_CONTEXT_AGE_SECONDS,
|
|
231
|
+
value=300.0,
|
|
232
|
+
intervention_level=InterventionLevel.SOFT_BLOCK,
|
|
233
|
+
description="Soft block on context older than 5 minutes",
|
|
234
|
+
),
|
|
235
|
+
ThresholdType.AMBIGUITY_SCORE_MAXIMUM: ThresholdRule(
|
|
236
|
+
threshold_type=ThresholdType.AMBIGUITY_SCORE_MAXIMUM,
|
|
237
|
+
value=0.6,
|
|
238
|
+
intervention_level=InterventionLevel.SOFT_BLOCK,
|
|
239
|
+
description="Soft block when ambiguity score exceeds 0.6",
|
|
240
|
+
),
|
|
241
|
+
ThresholdType.GRAPH_TRAVERSAL_LATENCY_MS: ThresholdRule(
|
|
242
|
+
threshold_type=ThresholdType.GRAPH_TRAVERSAL_LATENCY_MS,
|
|
243
|
+
value=100.0,
|
|
244
|
+
intervention_level=InterventionLevel.WARN,
|
|
245
|
+
description="Warn on graph traversal >100ms",
|
|
246
|
+
),
|
|
247
|
+
ThresholdType.HANDSHAKE_TIMEOUT_MS: ThresholdRule(
|
|
248
|
+
threshold_type=ThresholdType.HANDSHAKE_TIMEOUT_MS,
|
|
249
|
+
value=5000.0,
|
|
250
|
+
intervention_level=InterventionLevel.HARD_BLOCK,
|
|
251
|
+
description="Hard block on handshake timeout >5s",
|
|
252
|
+
),
|
|
253
|
+
ThresholdType.QUEUE_DEPTH_MAXIMUM: ThresholdRule(
|
|
254
|
+
threshold_type=ThresholdType.QUEUE_DEPTH_MAXIMUM,
|
|
255
|
+
value=100.0,
|
|
256
|
+
intervention_level=InterventionLevel.WARN,
|
|
257
|
+
description="Warn when action queue exceeds 100 items",
|
|
258
|
+
),
|
|
259
|
+
},
|
|
260
|
+
global_intervention_level=InterventionLevel.OBSERVE,
|
|
261
|
+
escalation_enabled=True,
|
|
262
|
+
cooldown_seconds=5.0,
|
|
263
|
+
window_size_seconds=60.0,
|
|
264
|
+
sample_rate_hz=1.0,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
# Strict threshold configuration for high-security environments
|
|
269
|
+
STRICT_THRESHOLDS = ThresholdConfig(
|
|
270
|
+
rules={
|
|
271
|
+
ThresholdType.CONSTRAINT_VIOLATION_COUNT: ThresholdRule(
|
|
272
|
+
threshold_type=ThresholdType.CONSTRAINT_VIOLATION_COUNT,
|
|
273
|
+
value=1.0,
|
|
274
|
+
intervention_level=InterventionLevel.SOFT_BLOCK,
|
|
275
|
+
description="Soft block on any constraint violation",
|
|
276
|
+
),
|
|
277
|
+
ThresholdType.TRUST_SCORE_MINIMUM: ThresholdRule(
|
|
278
|
+
threshold_type=ThresholdType.TRUST_SCORE_MINIMUM,
|
|
279
|
+
value=0.7,
|
|
280
|
+
intervention_level=InterventionLevel.HARD_BLOCK,
|
|
281
|
+
description="Hard block when trust score falls below 0.7",
|
|
282
|
+
),
|
|
283
|
+
ThresholdType.PERMISSION_ESCALATION_COUNT: ThresholdRule(
|
|
284
|
+
threshold_type=ThresholdType.PERMISSION_ESCALATION_COUNT,
|
|
285
|
+
value=1.0,
|
|
286
|
+
intervention_level=InterventionLevel.EMERGENCY,
|
|
287
|
+
description="Emergency alert on any permission escalation attempt",
|
|
288
|
+
),
|
|
289
|
+
},
|
|
290
|
+
global_intervention_level=InterventionLevel.WARN,
|
|
291
|
+
escalation_enabled=True,
|
|
292
|
+
cooldown_seconds=1.0,
|
|
293
|
+
window_size_seconds=30.0,
|
|
294
|
+
sample_rate_hz=10.0,
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
# Permissive threshold configuration for development/testing
|
|
299
|
+
PERMISSIVE_THRESHOLDS = ThresholdConfig(
|
|
300
|
+
rules={
|
|
301
|
+
ThresholdType.ANOMALY_SCORE_MAXIMUM: ThresholdRule(
|
|
302
|
+
threshold_type=ThresholdType.ANOMALY_SCORE_MAXIMUM,
|
|
303
|
+
value=0.95,
|
|
304
|
+
intervention_level=InterventionLevel.WARN,
|
|
305
|
+
description="Only warn on extreme anomaly scores",
|
|
306
|
+
),
|
|
307
|
+
},
|
|
308
|
+
global_intervention_level=InterventionLevel.OBSERVE,
|
|
309
|
+
escalation_enabled=False,
|
|
310
|
+
cooldown_seconds=30.0,
|
|
311
|
+
window_size_seconds=300.0,
|
|
312
|
+
sample_rate_hz=0.1,
|
|
313
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Super System routing components."""
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
Super System Router - Routes context to specific dimensional subgraphs.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Dict, List, Optional, Any
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from ..knowledge_graph.multidimensional_graph import MultidimensionalKnowledgeGraph
|
|
10
|
+
from ..knowledge_graph.graph_elements import Node
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Normalization mappings for common synonyms and colloquialisms
|
|
14
|
+
# Note: "east" and "west" map to -1 and -2 regions respectively as these are
|
|
15
|
+
# the most commonly used primary regions in AWS US availability zones
|
|
16
|
+
REGION_SYNONYMS = {
|
|
17
|
+
"virginia": "us-east-1",
|
|
18
|
+
"n. virginia": "us-east-1",
|
|
19
|
+
"northern virginia": "us-east-1",
|
|
20
|
+
"us-east": "us-east-1",
|
|
21
|
+
"east": "us-east-1", # Maps to primary east region
|
|
22
|
+
"oregon": "us-west-2",
|
|
23
|
+
"us-west": "us-west-2",
|
|
24
|
+
"west": "us-west-2", # Maps to primary west region (Oregon, not N. California)
|
|
25
|
+
"california": "us-west-1",
|
|
26
|
+
"ohio": "us-east-2",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
ENVIRONMENT_SYNONYMS = {
|
|
30
|
+
"production": "prod",
|
|
31
|
+
"production environment": "prod",
|
|
32
|
+
"the prod env": "prod",
|
|
33
|
+
"prod env": "prod",
|
|
34
|
+
"live": "prod",
|
|
35
|
+
"development": "dev",
|
|
36
|
+
"development environment": "dev",
|
|
37
|
+
"the dev env": "dev",
|
|
38
|
+
"dev env": "dev",
|
|
39
|
+
"staging": "stage",
|
|
40
|
+
"stage": "stage",
|
|
41
|
+
"test": "test",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class RoutingResult:
|
|
47
|
+
"""Result of routing a context through the Super System."""
|
|
48
|
+
selected_dimensions: List[str]
|
|
49
|
+
pruned_action_space: List[Node]
|
|
50
|
+
routing_metadata: Dict[str, Any]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class SuperSystemRouter:
|
|
54
|
+
"""
|
|
55
|
+
The Super System Router analyzes context and routes it to specific
|
|
56
|
+
dimensional subgraphs, effectively pruning the action space before
|
|
57
|
+
the agent acts.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, knowledge_graph: MultidimensionalKnowledgeGraph):
|
|
61
|
+
self.knowledge_graph = knowledge_graph
|
|
62
|
+
self.routing_history: List[RoutingResult] = []
|
|
63
|
+
self.normalization_enabled = True
|
|
64
|
+
self.custom_synonyms: Dict[str, Dict[str, str]] = {
|
|
65
|
+
"region": REGION_SYNONYMS.copy(),
|
|
66
|
+
"environment": ENVIRONMENT_SYNONYMS.copy(),
|
|
67
|
+
"env": ENVIRONMENT_SYNONYMS.copy(),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
def add_synonym_mapping(self, field_name: str, synonym: str, canonical: str) -> None:
|
|
71
|
+
"""Add a custom synonym mapping for normalization."""
|
|
72
|
+
if field_name not in self.custom_synonyms:
|
|
73
|
+
self.custom_synonyms[field_name] = {}
|
|
74
|
+
self.custom_synonyms[field_name][synonym.lower()] = canonical
|
|
75
|
+
|
|
76
|
+
def normalize_context(self, context: Dict[str, Any]) -> Dict[str, Any]:
|
|
77
|
+
"""
|
|
78
|
+
Normalize context values using synonym mappings.
|
|
79
|
+
This helps prevent "False Positive" rejections when users use colloquial terms.
|
|
80
|
+
"""
|
|
81
|
+
if not self.normalization_enabled:
|
|
82
|
+
return context
|
|
83
|
+
|
|
84
|
+
normalized = context.copy()
|
|
85
|
+
|
|
86
|
+
for key, value in context.items():
|
|
87
|
+
if not isinstance(value, str):
|
|
88
|
+
continue
|
|
89
|
+
|
|
90
|
+
# Check if we have synonym mappings for this field
|
|
91
|
+
if key in self.custom_synonyms:
|
|
92
|
+
value_lower = value.lower()
|
|
93
|
+
if value_lower in self.custom_synonyms[key]:
|
|
94
|
+
normalized[key] = self.custom_synonyms[key][value_lower]
|
|
95
|
+
|
|
96
|
+
return normalized
|
|
97
|
+
|
|
98
|
+
def route(self, context: Dict[str, Any]) -> RoutingResult:
|
|
99
|
+
"""
|
|
100
|
+
Route the context to appropriate dimensional subgraphs.
|
|
101
|
+
This is the core routing mechanism that implements the
|
|
102
|
+
"Forest of Trees" approach.
|
|
103
|
+
"""
|
|
104
|
+
# Step 0: Normalize context to handle synonyms
|
|
105
|
+
normalized_context = self.normalize_context(context)
|
|
106
|
+
|
|
107
|
+
# Step 1: Find relevant dimensions based on context
|
|
108
|
+
relevant_dimensions = self.knowledge_graph.find_relevant_dimensions(normalized_context)
|
|
109
|
+
|
|
110
|
+
if not relevant_dimensions:
|
|
111
|
+
# If no specific dimensions match, use all dimensions
|
|
112
|
+
relevant_dimensions = list(self.knowledge_graph.dimensions.keys())
|
|
113
|
+
|
|
114
|
+
# Step 2: Get pruned action spaces from each dimension
|
|
115
|
+
action_spaces = {}
|
|
116
|
+
for dim_name in relevant_dimensions:
|
|
117
|
+
action_space = self.knowledge_graph.get_pruned_action_space(
|
|
118
|
+
dim_name, normalized_context
|
|
119
|
+
)
|
|
120
|
+
action_spaces[dim_name] = action_space
|
|
121
|
+
|
|
122
|
+
# Step 3: Intersect action spaces to find valid actions across dimensions
|
|
123
|
+
pruned_action_space = self._intersect_action_spaces(
|
|
124
|
+
action_spaces,
|
|
125
|
+
relevant_dimensions
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Step 4: Create routing result
|
|
129
|
+
result = RoutingResult(
|
|
130
|
+
selected_dimensions=relevant_dimensions,
|
|
131
|
+
pruned_action_space=pruned_action_space,
|
|
132
|
+
routing_metadata={
|
|
133
|
+
"context": context,
|
|
134
|
+
"normalized_context": normalized_context,
|
|
135
|
+
"action_count_by_dimension": {
|
|
136
|
+
dim: len(actions) for dim, actions in action_spaces.items()
|
|
137
|
+
},
|
|
138
|
+
"final_action_count": len(pruned_action_space)
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Store in history
|
|
143
|
+
self.routing_history.append(result)
|
|
144
|
+
|
|
145
|
+
return result
|
|
146
|
+
|
|
147
|
+
def _intersect_action_spaces(
|
|
148
|
+
self,
|
|
149
|
+
action_spaces: Dict[str, List[Node]],
|
|
150
|
+
dimension_names: List[str]
|
|
151
|
+
) -> List[Node]:
|
|
152
|
+
"""
|
|
153
|
+
Intersect action spaces from multiple dimensions to find
|
|
154
|
+
actions that are valid across all dimensions.
|
|
155
|
+
"""
|
|
156
|
+
if not action_spaces or not dimension_names:
|
|
157
|
+
return []
|
|
158
|
+
|
|
159
|
+
# Start with the first dimension's action space
|
|
160
|
+
first_dim = dimension_names[0]
|
|
161
|
+
common_actions = {node.id: node for node in action_spaces.get(first_dim, [])}
|
|
162
|
+
|
|
163
|
+
# Intersect with other dimensions
|
|
164
|
+
for dim_name in dimension_names[1:]:
|
|
165
|
+
dim_actions = {node.id for node in action_spaces.get(dim_name, [])}
|
|
166
|
+
common_actions = {
|
|
167
|
+
action_id: node
|
|
168
|
+
for action_id, node in common_actions.items()
|
|
169
|
+
if action_id in dim_actions
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return list(common_actions.values())
|
|
173
|
+
|
|
174
|
+
def get_routing_statistics(self) -> Dict[str, Any]:
|
|
175
|
+
"""Get statistics about routing operations."""
|
|
176
|
+
if not self.routing_history:
|
|
177
|
+
return {
|
|
178
|
+
"total_routings": 0,
|
|
179
|
+
"avg_dimensions_per_routing": 0,
|
|
180
|
+
"avg_actions_per_routing": 0
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
total_routings = len(self.routing_history)
|
|
184
|
+
total_dimensions = sum(
|
|
185
|
+
len(result.selected_dimensions) for result in self.routing_history
|
|
186
|
+
)
|
|
187
|
+
total_actions = sum(
|
|
188
|
+
len(result.pruned_action_space) for result in self.routing_history
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
"total_routings": total_routings,
|
|
193
|
+
"avg_dimensions_per_routing": total_dimensions / total_routings if total_routings > 0 else 0,
|
|
194
|
+
"avg_actions_per_routing": total_actions / total_routings if total_routings > 0 else 0,
|
|
195
|
+
"dimension_usage": self._get_dimension_usage_stats()
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
def _get_dimension_usage_stats(self) -> Dict[str, int]:
|
|
199
|
+
"""Get statistics on how often each dimension is used."""
|
|
200
|
+
usage = {}
|
|
201
|
+
for result in self.routing_history:
|
|
202
|
+
for dim_name in result.selected_dimensions:
|
|
203
|
+
usage[dim_name] = usage.get(dim_name, 0) + 1
|
|
204
|
+
return usage
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
Visualization module for Mute Agent.
|
|
5
|
+
Provides graph debugging and execution trace visualization.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .graph_debugger import GraphDebugger, ExecutionTrace, NodeState
|
|
9
|
+
|
|
10
|
+
__all__ = ['GraphDebugger', 'ExecutionTrace', 'NodeState']
|