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.
Files changed (337) hide show
  1. agent_control_plane/__init__.py +662 -0
  2. agent_control_plane/a2a_adapter.py +543 -0
  3. agent_control_plane/adapter.py +417 -0
  4. agent_control_plane/agent_hibernation.py +394 -0
  5. agent_control_plane/agent_kernel.py +470 -0
  6. agent_control_plane/compliance.py +720 -0
  7. agent_control_plane/constraint_graphs.py +478 -0
  8. agent_control_plane/control_plane.py +854 -0
  9. agent_control_plane/example_executors.py +195 -0
  10. agent_control_plane/execution_engine.py +231 -0
  11. agent_control_plane/flight_recorder.py +846 -0
  12. agent_control_plane/governance_layer.py +435 -0
  13. agent_control_plane/hf_utils.py +563 -0
  14. agent_control_plane/interfaces/__init__.py +55 -0
  15. agent_control_plane/interfaces/kernel_interface.py +361 -0
  16. agent_control_plane/interfaces/plugin_interface.py +497 -0
  17. agent_control_plane/interfaces/protocol_interfaces.py +387 -0
  18. agent_control_plane/kernel_space.py +1009 -0
  19. agent_control_plane/langchain_adapter.py +424 -0
  20. agent_control_plane/lifecycle.py +3113 -0
  21. agent_control_plane/mcp_adapter.py +653 -0
  22. agent_control_plane/ml_safety.py +563 -0
  23. agent_control_plane/multimodal.py +727 -0
  24. agent_control_plane/mute_agent.py +422 -0
  25. agent_control_plane/observability.py +787 -0
  26. agent_control_plane/orchestrator.py +482 -0
  27. agent_control_plane/plugin_registry.py +750 -0
  28. agent_control_plane/policy_engine.py +954 -0
  29. agent_control_plane/process_isolation.py +777 -0
  30. agent_control_plane/shadow_mode.py +310 -0
  31. agent_control_plane/signals.py +493 -0
  32. agent_control_plane/supervisor_agents.py +430 -0
  33. agent_control_plane/time_travel_debugger.py +557 -0
  34. agent_control_plane/tool_registry.py +452 -0
  35. agent_control_plane/vfs.py +697 -0
  36. agent_kernel/__init__.py +69 -0
  37. agent_kernel/analyzer.py +435 -0
  38. agent_kernel/auditor.py +36 -0
  39. agent_kernel/completeness_auditor.py +237 -0
  40. agent_kernel/detector.py +203 -0
  41. agent_kernel/kernel.py +744 -0
  42. agent_kernel/memory_manager.py +85 -0
  43. agent_kernel/models.py +374 -0
  44. agent_kernel/nudge_mechanism.py +263 -0
  45. agent_kernel/outcome_analyzer.py +338 -0
  46. agent_kernel/patcher.py +582 -0
  47. agent_kernel/semantic_analyzer.py +316 -0
  48. agent_kernel/semantic_purge.py +349 -0
  49. agent_kernel/simulator.py +449 -0
  50. agent_kernel/teacher.py +85 -0
  51. agent_kernel/triage.py +152 -0
  52. agent_os/__init__.py +409 -0
  53. agent_os/_adversarial_impl.py +200 -0
  54. agent_os/_circuit_breaker_impl.py +232 -0
  55. agent_os/_mcp_metrics.py +193 -0
  56. agent_os/adversarial.py +20 -0
  57. agent_os/agents_compat.py +490 -0
  58. agent_os/audit_logger.py +135 -0
  59. agent_os/base_agent.py +651 -0
  60. agent_os/circuit_breaker.py +34 -0
  61. agent_os/cli/__init__.py +659 -0
  62. agent_os/cli/cmd_audit.py +128 -0
  63. agent_os/cli/cmd_init.py +152 -0
  64. agent_os/cli/cmd_policy.py +41 -0
  65. agent_os/cli/cmd_policy_gen.py +180 -0
  66. agent_os/cli/cmd_validate.py +258 -0
  67. agent_os/cli/mcp_scan.py +265 -0
  68. agent_os/cli/output.py +192 -0
  69. agent_os/cli/policy_checker.py +330 -0
  70. agent_os/compat.py +74 -0
  71. agent_os/constraint_graph.py +234 -0
  72. agent_os/content_governance.py +140 -0
  73. agent_os/context_budget.py +305 -0
  74. agent_os/credential_redactor.py +224 -0
  75. agent_os/diff_policy.py +89 -0
  76. agent_os/egress_policy.py +159 -0
  77. agent_os/escalation.py +276 -0
  78. agent_os/event_bus.py +124 -0
  79. agent_os/exceptions.py +180 -0
  80. agent_os/execution_context_policy.py +141 -0
  81. agent_os/github_enterprise.py +96 -0
  82. agent_os/health.py +20 -0
  83. agent_os/integrations/__init__.py +279 -0
  84. agent_os/integrations/a2a_adapter.py +279 -0
  85. agent_os/integrations/agent_lightning/__init__.py +30 -0
  86. agent_os/integrations/anthropic_adapter.py +420 -0
  87. agent_os/integrations/autogen_adapter.py +620 -0
  88. agent_os/integrations/base.py +1137 -0
  89. agent_os/integrations/compat.py +229 -0
  90. agent_os/integrations/config.py +98 -0
  91. agent_os/integrations/conversation_guardian.py +957 -0
  92. agent_os/integrations/crewai_adapter.py +467 -0
  93. agent_os/integrations/drift_detector.py +425 -0
  94. agent_os/integrations/dry_run.py +124 -0
  95. agent_os/integrations/escalation.py +582 -0
  96. agent_os/integrations/gemini_adapter.py +364 -0
  97. agent_os/integrations/google_adk_adapter.py +633 -0
  98. agent_os/integrations/guardrails_adapter.py +394 -0
  99. agent_os/integrations/health.py +197 -0
  100. agent_os/integrations/langchain_adapter.py +654 -0
  101. agent_os/integrations/llamafirewall.py +343 -0
  102. agent_os/integrations/llamaindex_adapter.py +188 -0
  103. agent_os/integrations/logging.py +191 -0
  104. agent_os/integrations/maf_adapter.py +631 -0
  105. agent_os/integrations/mistral_adapter.py +365 -0
  106. agent_os/integrations/openai_adapter.py +816 -0
  107. agent_os/integrations/openai_agents_sdk.py +406 -0
  108. agent_os/integrations/policy_compose.py +171 -0
  109. agent_os/integrations/profiling.py +144 -0
  110. agent_os/integrations/pydantic_ai_adapter.py +420 -0
  111. agent_os/integrations/rate_limiter.py +130 -0
  112. agent_os/integrations/rbac.py +143 -0
  113. agent_os/integrations/registry.py +113 -0
  114. agent_os/integrations/scope_guard.py +303 -0
  115. agent_os/integrations/semantic_kernel_adapter.py +769 -0
  116. agent_os/integrations/smolagents_adapter.py +629 -0
  117. agent_os/integrations/templates.py +178 -0
  118. agent_os/integrations/token_budget.py +134 -0
  119. agent_os/integrations/tool_aliases.py +190 -0
  120. agent_os/integrations/webhooks.py +177 -0
  121. agent_os/lite.py +208 -0
  122. agent_os/mcp_gateway.py +385 -0
  123. agent_os/mcp_message_signer.py +273 -0
  124. agent_os/mcp_protocols.py +161 -0
  125. agent_os/mcp_response_scanner.py +232 -0
  126. agent_os/mcp_security.py +924 -0
  127. agent_os/mcp_session_auth.py +231 -0
  128. agent_os/mcp_sliding_rate_limiter.py +184 -0
  129. agent_os/memory_guard.py +409 -0
  130. agent_os/metrics.py +134 -0
  131. agent_os/mute.py +428 -0
  132. agent_os/mute_agent.py +209 -0
  133. agent_os/policies/__init__.py +77 -0
  134. agent_os/policies/async_evaluator.py +275 -0
  135. agent_os/policies/backends.py +670 -0
  136. agent_os/policies/bridge.py +169 -0
  137. agent_os/policies/budget.py +85 -0
  138. agent_os/policies/cli.py +294 -0
  139. agent_os/policies/conflict_resolution.py +270 -0
  140. agent_os/policies/data_classification.py +252 -0
  141. agent_os/policies/evaluator.py +239 -0
  142. agent_os/policies/policy_schema.json +228 -0
  143. agent_os/policies/rate_limiting.py +145 -0
  144. agent_os/policies/schema.py +115 -0
  145. agent_os/policies/shared.py +331 -0
  146. agent_os/prompt_injection.py +694 -0
  147. agent_os/providers.py +182 -0
  148. agent_os/py.typed +0 -0
  149. agent_os/retry.py +81 -0
  150. agent_os/reversibility.py +251 -0
  151. agent_os/sandbox.py +432 -0
  152. agent_os/sandbox_provider.py +140 -0
  153. agent_os/secure_codegen.py +525 -0
  154. agent_os/security_skills.py +538 -0
  155. agent_os/semantic_policy.py +422 -0
  156. agent_os/server/__init__.py +15 -0
  157. agent_os/server/__main__.py +25 -0
  158. agent_os/server/app.py +277 -0
  159. agent_os/server/models.py +104 -0
  160. agent_os/shift_left_metrics.py +130 -0
  161. agent_os/stateless.py +742 -0
  162. agent_os/supervisor.py +148 -0
  163. agent_os/task_outcome.py +148 -0
  164. agent_os/transparency.py +181 -0
  165. agent_os/trust_root.py +128 -0
  166. agent_os_kernel-3.1.0.dist-info/METADATA +1269 -0
  167. agent_os_kernel-3.1.0.dist-info/RECORD +337 -0
  168. agent_os_kernel-3.1.0.dist-info/WHEEL +4 -0
  169. agent_os_kernel-3.1.0.dist-info/entry_points.txt +2 -0
  170. agent_os_kernel-3.1.0.dist-info/licenses/LICENSE +21 -0
  171. agent_os_observability/__init__.py +27 -0
  172. agent_os_observability/dashboards.py +898 -0
  173. agent_os_observability/metrics.py +398 -0
  174. agent_os_observability/server.py +223 -0
  175. agent_os_observability/tracer.py +232 -0
  176. agent_primitives/__init__.py +24 -0
  177. agent_primitives/failures.py +84 -0
  178. agent_primitives/py.typed +0 -0
  179. amb_core/__init__.py +177 -0
  180. amb_core/adapters/__init__.py +57 -0
  181. amb_core/adapters/aws_sqs_broker.py +376 -0
  182. amb_core/adapters/azure_servicebus_broker.py +340 -0
  183. amb_core/adapters/kafka_broker.py +260 -0
  184. amb_core/adapters/nats_broker.py +285 -0
  185. amb_core/adapters/rabbitmq_broker.py +235 -0
  186. amb_core/adapters/redis_broker.py +262 -0
  187. amb_core/broker.py +145 -0
  188. amb_core/bus.py +481 -0
  189. amb_core/cloudevents.py +509 -0
  190. amb_core/dlq.py +345 -0
  191. amb_core/hf_utils.py +536 -0
  192. amb_core/memory_broker.py +410 -0
  193. amb_core/models.py +141 -0
  194. amb_core/persistence.py +529 -0
  195. amb_core/schema.py +294 -0
  196. amb_core/tracing.py +358 -0
  197. atr/__init__.py +640 -0
  198. atr/access.py +348 -0
  199. atr/composition.py +645 -0
  200. atr/decorator.py +357 -0
  201. atr/executor.py +384 -0
  202. atr/health.py +557 -0
  203. atr/hf_utils.py +449 -0
  204. atr/injection.py +422 -0
  205. atr/metrics.py +440 -0
  206. atr/policies.py +403 -0
  207. atr/py.typed +2 -0
  208. atr/registry.py +452 -0
  209. atr/schema.py +480 -0
  210. atr/tools/safe/__init__.py +75 -0
  211. atr/tools/safe/calculator.py +467 -0
  212. atr/tools/safe/datetime_tool.py +443 -0
  213. atr/tools/safe/file_reader.py +402 -0
  214. atr/tools/safe/http_client.py +316 -0
  215. atr/tools/safe/json_parser.py +374 -0
  216. atr/tools/safe/text_tool.py +537 -0
  217. atr/tools/safe/toolkit.py +175 -0
  218. caas/__init__.py +162 -0
  219. caas/api/__init__.py +7 -0
  220. caas/api/server.py +1328 -0
  221. caas/caching.py +834 -0
  222. caas/cli.py +210 -0
  223. caas/conversation.py +223 -0
  224. caas/decay.py +72 -0
  225. caas/detection/__init__.py +9 -0
  226. caas/detection/detector.py +238 -0
  227. caas/enrichment.py +130 -0
  228. caas/gateway/__init__.py +27 -0
  229. caas/gateway/trust_gateway.py +474 -0
  230. caas/hf_utils.py +479 -0
  231. caas/ingestion/__init__.py +23 -0
  232. caas/ingestion/processors.py +253 -0
  233. caas/ingestion/structure_parser.py +188 -0
  234. caas/models.py +356 -0
  235. caas/pragmatic_truth.py +444 -0
  236. caas/routing/__init__.py +10 -0
  237. caas/routing/heuristic_router.py +58 -0
  238. caas/storage/__init__.py +9 -0
  239. caas/storage/store.py +389 -0
  240. caas/triad.py +213 -0
  241. caas/tuning/__init__.py +9 -0
  242. caas/tuning/tuner.py +329 -0
  243. caas/vfs/__init__.py +14 -0
  244. caas/vfs/filesystem.py +452 -0
  245. cmvk/__init__.py +218 -0
  246. cmvk/audit.py +402 -0
  247. cmvk/benchmarks.py +478 -0
  248. cmvk/constitutional.py +904 -0
  249. cmvk/hf_utils.py +301 -0
  250. cmvk/metrics.py +473 -0
  251. cmvk/profiles.py +300 -0
  252. cmvk/py.typed +0 -0
  253. cmvk/types.py +12 -0
  254. cmvk/verification.py +956 -0
  255. emk/__init__.py +89 -0
  256. emk/causal.py +352 -0
  257. emk/hf_utils.py +421 -0
  258. emk/indexer.py +83 -0
  259. emk/py.typed +0 -0
  260. emk/schema.py +204 -0
  261. emk/sleep_cycle.py +347 -0
  262. emk/store.py +281 -0
  263. iatp/__init__.py +166 -0
  264. iatp/attestation.py +461 -0
  265. iatp/cli.py +317 -0
  266. iatp/hf_utils.py +472 -0
  267. iatp/ipc_pipes.py +580 -0
  268. iatp/main.py +412 -0
  269. iatp/models/__init__.py +447 -0
  270. iatp/policy_engine.py +337 -0
  271. iatp/py.typed +2 -0
  272. iatp/recovery.py +321 -0
  273. iatp/security/__init__.py +270 -0
  274. iatp/sidecar/__init__.py +519 -0
  275. iatp/telemetry/__init__.py +164 -0
  276. iatp/tests/__init__.py +1 -0
  277. iatp/tests/test_attestation.py +370 -0
  278. iatp/tests/test_cli.py +131 -0
  279. iatp/tests/test_ed25519_attestation.py +211 -0
  280. iatp/tests/test_models.py +130 -0
  281. iatp/tests/test_policy_engine.py +347 -0
  282. iatp/tests/test_recovery.py +281 -0
  283. iatp/tests/test_security.py +222 -0
  284. iatp/tests/test_sidecar.py +167 -0
  285. iatp/tests/test_telemetry.py +175 -0
  286. mcp_kernel_server/__init__.py +28 -0
  287. mcp_kernel_server/cli.py +274 -0
  288. mcp_kernel_server/resources.py +217 -0
  289. mcp_kernel_server/server.py +564 -0
  290. mcp_kernel_server/tools.py +1174 -0
  291. mute_agent/__init__.py +68 -0
  292. mute_agent/core/__init__.py +1 -0
  293. mute_agent/core/execution_agent.py +166 -0
  294. mute_agent/core/handshake_protocol.py +201 -0
  295. mute_agent/core/reasoning_agent.py +238 -0
  296. mute_agent/knowledge_graph/__init__.py +1 -0
  297. mute_agent/knowledge_graph/graph_elements.py +65 -0
  298. mute_agent/knowledge_graph/multidimensional_graph.py +170 -0
  299. mute_agent/knowledge_graph/subgraph.py +224 -0
  300. mute_agent/listener/__init__.py +43 -0
  301. mute_agent/listener/adapters/__init__.py +31 -0
  302. mute_agent/listener/adapters/base_adapter.py +189 -0
  303. mute_agent/listener/adapters/caas_adapter.py +344 -0
  304. mute_agent/listener/adapters/control_plane_adapter.py +436 -0
  305. mute_agent/listener/adapters/iatp_adapter.py +332 -0
  306. mute_agent/listener/adapters/scak_adapter.py +251 -0
  307. mute_agent/listener/listener.py +610 -0
  308. mute_agent/listener/state_observer.py +436 -0
  309. mute_agent/listener/threshold_config.py +313 -0
  310. mute_agent/super_system/__init__.py +1 -0
  311. mute_agent/super_system/router.py +204 -0
  312. mute_agent/visualization/__init__.py +10 -0
  313. mute_agent/visualization/graph_debugger.py +502 -0
  314. nexus/README.md +60 -0
  315. nexus/__init__.py +51 -0
  316. nexus/arbiter.py +359 -0
  317. nexus/client.py +466 -0
  318. nexus/dmz.py +444 -0
  319. nexus/escrow.py +430 -0
  320. nexus/exceptions.py +286 -0
  321. nexus/pyproject.toml +36 -0
  322. nexus/registry.py +393 -0
  323. nexus/reputation.py +425 -0
  324. nexus/schemas/__init__.py +51 -0
  325. nexus/schemas/compliance.py +276 -0
  326. nexus/schemas/escrow.py +251 -0
  327. nexus/schemas/manifest.py +225 -0
  328. nexus/schemas/receipt.py +208 -0
  329. nexus/tests/__init__.py +0 -0
  330. nexus/tests/conftest.py +146 -0
  331. nexus/tests/test_arbiter.py +192 -0
  332. nexus/tests/test_dmz.py +194 -0
  333. nexus/tests/test_escrow.py +276 -0
  334. nexus/tests/test_exceptions.py +225 -0
  335. nexus/tests/test_registry.py +232 -0
  336. nexus/tests/test_reputation.py +328 -0
  337. nexus/tests/test_schemas.py +295 -0
agent_kernel/kernel.py ADDED
@@ -0,0 +1,744 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ """
5
+ Self-Correcting Agent Kernel - Main orchestrator.
6
+
7
+ Implements the Dual-Loop Architecture:
8
+ - Loop 1 (Runtime): Constraint Engine (Safety)
9
+ - Loop 2 (Offline): Alignment Engine (Quality & Efficiency)
10
+ """
11
+
12
+ import logging
13
+ from typing import Optional, Dict, Any, List
14
+ from datetime import datetime
15
+
16
+ from .models import (
17
+ AgentFailure, FailureAnalysis, SimulationResult, CorrectionPatch, AgentState,
18
+ AgentOutcome, CompletenessAudit, ClassifiedPatch,
19
+ ToolExecutionTelemetry, NudgeResult
20
+ )
21
+ from .detector import FailureDetector
22
+ from .analyzer import FailureAnalyzer
23
+ from .simulator import PathSimulator
24
+ from .patcher import AgentPatcher
25
+ from .outcome_analyzer import OutcomeAnalyzer
26
+ from .completeness_auditor import CompletenessAuditor
27
+ from .semantic_purge import SemanticPurge
28
+ from .triage import FailureTriage, FixStrategy
29
+ from .nudge_mechanism import NudgeMechanism
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+
34
+ class SelfCorrectingAgentKernel:
35
+ """
36
+ Main kernel implementing the Dual-Loop Architecture.
37
+
38
+ LOOP 1 (Runtime): The Constraint Engine filters for Safety
39
+ LOOP 2 (Offline): The Alignment Engine filters for Quality & Efficiency:
40
+ - Completeness Auditor: Detects "laziness" (give-up signals)
41
+ - Semantic Purge: Manages patch lifecycle (scale by subtraction)
42
+
43
+ When an agent fails OR gives up:
44
+ 1. Detects and classifies the outcome
45
+ 2. Analyzes for safety (Loop 1) and competence (Loop 2)
46
+ 3. Simulates alternative paths
47
+ 4. Patches the agent with classified, lifecycle-managed fixes
48
+ """
49
+
50
+ def __init__(self, config: Optional[Dict[str, Any]] = None):
51
+ """
52
+ Initialize the self-correcting agent kernel with Dual-Loop Architecture.
53
+
54
+ Args:
55
+ config: Optional configuration dictionary
56
+ """
57
+ self.config = config or {}
58
+
59
+ # LOOP 1: Runtime Safety Components
60
+ self.detector = FailureDetector()
61
+ self.analyzer = FailureAnalyzer()
62
+ self.simulator = PathSimulator()
63
+ self.patcher = AgentPatcher()
64
+
65
+ # LOOP 2: Offline Alignment Components
66
+ use_semantic_analysis = self.config.get("use_semantic_analysis", True)
67
+ self.outcome_analyzer = OutcomeAnalyzer(use_semantic_analysis=use_semantic_analysis)
68
+ self.completeness_auditor = CompletenessAuditor(
69
+ teacher_model=self.config.get("teacher_model", "o1-preview")
70
+ )
71
+ self.semantic_purge = SemanticPurge()
72
+ self.nudge_mechanism = NudgeMechanism()
73
+
74
+ # Triage Engine: Decides sync (JIT) vs async (batch) correction
75
+ self.triage = FailureTriage(config=self.config.get("triage_config", {}))
76
+
77
+ # Background queue for async failures (placeholder for production implementation)
78
+ self.async_failure_queue = []
79
+
80
+ # Model version tracking for semantic purge
81
+ self.current_model_version = self.config.get("model_version", "gpt-4o")
82
+
83
+ # Configure logging
84
+ self._setup_logging()
85
+
86
+ logger.info("=" * 80)
87
+ logger.info("Self-Correcting Agent Kernel initialized (Dual-Loop Architecture)")
88
+ logger.info(f" Loop 1 (Runtime): Constraint Engine (Safety)")
89
+ logger.info(f" Loop 2 (Offline): Alignment Engine (Quality & Efficiency)")
90
+ logger.info(f" - Completeness Auditor: {self.completeness_auditor.teacher_model}")
91
+ logger.info(f" - Semantic Purge: Active")
92
+ logger.info(f" - Failure Triage: Active (Sync/Async routing)")
93
+ logger.info(f" - Semantic Analysis: {use_semantic_analysis}")
94
+ logger.info(f" - Nudge Mechanism: Active")
95
+ logger.info(f" Model Version: {self.current_model_version}")
96
+ logger.info("=" * 80)
97
+
98
+ def _setup_logging(self):
99
+ """Setup logging configuration."""
100
+ log_level = self.config.get("log_level", "INFO")
101
+ logging.basicConfig(
102
+ level=getattr(logging, log_level),
103
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
104
+ )
105
+
106
+ def handle_failure(
107
+ self,
108
+ agent_id: str,
109
+ error_message: str,
110
+ context: Optional[Dict[str, Any]] = None,
111
+ stack_trace: Optional[str] = None,
112
+ auto_patch: bool = True,
113
+ user_prompt: Optional[str] = None,
114
+ chain_of_thought: Optional[List[str]] = None,
115
+ failed_action: Optional[Dict[str, Any]] = None,
116
+ user_metadata: Optional[Dict[str, Any]] = None
117
+ ) -> Dict[str, Any]:
118
+ """
119
+ Handle an agent failure through the full self-correction pipeline.
120
+
121
+ Enhanced to support full trace capture, cognitive diagnosis, and triage routing.
122
+
123
+ This is the main entry point when an agent fails in production.
124
+
125
+ Args:
126
+ agent_id: Identifier of the failed agent
127
+ error_message: Error message from the failure
128
+ context: Additional context about the failure
129
+ stack_trace: Optional stack trace
130
+ auto_patch: Whether to automatically apply the patch (default: True)
131
+ user_prompt: Original user prompt (for full trace)
132
+ chain_of_thought: Agent's reasoning steps (for cognitive analysis)
133
+ failed_action: The specific action that failed
134
+ user_metadata: User metadata (e.g., VIP status) for triage decisions
135
+
136
+ Returns:
137
+ Dictionary containing the results of the self-correction process
138
+ """
139
+ logger.info(f"=" * 80)
140
+ logger.info(f"AGENT FAILURE DETECTED - Starting enhanced self-correction process")
141
+ logger.info(f"Agent ID: {agent_id}")
142
+ logger.info(f"Error: {error_message}")
143
+ logger.info(f"=" * 80)
144
+
145
+ # Step 0: Triage - Decide sync (JIT) or async (batch) correction strategy
146
+ if user_prompt:
147
+ tool_name = context.get("action") if context else None
148
+
149
+ # Prepare enhanced context for triage including failed_action and chain_of_thought
150
+ triage_context = dict(context) if context else {}
151
+ if failed_action:
152
+ triage_context["failed_action"] = failed_action
153
+ if chain_of_thought:
154
+ triage_context["chain_of_thought"] = chain_of_thought
155
+
156
+ strategy = self.triage.decide_strategy(
157
+ prompt=user_prompt,
158
+ tool_name=tool_name,
159
+ user_metadata=user_metadata,
160
+ context=triage_context
161
+ )
162
+
163
+ logger.info(f"[TRIAGE] Decision: {strategy.value}")
164
+
165
+ if strategy == FixStrategy.ASYNC_BATCH:
166
+ logger.info(">> Non-Critical Failure. Queuing for async optimization.")
167
+ logger.info(">> Returning error to user immediately (low latency).")
168
+
169
+ # Add to async queue for later processing
170
+ self.async_failure_queue.append({
171
+ "agent_id": agent_id,
172
+ "error_message": error_message,
173
+ "context": context,
174
+ "stack_trace": stack_trace,
175
+ "user_prompt": user_prompt,
176
+ "chain_of_thought": chain_of_thought,
177
+ "failed_action": failed_action,
178
+ "timestamp": datetime.utcnow()
179
+ })
180
+
181
+ return {
182
+ "success": False,
183
+ "strategy": strategy,
184
+ "message": "Non-critical failure queued for async correction",
185
+ "queued": True,
186
+ "error": error_message
187
+ }
188
+ else:
189
+ logger.info(">> Critical Failure Detected. Entering Self-Correction Mode (User Waiting)...")
190
+ logger.info(">> High latency path - fixing immediately for reliability.")
191
+
192
+ # Step 1: Detect and classify failure with full trace
193
+ logger.info("[1/5] Detecting and classifying failure (capturing full trace)...")
194
+ failure = self.detector.detect_failure(
195
+ agent_id=agent_id,
196
+ error_message=error_message,
197
+ context=context,
198
+ stack_trace=stack_trace,
199
+ user_prompt=user_prompt,
200
+ chain_of_thought=chain_of_thought,
201
+ failed_action=failed_action
202
+ )
203
+
204
+ # Step 2: Deep cognitive analysis
205
+ logger.info("[2/5] Analyzing failure (identifying cognitive glitches)...")
206
+ failure_history = self.detector.get_failure_history(agent_id=agent_id)
207
+ similar_failures = self.analyzer.find_similar_failures(failure, failure_history)
208
+ analysis = self.analyzer.analyze(failure, similar_failures)
209
+
210
+ # Generate cognitive diagnosis if trace available
211
+ diagnosis = None
212
+ if failure.failure_trace:
213
+ logger.info(" → Performing deep cognitive analysis...")
214
+ diagnosis = self.analyzer.diagnose_cognitive_glitch(failure)
215
+ logger.info(f" → Cognitive glitch: {diagnosis.cognitive_glitch.value}")
216
+
217
+ # Step 3: Simulate alternative path
218
+ logger.info("[3/5] Simulating alternative path...")
219
+ simulation = self.simulator.simulate(analysis)
220
+
221
+ # Step 4: Counterfactual simulation with Shadow Agent
222
+ shadow_result = None
223
+ if diagnosis and failure.failure_trace:
224
+ logger.info("[4/5] Running counterfactual simulation (Shadow Agent)...")
225
+ shadow_result = self.simulator.simulate_counterfactual(diagnosis, failure)
226
+ logger.info(f" → Shadow agent verified: {shadow_result.verified}")
227
+ else:
228
+ logger.info("[4/5] Skipping Shadow Agent (no trace available)")
229
+
230
+ if not simulation.success and (not shadow_result or not shadow_result.verified):
231
+ logger.warning("Simulation did not produce a viable alternative path")
232
+ return {
233
+ "success": False,
234
+ "failure": failure,
235
+ "analysis": analysis,
236
+ "diagnosis": diagnosis,
237
+ "simulation": simulation,
238
+ "shadow_result": shadow_result,
239
+ "patch": None,
240
+ "message": "Could not find a viable alternative path"
241
+ }
242
+
243
+ # Step 5: Create and optionally apply patch
244
+ logger.info("[5/5] Creating correction patch (The Optimizer)...")
245
+ patch = self.patcher.create_patch(
246
+ agent_id, analysis, simulation, diagnosis, shadow_result
247
+ )
248
+
249
+ # Classify patch for lifecycle management (Semantic Purge integration)
250
+ classified_patch = self.semantic_purge.register_patch(
251
+ patch=patch,
252
+ current_model_version=self.current_model_version
253
+ )
254
+ logger.info(f" → Patch classified as: {classified_patch.decay_type.value}")
255
+
256
+ patch_applied = False
257
+ if auto_patch:
258
+ logger.info("Auto-patching enabled, applying patch...")
259
+ patch_applied = self.patcher.apply_patch(patch)
260
+ else:
261
+ logger.info("Auto-patching disabled, patch created but not applied")
262
+
263
+ logger.info(f"=" * 80)
264
+ logger.info(f"SELF-CORRECTION COMPLETE")
265
+ logger.info(f"Patch ID: {patch.patch_id}")
266
+ logger.info(f"Patch Type: {patch.patch_type}")
267
+ logger.info(f"Decay Type: {classified_patch.decay_type.value}")
268
+ logger.info(f"Purge on Upgrade: {classified_patch.should_purge_on_upgrade}")
269
+ if diagnosis:
270
+ logger.info(f"Cognitive Glitch: {diagnosis.cognitive_glitch.value}")
271
+ logger.info(f"Patch Applied: {patch_applied}")
272
+ logger.info(f"Expected Success Rate: {simulation.estimated_success_rate:.2%}")
273
+ logger.info(f"=" * 80)
274
+
275
+ return {
276
+ "success": True,
277
+ "failure": failure,
278
+ "analysis": analysis,
279
+ "diagnosis": diagnosis,
280
+ "simulation": simulation,
281
+ "shadow_result": shadow_result,
282
+ "patch": patch,
283
+ "classified_patch": classified_patch,
284
+ "patch_applied": patch_applied,
285
+ "message": "Agent successfully patched" if patch_applied else "Patch created, awaiting manual approval"
286
+ }
287
+
288
+ def get_agent_status(self, agent_id: str) -> AgentState:
289
+ """
290
+ Get the current status of an agent.
291
+
292
+ Args:
293
+ agent_id: ID of the agent
294
+
295
+ Returns:
296
+ AgentState object with current status
297
+ """
298
+ return self.patcher.get_agent_state(agent_id)
299
+
300
+ def rollback_patch(self, patch_id: str) -> bool:
301
+ """
302
+ Rollback a previously applied patch.
303
+
304
+ Args:
305
+ patch_id: ID of the patch to rollback
306
+
307
+ Returns:
308
+ True if rollback was successful
309
+ """
310
+ return self.patcher.rollback_patch(patch_id)
311
+
312
+ def get_failure_history(self, agent_id: Optional[str] = None, limit: int = 100) -> List[AgentFailure]:
313
+ """
314
+ Get failure history.
315
+
316
+ Args:
317
+ agent_id: Optional filter by agent ID
318
+ limit: Maximum number of failures to return
319
+
320
+ Returns:
321
+ List of AgentFailure objects
322
+ """
323
+ return self.detector.get_failure_history(agent_id, limit)
324
+
325
+ def get_patch_history(self, agent_id: Optional[str] = None) -> List[CorrectionPatch]:
326
+ """
327
+ Get patch history.
328
+
329
+ Args:
330
+ agent_id: Optional filter by agent ID
331
+
332
+ Returns:
333
+ List of CorrectionPatch objects
334
+ """
335
+ return self.patcher.get_patch_history(agent_id)
336
+
337
+ def wake_up_and_fix(self, agent_id: str, error_message: str, context: Optional[Dict[str, Any]] = None):
338
+ """
339
+ Convenience method that wakes up the kernel, analyzes the failure,
340
+ simulates a better path, and patches the agent.
341
+
342
+ This is the main method referenced in the problem statement.
343
+
344
+ Args:
345
+ agent_id: ID of the failed agent
346
+ error_message: Error message from the failure
347
+ context: Additional context
348
+ """
349
+ logger.info("🚀 Kernel waking up to fix agent failure...")
350
+ result = self.handle_failure(agent_id, error_message, context, auto_patch=True)
351
+
352
+ if result["success"] and result["patch_applied"]:
353
+ logger.info("✅ Agent fixed and patched successfully!")
354
+ else:
355
+ logger.warning("⚠️ Agent fix incomplete, manual intervention may be required")
356
+
357
+ return result
358
+
359
+ # ============================================================================
360
+ # DUAL-LOOP ARCHITECTURE: Loop 2 (Alignment Engine) Methods
361
+ # ============================================================================
362
+
363
+ def handle_outcome(
364
+ self,
365
+ agent_id: str,
366
+ user_prompt: str,
367
+ agent_response: str,
368
+ context: Optional[Dict[str, Any]] = None,
369
+ tool_telemetry: Optional[List[ToolExecutionTelemetry]] = None,
370
+ auto_nudge: bool = True
371
+ ) -> Dict[str, Any]:
372
+ """
373
+ Handle an agent outcome through the Alignment Engine (Loop 2).
374
+
375
+ This is the entry point for the Completeness Auditor. Instead of waiting
376
+ for hard failures, we proactively detect when agents "give up" with
377
+ negative results.
378
+
379
+ Enhanced with:
380
+ - Tool execution telemetry correlation
381
+ - Automatic nudging on give-up detection
382
+ - Semantic analysis
383
+
384
+ Args:
385
+ agent_id: ID of the agent
386
+ user_prompt: Original user request
387
+ agent_response: Agent's response
388
+ context: Additional context
389
+ tool_telemetry: Optional tool execution telemetry
390
+ auto_nudge: Whether to automatically nudge on give-up (default: True)
391
+
392
+ Returns:
393
+ Dictionary with outcome analysis, audit results, and nudge results
394
+ """
395
+ logger.info(f"🔄 Loop 2 (Alignment Engine): Analyzing outcome for {agent_id}")
396
+
397
+ # Step 1: Analyze the outcome with enhanced telemetry
398
+ outcome = self.outcome_analyzer.analyze_outcome(
399
+ agent_id=agent_id,
400
+ user_prompt=user_prompt,
401
+ agent_response=agent_response,
402
+ context=context,
403
+ tool_telemetry=tool_telemetry
404
+ )
405
+
406
+ result = {
407
+ "outcome": outcome,
408
+ "audit": None,
409
+ "patch": None,
410
+ "classified_patch": None,
411
+ "nudge_result": None
412
+ }
413
+
414
+ # Step 2: Check if this triggers Completeness Audit (Give-Up Signal)
415
+ if self.outcome_analyzer.should_trigger_audit(outcome):
416
+ logger.info(f"🔍 Give-Up Signal detected! Triggering Completeness Auditor...")
417
+
418
+ # Step 2a: Auto-nudge if enabled
419
+ if auto_nudge and self.nudge_mechanism.should_nudge(outcome):
420
+ logger.info(f"💡 Auto-nudge enabled - attempting nudge...")
421
+ nudge_prompt = self.nudge_mechanism.generate_nudge(outcome)
422
+ logger.info(f"Nudge prompt: {nudge_prompt[:100]}...")
423
+
424
+ # Note: In a real system, you would re-invoke the agent with the nudge
425
+ # For demo purposes, we'll simulate the nudge result
426
+ # Real implementation would call: retry_response = agent.invoke(nudge_prompt)
427
+ result["nudge_prompt"] = nudge_prompt
428
+ logger.info(f"✓ Nudge prompt generated (agent should be re-invoked)")
429
+
430
+ # Step 3: Run Completeness Audit (Differential Auditing)
431
+ audit = self.completeness_auditor.audit_give_up(outcome)
432
+ result["audit"] = audit
433
+
434
+ # Step 4: If teacher found data (laziness detected), create competence patch
435
+ if audit.teacher_found_data:
436
+ logger.info(f"⚠️ LAZINESS DETECTED: Creating competence patch...")
437
+
438
+ # Create a patch from the competence lesson
439
+ patch = self._create_competence_patch(agent_id, audit)
440
+ result["patch"] = patch
441
+
442
+ # Step 5: Classify patch for lifecycle management (Semantic Purge)
443
+ classified_patch = self.semantic_purge.register_patch(
444
+ patch=patch,
445
+ current_model_version=self.current_model_version
446
+ )
447
+ result["classified_patch"] = classified_patch
448
+
449
+ # Register with auditor
450
+ self.semantic_purge.register_completeness_audit(
451
+ audit=audit,
452
+ current_model_version=self.current_model_version
453
+ )
454
+
455
+ # Apply patch
456
+ if self.config.get("auto_patch", True):
457
+ self.patcher.apply_patch(patch)
458
+ logger.info(f"✓ Competence patch applied")
459
+ else:
460
+ logger.info(f"✓ No give-up signal detected - agent performing well")
461
+
462
+ return result
463
+
464
+ def _create_competence_patch(
465
+ self,
466
+ agent_id: str,
467
+ audit: CompletenessAudit
468
+ ) -> CorrectionPatch:
469
+ """
470
+ Create a patch from a completeness audit.
471
+
472
+ Competence patches teach the agent to avoid giving up too early.
473
+ """
474
+ import uuid
475
+ from datetime import datetime
476
+ from .models import FailureAnalysis, SimulationResult, AgentFailure, FailureType, FailureSeverity
477
+
478
+ # Create a synthetic failure for the audit
479
+ failure = AgentFailure(
480
+ agent_id=agent_id,
481
+ failure_type=FailureType.LOGIC_ERROR,
482
+ severity=FailureSeverity.MEDIUM,
483
+ error_message=f"Agent gave up: {audit.agent_outcome.agent_response}",
484
+ context=audit.agent_outcome.context
485
+ )
486
+
487
+ # Create analysis
488
+ analysis = FailureAnalysis(
489
+ failure=failure,
490
+ root_cause="Agent gave up too early without exhaustive search",
491
+ contributing_factors=[audit.gap_analysis],
492
+ suggested_fixes=[audit.competence_patch],
493
+ confidence_score=audit.confidence,
494
+ similar_failures=[]
495
+ )
496
+
497
+ # Create simulation
498
+ simulation = SimulationResult(
499
+ simulation_id=f"sim-{uuid.uuid4().hex[:8]}",
500
+ success=True,
501
+ alternative_path=[
502
+ {
503
+ "step": 1,
504
+ "action": "exhaustive_search",
505
+ "description": "Check all data sources before reporting 'not found'"
506
+ },
507
+ {
508
+ "step": 2,
509
+ "action": "apply_competence_lesson",
510
+ "description": audit.competence_patch
511
+ }
512
+ ],
513
+ expected_outcome="Agent will search exhaustively before giving up",
514
+ risk_score=0.1,
515
+ estimated_success_rate=0.9
516
+ )
517
+
518
+ # Create patch
519
+ patch_id = f"competence-patch-{uuid.uuid4().hex[:8]}"
520
+
521
+ patch = CorrectionPatch(
522
+ patch_id=patch_id,
523
+ agent_id=agent_id,
524
+ failure_analysis=analysis,
525
+ simulation_result=simulation,
526
+ patch_type="system_prompt",
527
+ patch_content={
528
+ "type": "competence_rule",
529
+ "rule": audit.competence_patch,
530
+ "from_audit": audit.audit_id,
531
+ "teacher_model": audit.teacher_model
532
+ },
533
+ applied=False
534
+ )
535
+
536
+ return patch
537
+
538
+ def upgrade_model(self, new_model_version: str) -> Dict[str, Any]:
539
+ """
540
+ Upgrade the model version and trigger Semantic Purge.
541
+
542
+ This is the "Purge Event" that removes Type A (Syntax) patches
543
+ that are likely fixed in the new model version.
544
+
545
+ Args:
546
+ new_model_version: New model version (e.g., "gpt-5")
547
+
548
+ Returns:
549
+ Dictionary with purge statistics
550
+ """
551
+ logger.info(f"=" * 80)
552
+ logger.info(f"MODEL UPGRADE: {self.current_model_version} → {new_model_version}")
553
+ logger.info(f"=" * 80)
554
+
555
+ old_version = self.current_model_version
556
+
557
+ # Trigger semantic purge
558
+ purge_result = self.semantic_purge.purge_on_upgrade(
559
+ old_model_version=old_version,
560
+ new_model_version=new_model_version
561
+ )
562
+
563
+ # Update model version
564
+ self.current_model_version = new_model_version
565
+
566
+ # Update all agent states
567
+ for agent_state in self.patcher.agent_states.values():
568
+ agent_state.model_version = new_model_version
569
+
570
+ logger.info(f"=" * 80)
571
+ logger.info(f"MODEL UPGRADE COMPLETE")
572
+ logger.info(f" Purged: {purge_result['stats']['purged_count']} Type A patches")
573
+ logger.info(f" Retained: {purge_result['stats']['retained_count']} Type B patches")
574
+ logger.info(f" Tokens Reclaimed: {purge_result['stats']['tokens_reclaimed']}")
575
+ logger.info(f"=" * 80)
576
+
577
+ return purge_result
578
+
579
+ def get_alignment_stats(self) -> Dict[str, Any]:
580
+ """
581
+ Get statistics about the Alignment Engine (Loop 2).
582
+
583
+ Enhanced to include:
584
+ - Completeness auditor metrics
585
+ - Semantic purge metrics
586
+ - Nudge mechanism effectiveness
587
+ - Value delivery metrics (competence focus)
588
+
589
+ Returns:
590
+ Dictionary with comprehensive stats about quality and efficiency
591
+ """
592
+ return {
593
+ "completeness_auditor": self.completeness_auditor.get_audit_stats(),
594
+ "semantic_purge": self.semantic_purge.get_purge_stats(),
595
+ "outcome_analyzer": {
596
+ "total_outcomes": len(self.outcome_analyzer.outcome_history),
597
+ "give_up_rate": self.outcome_analyzer.get_give_up_rate()
598
+ },
599
+ "nudge_mechanism": self.nudge_mechanism.get_nudge_stats(),
600
+ "value_delivery": self._calculate_value_delivery_metrics()
601
+ }
602
+
603
+ def _calculate_value_delivery_metrics(self) -> Dict[str, Any]:
604
+ """
605
+ Calculate metrics focused on competence and value delivery.
606
+
607
+ This differentiates the system from standard governance tools
608
+ that only focus on safety/compliance (Loop 1). We measure:
609
+ - Give-up rate (lower is better)
610
+ - Laziness detection rate
611
+ - Nudge success rate
612
+ - Competence patch effectiveness
613
+
614
+ Returns:
615
+ Dictionary with value delivery metrics
616
+ """
617
+ audit_stats = self.completeness_auditor.get_audit_stats()
618
+ nudge_stats = self.nudge_mechanism.get_nudge_stats()
619
+ give_up_rate = self.outcome_analyzer.get_give_up_rate()
620
+
621
+ # Calculate competence score (0-100)
622
+ # Higher score = better value delivery
623
+ competence_score = 100.0
624
+
625
+ # Penalize for high give-up rate
626
+ competence_score -= (give_up_rate * 30) # Max 30 point penalty
627
+
628
+ # Penalize for laziness detection
629
+ laziness_rate = audit_stats.get("laziness_rate", 0.0)
630
+ competence_score -= (laziness_rate * 40) # Max 40 point penalty
631
+
632
+ # Reward for nudge effectiveness
633
+ nudge_success_rate = nudge_stats.get("success_rate", 0.0)
634
+ competence_score += (nudge_success_rate * 20) # Max 20 point bonus
635
+
636
+ # Ensure bounds
637
+ competence_score = max(0, min(100, competence_score))
638
+
639
+ return {
640
+ "competence_score": round(competence_score, 2),
641
+ "give_up_rate": round(give_up_rate, 4),
642
+ "laziness_detection_rate": round(laziness_rate, 4),
643
+ "nudge_success_rate": round(nudge_success_rate, 4),
644
+ "total_audits": audit_stats.get("total_audits", 0),
645
+ "laziness_caught": audit_stats.get("laziness_detected", 0),
646
+ "focus": "Competence & Value Delivery (differentiates from safety-only tools)"
647
+ }
648
+
649
+ def get_classified_patches(self) -> Dict[str, List[ClassifiedPatch]]:
650
+ """
651
+ Get patches classified by type.
652
+
653
+ Returns:
654
+ Dictionary with purgeable and permanent patches
655
+ """
656
+ return {
657
+ "purgeable": self.semantic_purge.get_purgeable_patches(),
658
+ "permanent": self.semantic_purge.get_permanent_patches()
659
+ }
660
+
661
+ def process_async_queue(self, batch_size: int = 10) -> Dict[str, Any]:
662
+ """
663
+ Process failures from the async queue (background/nightly processing).
664
+
665
+ This method would typically run in a background worker or during
666
+ off-peak hours to fix non-critical failures that were queued.
667
+
668
+ Args:
669
+ batch_size: Maximum number of failures to process in this batch
670
+
671
+ Returns:
672
+ Dictionary with processing statistics
673
+ """
674
+ logger.info(f"=" * 80)
675
+ logger.info(f"ASYNC QUEUE PROCESSING - Processing up to {batch_size} failures")
676
+ logger.info(f"Queue size: {len(self.async_failure_queue)}")
677
+ logger.info(f"=" * 80)
678
+
679
+ processed = 0
680
+ succeeded = 0
681
+ failed = 0
682
+
683
+ # Process up to batch_size items
684
+ while self.async_failure_queue and processed < batch_size:
685
+ failure_data = self.async_failure_queue.pop(0)
686
+ processed += 1
687
+
688
+ logger.info(f"Processing async failure {processed}/{batch_size}")
689
+ logger.info(f" Agent: {failure_data['agent_id']}")
690
+ logger.info(f" Error: {failure_data['error_message']}")
691
+
692
+ try:
693
+ # Process the failure without triage (already decided async)
694
+ # Temporarily remove user_prompt to skip triage
695
+ user_prompt = failure_data.pop('user_prompt', None)
696
+
697
+ result = self.handle_failure(
698
+ agent_id=failure_data['agent_id'],
699
+ error_message=failure_data['error_message'],
700
+ context=failure_data.get('context'),
701
+ stack_trace=failure_data.get('stack_trace'),
702
+ auto_patch=True,
703
+ user_prompt=None, # Skip triage by not providing user_prompt
704
+ chain_of_thought=failure_data.get('chain_of_thought'),
705
+ failed_action=failure_data.get('failed_action')
706
+ )
707
+
708
+ if result.get('success') and result.get('patch_applied'):
709
+ succeeded += 1
710
+ logger.info(f" ✓ Fixed successfully")
711
+ else:
712
+ failed += 1
713
+ logger.info(f" ✗ Fix failed")
714
+ except Exception as e:
715
+ failed += 1
716
+ logger.error(f" ✗ Error processing: {str(e)}")
717
+
718
+ logger.info(f"=" * 80)
719
+ logger.info(f"ASYNC QUEUE PROCESSING COMPLETE")
720
+ logger.info(f" Processed: {processed}")
721
+ logger.info(f" Succeeded: {succeeded}")
722
+ logger.info(f" Failed: {failed}")
723
+ logger.info(f" Remaining in queue: {len(self.async_failure_queue)}")
724
+ logger.info(f"=" * 80)
725
+
726
+ return {
727
+ "processed": processed,
728
+ "succeeded": succeeded,
729
+ "failed": failed,
730
+ "remaining": len(self.async_failure_queue)
731
+ }
732
+
733
+ def get_triage_stats(self) -> Dict[str, Any]:
734
+ """
735
+ Get statistics about triage decisions.
736
+
737
+ Returns:
738
+ Dictionary with triage statistics
739
+ """
740
+ return {
741
+ "async_queue_size": len(self.async_failure_queue),
742
+ "critical_tools": len(self.triage.critical_tools),
743
+ "high_effort_keywords": len(self.triage.high_effort_keywords)
744
+ }