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,470 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
Agent Control Plane - Core Kernel Module
|
|
5
|
+
|
|
6
|
+
The Agent Kernel is the central component that mediates all interactions
|
|
7
|
+
between LLMs (raw compute) and the execution environment. It provides
|
|
8
|
+
governance, safety, and observability for autonomous agents.
|
|
9
|
+
|
|
10
|
+
Research Foundations:
|
|
11
|
+
- Deterministic enforcement approach inspired by OS kernel security models
|
|
12
|
+
- Permission model based on capability-based security (principle of least privilege)
|
|
13
|
+
- Risk assessment informed by "A Safety Framework for Real-World Agentic Systems"
|
|
14
|
+
(arXiv:2511.21990, 2024)
|
|
15
|
+
- Multi-agent patterns from "Multi-Agent Systems: A Survey" (arXiv:2308.05391, 2023)
|
|
16
|
+
- Governance practices from "Practices for Governing Agentic AI Systems" (OpenAI, 2023)
|
|
17
|
+
|
|
18
|
+
See docs/RESEARCH_FOUNDATION.md for complete references.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from typing import Any, Dict, List, Optional, Callable, TYPE_CHECKING
|
|
22
|
+
from dataclasses import dataclass, field
|
|
23
|
+
from enum import Enum
|
|
24
|
+
from datetime import datetime
|
|
25
|
+
import uuid
|
|
26
|
+
import logging
|
|
27
|
+
import asyncio
|
|
28
|
+
|
|
29
|
+
if TYPE_CHECKING:
|
|
30
|
+
from .policy_engine import PolicyEngine
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ActionType(Enum):
|
|
34
|
+
"""Types of actions an agent can request"""
|
|
35
|
+
|
|
36
|
+
CODE_EXECUTION = "code_execution"
|
|
37
|
+
FILE_READ = "file_read"
|
|
38
|
+
FILE_WRITE = "file_write"
|
|
39
|
+
API_CALL = "api_call"
|
|
40
|
+
DATABASE_QUERY = "database_query"
|
|
41
|
+
DATABASE_WRITE = "database_write"
|
|
42
|
+
WORKFLOW_TRIGGER = "workflow_trigger"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class PermissionLevel(Enum):
|
|
46
|
+
"""Permission levels for agent actions"""
|
|
47
|
+
|
|
48
|
+
NONE = 0
|
|
49
|
+
READ_ONLY = 1
|
|
50
|
+
READ_WRITE = 2
|
|
51
|
+
ADMIN = 3
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class ExecutionStatus(Enum):
|
|
55
|
+
"""Status of an execution request"""
|
|
56
|
+
|
|
57
|
+
PENDING = "pending"
|
|
58
|
+
APPROVED = "approved"
|
|
59
|
+
DENIED = "denied"
|
|
60
|
+
EXECUTING = "executing"
|
|
61
|
+
COMPLETED = "completed"
|
|
62
|
+
FAILED = "failed"
|
|
63
|
+
ROLLED_BACK = "rolled_back"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass
|
|
67
|
+
class AgentContext:
|
|
68
|
+
"""Context for an agent session"""
|
|
69
|
+
|
|
70
|
+
agent_id: str
|
|
71
|
+
session_id: str
|
|
72
|
+
created_at: datetime
|
|
73
|
+
permissions: Dict[ActionType, PermissionLevel] = field(default_factory=dict)
|
|
74
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass
|
|
78
|
+
class ExecutionRequest:
|
|
79
|
+
"""Request from an agent to execute an action"""
|
|
80
|
+
|
|
81
|
+
request_id: str
|
|
82
|
+
agent_context: AgentContext
|
|
83
|
+
action_type: ActionType
|
|
84
|
+
parameters: Dict[str, Any]
|
|
85
|
+
timestamp: datetime
|
|
86
|
+
status: ExecutionStatus = ExecutionStatus.PENDING
|
|
87
|
+
risk_score: float = 0.0
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@dataclass
|
|
91
|
+
class ExecutionResult:
|
|
92
|
+
"""Result of an execution request"""
|
|
93
|
+
|
|
94
|
+
request_id: str
|
|
95
|
+
status: ExecutionStatus
|
|
96
|
+
result: Optional[Any] = None
|
|
97
|
+
error: Optional[str] = None
|
|
98
|
+
execution_time_ms: float = 0.0
|
|
99
|
+
resources_used: Dict[str, Any] = field(default_factory=dict)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class PolicyRule:
|
|
104
|
+
"""A governance policy rule"""
|
|
105
|
+
|
|
106
|
+
rule_id: str
|
|
107
|
+
name: str
|
|
108
|
+
description: str
|
|
109
|
+
action_types: List[ActionType]
|
|
110
|
+
validator: Callable[[ExecutionRequest], bool]
|
|
111
|
+
priority: int = 0
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class AgentKernel:
|
|
115
|
+
"""
|
|
116
|
+
The Agent Kernel - Core control plane component (The Hypervisor for AI Agents)
|
|
117
|
+
|
|
118
|
+
Mediates between LLM output and actual execution, providing:
|
|
119
|
+
- Permission checking
|
|
120
|
+
- Policy enforcement
|
|
121
|
+
- Resource management
|
|
122
|
+
- Audit logging
|
|
123
|
+
- Tool interception at the API level
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
def __init__(
|
|
127
|
+
self,
|
|
128
|
+
policy_engine: Optional["PolicyEngine"] = None,
|
|
129
|
+
shadow_mode: bool = False,
|
|
130
|
+
audit_logger: Optional[Any] = None,
|
|
131
|
+
):
|
|
132
|
+
self.active_sessions: Dict[str, AgentContext] = {}
|
|
133
|
+
self.policy_rules: List[PolicyRule] = []
|
|
134
|
+
self.audit_log: List[Dict[str, Any]] = []
|
|
135
|
+
self.policy_engine = policy_engine
|
|
136
|
+
self.shadow_mode = shadow_mode
|
|
137
|
+
self.logger = logging.getLogger("AgentKernel")
|
|
138
|
+
self.audit_logger = audit_logger # FlightRecorder instance
|
|
139
|
+
|
|
140
|
+
def create_agent_session(
|
|
141
|
+
self, agent_id: str, permissions: Optional[Dict[ActionType, PermissionLevel]] = None
|
|
142
|
+
) -> AgentContext:
|
|
143
|
+
"""Create a new agent session with specified permissions"""
|
|
144
|
+
session_id = str(uuid.uuid4())
|
|
145
|
+
context = AgentContext(
|
|
146
|
+
agent_id=agent_id,
|
|
147
|
+
session_id=session_id,
|
|
148
|
+
created_at=datetime.now(),
|
|
149
|
+
permissions=permissions or self._default_permissions(),
|
|
150
|
+
)
|
|
151
|
+
self.active_sessions[session_id] = context
|
|
152
|
+
self._audit("session_created", {"agent_id": agent_id, "session_id": session_id})
|
|
153
|
+
return context
|
|
154
|
+
|
|
155
|
+
def intercept_tool_execution(
|
|
156
|
+
self,
|
|
157
|
+
agent_id: str,
|
|
158
|
+
tool_name: str,
|
|
159
|
+
tool_args: Dict[str, Any],
|
|
160
|
+
input_prompt: Optional[str] = None,
|
|
161
|
+
) -> Optional[Dict[str, Any]]:
|
|
162
|
+
"""
|
|
163
|
+
The critical choke point. No tool executes without passing this gate.
|
|
164
|
+
|
|
165
|
+
This is the "Hypervisor" pattern - intercepts tool calls BEFORE they execute.
|
|
166
|
+
Synchronous version for backward compatibility. For async support, use intercept_tool_execution_async.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
agent_id: The agent attempting the action
|
|
170
|
+
tool_name: The name of the tool being called
|
|
171
|
+
tool_args: Arguments passed to the tool
|
|
172
|
+
input_prompt: The original prompt/intent (optional, for audit trail)
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
None if execution should proceed, or a dict with blocking/shadow information
|
|
176
|
+
"""
|
|
177
|
+
# 1. TELEMETRY: Start the trace
|
|
178
|
+
request_id = None
|
|
179
|
+
if self.audit_logger:
|
|
180
|
+
request_id = self.audit_logger.start_trace(agent_id, tool_name, tool_args, input_prompt)
|
|
181
|
+
|
|
182
|
+
# 2. POLICY CHECK: The "Mute" Protocol
|
|
183
|
+
# We don't just check the tool name; we check the ARGS.
|
|
184
|
+
# e.g., allow "read_file" but block path="/etc/passwd"
|
|
185
|
+
if self.policy_engine:
|
|
186
|
+
violation = self.policy_engine.check_violation(agent_id, tool_name, tool_args)
|
|
187
|
+
|
|
188
|
+
if violation:
|
|
189
|
+
if self.audit_logger and request_id:
|
|
190
|
+
self.audit_logger.log_violation(request_id, violation)
|
|
191
|
+
|
|
192
|
+
self.logger.warning(
|
|
193
|
+
f"BLOCKED: Agent {agent_id} tried {tool_name} but violated constraint: {violation}"
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# THE MUTE AGENT:
|
|
197
|
+
# We return a system error with actionable details.
|
|
198
|
+
return {
|
|
199
|
+
"status": "blocked",
|
|
200
|
+
"error": f"RuntimeError: PolicyViolation - {violation}",
|
|
201
|
+
"policy": tool_name,
|
|
202
|
+
"agent": agent_id,
|
|
203
|
+
"mute": True,
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# 3. SHADOW MODE: The Matrix
|
|
207
|
+
# If the agent is in shadow mode, we return a "Simulated Success"
|
|
208
|
+
if self.shadow_mode:
|
|
209
|
+
if self.audit_logger and request_id:
|
|
210
|
+
self.audit_logger.log_shadow_exec(request_id, f"Simulated success for {tool_name}")
|
|
211
|
+
|
|
212
|
+
self.logger.info(f"SHADOW: Simulating {tool_name} for {agent_id}")
|
|
213
|
+
return {
|
|
214
|
+
"status": "simulated",
|
|
215
|
+
"result": "Success (Simulated)",
|
|
216
|
+
"meta": {"shadow": True},
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
# 4. EXECUTE (Allow)
|
|
220
|
+
if self.audit_logger and request_id:
|
|
221
|
+
self.audit_logger.log_success(request_id)
|
|
222
|
+
|
|
223
|
+
self.logger.info(f"ALLOWED: {tool_name} for {agent_id}")
|
|
224
|
+
return None # None means allowed (for backward compatibility)
|
|
225
|
+
|
|
226
|
+
async def intercept_tool_execution_async(
|
|
227
|
+
self,
|
|
228
|
+
agent_id: str,
|
|
229
|
+
tool_name: str,
|
|
230
|
+
tool_args: Dict[str, Any],
|
|
231
|
+
input_prompt: Optional[str] = None,
|
|
232
|
+
) -> Dict[str, Any]:
|
|
233
|
+
"""
|
|
234
|
+
Async version of intercept_tool_execution for non-blocking operation.
|
|
235
|
+
|
|
236
|
+
This is the production-ready async implementation that supports
|
|
237
|
+
concurrent agent operations.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
agent_id: The agent attempting the action
|
|
241
|
+
tool_name: The name of the tool being called
|
|
242
|
+
tool_args: Arguments passed to the tool
|
|
243
|
+
input_prompt: The original prompt/intent (optional, for audit trail)
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
Dict with:
|
|
247
|
+
- allowed: bool - Whether execution is allowed
|
|
248
|
+
- error: str - Error message (if blocked)
|
|
249
|
+
- mute: bool - True for blocked actions (NULL response)
|
|
250
|
+
- result: Any - Simulated result (for shadow mode)
|
|
251
|
+
- shadow: bool - True if shadow mode
|
|
252
|
+
"""
|
|
253
|
+
# 1. TELEMETRY: Start the trace
|
|
254
|
+
request_id = None
|
|
255
|
+
if self.audit_logger:
|
|
256
|
+
request_id = self.audit_logger.start_trace(agent_id, tool_name, tool_args, input_prompt)
|
|
257
|
+
|
|
258
|
+
# 2. POLICY CHECK: The "Mute" Protocol
|
|
259
|
+
if self.policy_engine:
|
|
260
|
+
violation = self.policy_engine.check_violation(agent_id, tool_name, tool_args)
|
|
261
|
+
|
|
262
|
+
if violation:
|
|
263
|
+
if self.audit_logger and request_id:
|
|
264
|
+
self.audit_logger.log_violation(request_id, violation)
|
|
265
|
+
|
|
266
|
+
self.logger.warning(
|
|
267
|
+
f"BLOCKED: Agent {agent_id} tried {tool_name} but violated constraint: {violation}"
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
"allowed": False,
|
|
272
|
+
"error": f"RuntimeError: PolicyViolation - {violation}",
|
|
273
|
+
"policy": tool_name,
|
|
274
|
+
"agent": agent_id,
|
|
275
|
+
"mute": True,
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
# 3. SHADOW MODE: The Matrix
|
|
279
|
+
if self.shadow_mode:
|
|
280
|
+
if self.audit_logger and request_id:
|
|
281
|
+
self.audit_logger.log_shadow_exec(request_id, f"Simulated success for {tool_name}")
|
|
282
|
+
|
|
283
|
+
self.logger.info(f"SHADOW: Simulating {tool_name} for {agent_id}")
|
|
284
|
+
return {
|
|
285
|
+
"allowed": False, # Technically false because we didn't run it
|
|
286
|
+
"result": "Success (Simulated)",
|
|
287
|
+
"shadow": True,
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
# 4. EXECUTE
|
|
291
|
+
if self.audit_logger and request_id:
|
|
292
|
+
self.audit_logger.log_success(request_id)
|
|
293
|
+
|
|
294
|
+
self.logger.info(f"ALLOWED: {tool_name} for {agent_id}")
|
|
295
|
+
return {"allowed": True}
|
|
296
|
+
|
|
297
|
+
def submit_request(
|
|
298
|
+
self, agent_context: AgentContext, action_type: ActionType, parameters: Dict[str, Any]
|
|
299
|
+
) -> ExecutionRequest:
|
|
300
|
+
"""Submit an execution request for validation and execution"""
|
|
301
|
+
request = ExecutionRequest(
|
|
302
|
+
request_id=str(uuid.uuid4()),
|
|
303
|
+
agent_context=agent_context,
|
|
304
|
+
action_type=action_type,
|
|
305
|
+
parameters=parameters,
|
|
306
|
+
timestamp=datetime.now(),
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
# Check permissions
|
|
310
|
+
if not self._check_permission(request):
|
|
311
|
+
request.status = ExecutionStatus.DENIED
|
|
312
|
+
self._audit(
|
|
313
|
+
"request_denied",
|
|
314
|
+
{"request_id": request.request_id, "reason": "insufficient_permissions"},
|
|
315
|
+
)
|
|
316
|
+
return request
|
|
317
|
+
|
|
318
|
+
# Validate against policies
|
|
319
|
+
if not self._validate_policies(request):
|
|
320
|
+
request.status = ExecutionStatus.DENIED
|
|
321
|
+
self._audit(
|
|
322
|
+
"request_denied", {"request_id": request.request_id, "reason": "policy_violation"}
|
|
323
|
+
)
|
|
324
|
+
return request
|
|
325
|
+
|
|
326
|
+
# Assess risk
|
|
327
|
+
request.risk_score = self._assess_risk(request)
|
|
328
|
+
|
|
329
|
+
# Approve for execution
|
|
330
|
+
request.status = ExecutionStatus.APPROVED
|
|
331
|
+
self._audit(
|
|
332
|
+
"request_approved",
|
|
333
|
+
{
|
|
334
|
+
"request_id": request.request_id,
|
|
335
|
+
"action_type": action_type.value,
|
|
336
|
+
"risk_score": request.risk_score,
|
|
337
|
+
},
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
return request
|
|
341
|
+
|
|
342
|
+
def execute(self, request: ExecutionRequest) -> ExecutionResult:
|
|
343
|
+
"""Execute an approved request"""
|
|
344
|
+
if request.status != ExecutionStatus.APPROVED:
|
|
345
|
+
return ExecutionResult(
|
|
346
|
+
request_id=request.request_id,
|
|
347
|
+
status=ExecutionStatus.FAILED,
|
|
348
|
+
error="Request not approved for execution",
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
request.status = ExecutionStatus.EXECUTING
|
|
352
|
+
start_time = datetime.now()
|
|
353
|
+
|
|
354
|
+
try:
|
|
355
|
+
# This is where actual execution would happen
|
|
356
|
+
# In a real implementation, this would dispatch to appropriate executors
|
|
357
|
+
result = self._dispatch_execution(request)
|
|
358
|
+
|
|
359
|
+
execution_time = (datetime.now() - start_time).total_seconds() * 1000
|
|
360
|
+
|
|
361
|
+
execution_result = ExecutionResult(
|
|
362
|
+
request_id=request.request_id,
|
|
363
|
+
status=ExecutionStatus.COMPLETED,
|
|
364
|
+
result=result,
|
|
365
|
+
execution_time_ms=execution_time,
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
self._audit(
|
|
369
|
+
"execution_completed",
|
|
370
|
+
{"request_id": request.request_id, "execution_time_ms": execution_time},
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
return execution_result
|
|
374
|
+
|
|
375
|
+
except Exception as e:
|
|
376
|
+
execution_time = (datetime.now() - start_time).total_seconds() * 1000
|
|
377
|
+
|
|
378
|
+
execution_result = ExecutionResult(
|
|
379
|
+
request_id=request.request_id,
|
|
380
|
+
status=ExecutionStatus.FAILED,
|
|
381
|
+
error=str(e),
|
|
382
|
+
execution_time_ms=execution_time,
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
self._audit("execution_failed", {"request_id": request.request_id, "error": str(e)})
|
|
386
|
+
|
|
387
|
+
return execution_result
|
|
388
|
+
|
|
389
|
+
def add_policy_rule(self, rule: PolicyRule):
|
|
390
|
+
"""Add a policy rule to the kernel"""
|
|
391
|
+
self.policy_rules.append(rule)
|
|
392
|
+
self.policy_rules.sort(key=lambda r: r.priority, reverse=True)
|
|
393
|
+
self._audit("policy_added", {"rule_id": rule.rule_id, "name": rule.name})
|
|
394
|
+
|
|
395
|
+
def get_audit_log(self) -> List[Dict[str, Any]]:
|
|
396
|
+
"""Retrieve the audit log"""
|
|
397
|
+
return self.audit_log.copy()
|
|
398
|
+
|
|
399
|
+
def _check_permission(self, request: ExecutionRequest) -> bool:
|
|
400
|
+
"""Check if agent has permission for the requested action"""
|
|
401
|
+
required_level = self._get_required_permission_level(request.action_type)
|
|
402
|
+
agent_level = request.agent_context.permissions.get(
|
|
403
|
+
request.action_type, PermissionLevel.NONE
|
|
404
|
+
)
|
|
405
|
+
return agent_level.value >= required_level.value
|
|
406
|
+
|
|
407
|
+
def _validate_policies(self, request: ExecutionRequest) -> bool:
|
|
408
|
+
"""Validate request against all applicable policy rules"""
|
|
409
|
+
for rule in self.policy_rules:
|
|
410
|
+
if request.action_type in rule.action_types:
|
|
411
|
+
if not rule.validator(request):
|
|
412
|
+
return False
|
|
413
|
+
return True
|
|
414
|
+
|
|
415
|
+
def _assess_risk(self, request: ExecutionRequest) -> float:
|
|
416
|
+
"""Assess the risk level of a request (0.0 = no risk, 1.0 = maximum risk)"""
|
|
417
|
+
# Simple risk assessment based on action type
|
|
418
|
+
risk_weights = {
|
|
419
|
+
ActionType.FILE_READ: 0.1,
|
|
420
|
+
ActionType.API_CALL: 0.3,
|
|
421
|
+
ActionType.CODE_EXECUTION: 0.7,
|
|
422
|
+
ActionType.FILE_WRITE: 0.5,
|
|
423
|
+
ActionType.DATABASE_QUERY: 0.4,
|
|
424
|
+
ActionType.DATABASE_WRITE: 0.6,
|
|
425
|
+
ActionType.WORKFLOW_TRIGGER: 0.5,
|
|
426
|
+
}
|
|
427
|
+
return risk_weights.get(request.action_type, 0.5)
|
|
428
|
+
|
|
429
|
+
def _dispatch_execution(self, request: ExecutionRequest) -> Any:
|
|
430
|
+
"""
|
|
431
|
+
Dispatch execution to appropriate handler
|
|
432
|
+
|
|
433
|
+
Note: This returns simulated execution results for demonstration purposes.
|
|
434
|
+
In production, this should route to actual ExecutionEngine handlers.
|
|
435
|
+
The Control Plane's execute_action() method uses the ExecutionEngine
|
|
436
|
+
directly for actual execution.
|
|
437
|
+
"""
|
|
438
|
+
return {
|
|
439
|
+
"status": "simulated_execution",
|
|
440
|
+
"action": request.action_type.value,
|
|
441
|
+
"note": "Simulated result - use Control Plane for actual execution",
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
def _get_required_permission_level(self, action_type: ActionType) -> PermissionLevel:
|
|
445
|
+
"""Get the minimum permission level required for an action type"""
|
|
446
|
+
if action_type in [ActionType.FILE_READ, ActionType.DATABASE_QUERY]:
|
|
447
|
+
return PermissionLevel.READ_ONLY
|
|
448
|
+
elif action_type in [
|
|
449
|
+
ActionType.FILE_WRITE,
|
|
450
|
+
ActionType.DATABASE_WRITE,
|
|
451
|
+
ActionType.CODE_EXECUTION,
|
|
452
|
+
ActionType.API_CALL,
|
|
453
|
+
ActionType.WORKFLOW_TRIGGER,
|
|
454
|
+
]:
|
|
455
|
+
return PermissionLevel.READ_WRITE
|
|
456
|
+
return PermissionLevel.ADMIN
|
|
457
|
+
|
|
458
|
+
def _default_permissions(self) -> Dict[ActionType, PermissionLevel]:
|
|
459
|
+
"""Get default (minimal) permissions for an agent"""
|
|
460
|
+
return {
|
|
461
|
+
ActionType.FILE_READ: PermissionLevel.READ_ONLY,
|
|
462
|
+
ActionType.API_CALL: PermissionLevel.NONE,
|
|
463
|
+
ActionType.CODE_EXECUTION: PermissionLevel.NONE,
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
def _audit(self, event_type: str, details: Dict[str, Any]):
|
|
467
|
+
"""Log an audit event"""
|
|
468
|
+
self.audit_log.append(
|
|
469
|
+
{"timestamp": datetime.now().isoformat(), "event_type": event_type, "details": details}
|
|
470
|
+
)
|