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
@@ -0,0 +1,582 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ """
5
+ Agent patcher that applies corrections to agents.
6
+ """
7
+
8
+ import logging
9
+ import uuid
10
+ from typing import Dict, Any, Optional, List
11
+ from datetime import datetime
12
+
13
+ from .models import (
14
+ FailureAnalysis, SimulationResult, CorrectionPatch, AgentState,
15
+ DiagnosisJSON, ShadowAgentResult, PatchStrategy, CognitiveGlitch,
16
+ AgentFailure
17
+ )
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ class AgentPatcher:
23
+ """
24
+ Patches agents to prevent future failures.
25
+
26
+ This is "The Patcher" (The Optimizer) - applies fixes permanently.
27
+ """
28
+
29
+ def __init__(self):
30
+ self.patches: Dict[str, CorrectionPatch] = {}
31
+ self.agent_states: Dict[str, AgentState] = {}
32
+ self.system_prompts: Dict[str, str] = {} # Store system prompts
33
+ self.rag_memories: List[Dict[str, Any]] = [] # RAG memory store
34
+
35
+ def create_patch(
36
+ self,
37
+ agent_id: str,
38
+ analysis: FailureAnalysis,
39
+ simulation: SimulationResult,
40
+ diagnosis: Optional[DiagnosisJSON] = None,
41
+ shadow_result: Optional[ShadowAgentResult] = None
42
+ ) -> CorrectionPatch:
43
+ """
44
+ Create a correction patch for an agent.
45
+
46
+ Args:
47
+ agent_id: ID of the agent to patch
48
+ analysis: Failure analysis
49
+ simulation: Successful simulation result
50
+ diagnosis: Cognitive glitch diagnosis if available
51
+ shadow_result: Shadow agent verification result
52
+
53
+ Returns:
54
+ CorrectionPatch object
55
+ """
56
+ logger.info(f"Creating patch for agent {agent_id}")
57
+
58
+ # Generate patch ID
59
+ patch_id = f"patch-{uuid.uuid4().hex[:8]}"
60
+
61
+ # Determine patch strategy (easy vs hard fix)
62
+ strategy = self._determine_patch_strategy(analysis, diagnosis)
63
+
64
+ # Determine patch type based on failure
65
+ patch_type = self._determine_patch_type(analysis, strategy)
66
+
67
+ # Generate patch content based on strategy
68
+ patch_content = self._generate_patch_content(
69
+ analysis, simulation, strategy, diagnosis, shadow_result
70
+ )
71
+
72
+ patch = CorrectionPatch(
73
+ patch_id=patch_id,
74
+ agent_id=agent_id,
75
+ failure_analysis=analysis,
76
+ simulation_result=simulation,
77
+ patch_type=patch_type,
78
+ patch_content=patch_content,
79
+ applied=False,
80
+ rollback_available=True,
81
+ diagnosis=diagnosis,
82
+ shadow_result=shadow_result
83
+ )
84
+
85
+ self.patches[patch_id] = patch
86
+ logger.info(f"Created {patch_type} patch {patch_id} with strategy {strategy}")
87
+
88
+ return patch
89
+
90
+ def apply_patch(self, patch: CorrectionPatch) -> bool:
91
+ """
92
+ Apply a correction patch to an agent.
93
+
94
+ This is "The Patcher" in action - applying the fix permanently.
95
+
96
+ Args:
97
+ patch: The patch to apply
98
+
99
+ Returns:
100
+ True if patch was applied successfully
101
+ """
102
+ logger.info(f"Applying patch {patch.patch_id} to agent {patch.agent_id}")
103
+
104
+ try:
105
+ # Apply patch based on type
106
+ if patch.patch_type in [PatchStrategy.SYSTEM_PROMPT.value, "system_prompt"]:
107
+ self._apply_system_prompt_patch(patch)
108
+ elif patch.patch_type in [PatchStrategy.RAG_MEMORY.value, "rag_memory"]:
109
+ self._apply_rag_memory_patch(patch)
110
+ elif patch.patch_type == "code":
111
+ self._apply_code_patch(patch)
112
+ elif patch.patch_type == "config":
113
+ self._apply_config_patch(patch)
114
+ else:
115
+ logger.warning(f"Unknown patch type: {patch.patch_type}, applying generically")
116
+
117
+ # Mark as applied
118
+ patch.applied = True
119
+ patch.applied_at = datetime.utcnow()
120
+
121
+ # Update agent state
122
+ self._update_agent_state(patch.agent_id, patch)
123
+
124
+ logger.info(f"Successfully applied patch {patch.patch_id}")
125
+ return True
126
+
127
+ except Exception as e:
128
+ logger.error(f"Failed to apply patch {patch.patch_id}: {e}")
129
+ return False
130
+
131
+ def _apply_system_prompt_patch(self, patch: CorrectionPatch):
132
+ """
133
+ Apply an easy fix: Update the system_prompt with a new rule.
134
+
135
+ Example: "Always check schema before querying"
136
+ """
137
+ agent_id = patch.agent_id
138
+ rule = patch.patch_content.get("rule", "")
139
+
140
+ # Get or create system prompt
141
+ if agent_id not in self.system_prompts:
142
+ self.system_prompts[agent_id] = "You are a helpful assistant."
143
+
144
+ # Append the new rule
145
+ self.system_prompts[agent_id] += f"\n\nIMPORTANT RULE: {rule}"
146
+
147
+ logger.info(f"Updated system prompt for agent {agent_id} with new rule")
148
+
149
+ def _apply_rag_memory_patch(self, patch: CorrectionPatch):
150
+ """
151
+ Apply a hard fix: Inject a "Memory" into the vector store.
152
+
153
+ Example: "In 2025, user asked X, and we failed. The correct logic is Y."
154
+ """
155
+ memory = {
156
+ "agent_id": patch.agent_id,
157
+ "timestamp": datetime.utcnow(),
158
+ "failure_context": patch.patch_content.get("failure_context", ""),
159
+ "correct_logic": patch.patch_content.get("correct_logic", ""),
160
+ "patch_id": patch.patch_id,
161
+ "embeddings_ready": False # Would compute embeddings in real system
162
+ }
163
+
164
+ self.rag_memories.append(memory)
165
+
166
+ logger.info(f"Injected RAG memory for agent {patch.agent_id}: {memory['correct_logic'][:50]}...")
167
+
168
+ def _apply_code_patch(self, patch: CorrectionPatch):
169
+ """Apply code changes patch."""
170
+ # In real system, would modify actual code
171
+ logger.info(f"Code patch applied (simulated) for agent {patch.agent_id}")
172
+
173
+ def _apply_config_patch(self, patch: CorrectionPatch):
174
+ """Apply configuration changes patch."""
175
+ # In real system, would update configuration
176
+ logger.info(f"Config patch applied (simulated) for agent {patch.agent_id}")
177
+
178
+ def rollback_patch(self, patch_id: str) -> bool:
179
+ """
180
+ Rollback a previously applied patch.
181
+
182
+ Args:
183
+ patch_id: ID of the patch to rollback
184
+
185
+ Returns:
186
+ True if rollback was successful
187
+ """
188
+ if patch_id not in self.patches:
189
+ logger.error(f"Patch {patch_id} not found")
190
+ return False
191
+
192
+ patch = self.patches[patch_id]
193
+
194
+ if not patch.applied:
195
+ logger.warning(f"Patch {patch_id} is not applied, cannot rollback")
196
+ return False
197
+
198
+ if not patch.rollback_available:
199
+ logger.error(f"Patch {patch_id} does not support rollback")
200
+ return False
201
+
202
+ logger.info(f"Rolling back patch {patch_id}")
203
+
204
+ try:
205
+ # Rollback based on patch type
206
+ if patch.patch_type in [PatchStrategy.SYSTEM_PROMPT.value, "system_prompt"]:
207
+ self._rollback_system_prompt(patch)
208
+ elif patch.patch_type in [PatchStrategy.RAG_MEMORY.value, "rag_memory"]:
209
+ self._rollback_rag_memory(patch)
210
+
211
+ # Mark as not applied
212
+ patch.applied = False
213
+ patch.applied_at = None
214
+
215
+ # Update agent state
216
+ if patch.agent_id in self.agent_states:
217
+ state = self.agent_states[patch.agent_id]
218
+ if patch_id in state.patches_applied:
219
+ state.patches_applied.remove(patch_id)
220
+
221
+ logger.info(f"Successfully rolled back patch {patch_id}")
222
+ return True
223
+
224
+ except Exception as e:
225
+ logger.error(f"Failed to rollback patch {patch_id}: {e}")
226
+ return False
227
+
228
+ def _rollback_system_prompt(self, patch: CorrectionPatch):
229
+ """Rollback system prompt changes."""
230
+ # In real system, would restore previous version
231
+ logger.info(f"Rolled back system prompt for agent {patch.agent_id}")
232
+
233
+ def _rollback_rag_memory(self, patch: CorrectionPatch):
234
+ """Rollback RAG memory injection."""
235
+ # Remove the memory from RAG store
236
+ self.rag_memories = [
237
+ m for m in self.rag_memories if m.get("patch_id") != patch.patch_id
238
+ ]
239
+ logger.info(f"Removed RAG memory for patch {patch.patch_id}")
240
+
241
+ def get_agent_state(self, agent_id: str) -> AgentState:
242
+ """Get the current state of an agent."""
243
+ if agent_id not in self.agent_states:
244
+ self.agent_states[agent_id] = AgentState(
245
+ agent_id=agent_id,
246
+ status="unknown"
247
+ )
248
+ return self.agent_states[agent_id]
249
+
250
+ def _determine_patch_strategy(
251
+ self,
252
+ analysis: FailureAnalysis,
253
+ diagnosis: Optional[DiagnosisJSON]
254
+ ) -> PatchStrategy:
255
+ """
256
+ Determine patch strategy based on the problem statement requirements:
257
+
258
+ - Tool Misuse → Schema Injection (update tool definition in prompt)
259
+ - Hallucination → RAG Patch (add negative constraint to context)
260
+ - Policy Violation → Constitutional Update (prepend refusal rule to system prompt)
261
+ """
262
+ if not diagnosis:
263
+ return PatchStrategy.CODE_CHANGE
264
+
265
+ # Tool Misuse: Schema Injection - update tool definition in the prompt
266
+ if diagnosis.cognitive_glitch == CognitiveGlitch.TOOL_MISUSE:
267
+ return PatchStrategy.SYSTEM_PROMPT
268
+
269
+ # Policy Violation: Constitutional Update - prepend refusal rule to system prompt
270
+ if diagnosis.cognitive_glitch == CognitiveGlitch.POLICY_VIOLATION:
271
+ return PatchStrategy.SYSTEM_PROMPT
272
+
273
+ # Hallucination: RAG Patch - add negative constraint to memory
274
+ if diagnosis.cognitive_glitch == CognitiveGlitch.HALLUCINATION:
275
+ return PatchStrategy.RAG_MEMORY
276
+
277
+ # Easy fixes: Simple cognitive glitches that can be addressed with rules
278
+ if diagnosis.cognitive_glitch in [
279
+ CognitiveGlitch.PERMISSION_ERROR,
280
+ CognitiveGlitch.CONTEXT_GAP
281
+ ]:
282
+ if diagnosis.confidence > 0.8:
283
+ return PatchStrategy.SYSTEM_PROMPT
284
+
285
+ # Hard fixes: Complex patterns requiring historical context
286
+ if diagnosis.cognitive_glitch in [
287
+ CognitiveGlitch.SCHEMA_MISMATCH,
288
+ CognitiveGlitch.LOGIC_ERROR
289
+ ]:
290
+ return PatchStrategy.RAG_MEMORY
291
+
292
+ return PatchStrategy.CODE_CHANGE
293
+
294
+ def _determine_patch_type(
295
+ self,
296
+ analysis: FailureAnalysis,
297
+ strategy: PatchStrategy
298
+ ) -> str:
299
+ """Determine the type of patch needed."""
300
+ # Use strategy as primary determinant
301
+ if strategy == PatchStrategy.SYSTEM_PROMPT:
302
+ return "system_prompt"
303
+ elif strategy == PatchStrategy.RAG_MEMORY:
304
+ return "rag_memory"
305
+ elif strategy == PatchStrategy.CONFIG_UPDATE:
306
+ return "config"
307
+ elif strategy == PatchStrategy.RULE_UPDATE:
308
+ return "rule"
309
+
310
+ # Fall back to failure type analysis
311
+ failure_type = analysis.failure.failure_type.value
312
+
313
+ if failure_type == "blocked_by_control_plane":
314
+ return "code" # Code changes to add permission checks
315
+ elif failure_type == "timeout":
316
+ return "config" # Configuration changes for timeouts
317
+ elif failure_type == "invalid_action":
318
+ return "rule" # Rule changes to validate actions
319
+ else:
320
+ return "code" # Default to code patches
321
+
322
+ def _generate_patch_content(
323
+ self,
324
+ analysis: FailureAnalysis,
325
+ simulation: SimulationResult,
326
+ strategy: PatchStrategy,
327
+ diagnosis: Optional[DiagnosisJSON] = None,
328
+ shadow_result: Optional[ShadowAgentResult] = None
329
+ ) -> Dict[str, Any]:
330
+ """Generate the actual patch content based on strategy."""
331
+
332
+ # EASY FIX: System Prompt Update
333
+ if strategy == PatchStrategy.SYSTEM_PROMPT:
334
+ rule = self._generate_system_prompt_rule(diagnosis, analysis)
335
+ return {
336
+ "type": "system_prompt_update",
337
+ "rule": rule,
338
+ "diagnosis": diagnosis.cognitive_glitch.value if diagnosis else "unknown",
339
+ "hint_applied": diagnosis.hint if diagnosis else ""
340
+ }
341
+
342
+ # HARD FIX: RAG Memory Injection
343
+ elif strategy == PatchStrategy.RAG_MEMORY:
344
+ return self._generate_rag_memory_content(diagnosis, analysis, shadow_result)
345
+
346
+ # CODE CHANGE
347
+ elif strategy == PatchStrategy.CODE_CHANGE:
348
+ return self._generate_code_change_content(analysis, simulation)
349
+
350
+ # CONFIG UPDATE
351
+ elif strategy == PatchStrategy.CONFIG_UPDATE:
352
+ return self._generate_config_content(analysis, simulation)
353
+
354
+ # Default fallback
355
+ return {
356
+ "type": "generic_fix",
357
+ "suggested_fixes": analysis.suggested_fixes,
358
+ "simulation_steps": simulation.alternative_path
359
+ }
360
+
361
+ def _generate_system_prompt_rule(
362
+ self,
363
+ diagnosis: Optional[DiagnosisJSON],
364
+ analysis: FailureAnalysis
365
+ ) -> str:
366
+ """
367
+ Generate a rule to add to system prompt.
368
+
369
+ Implements:
370
+ - Tool Misuse → Schema Injection (stricter tool definition)
371
+ - Policy Violation → Constitutional Update (refusal rule)
372
+ """
373
+ if not diagnosis:
374
+ return f"Always validate before: {analysis.suggested_fixes[0] if analysis.suggested_fixes else 'executing actions'}"
375
+
376
+ # Tool Misuse: Schema Injection - Make tool definition stricter
377
+ if diagnosis.cognitive_glitch == CognitiveGlitch.TOOL_MISUSE:
378
+ failure = analysis.failure
379
+ # Extract specific tool information from the failure
380
+ tool_info = ""
381
+ if failure.failure_trace and failure.failure_trace.failed_action:
382
+ action_name = failure.failure_trace.failed_action.get("action", "tool")
383
+ tool_info = f" for {action_name}"
384
+ return f"SCHEMA INJECTION: Tool definitions{tool_info} require strict parameter type checking. Always verify parameter types match the schema exactly (e.g., UUID format for id parameters, not names or strings)."
385
+
386
+ # Policy Violation: Constitutional Update - Prepend refusal rule
387
+ if diagnosis.cognitive_glitch == CognitiveGlitch.POLICY_VIOLATION:
388
+ # Determine the specific policy domain from the failure
389
+ failure = analysis.failure
390
+ domain = "restricted topics"
391
+
392
+ # Check error message first
393
+ error_lower = failure.error_message.lower()
394
+ if any(kw in error_lower for kw in ["medical", "health"]):
395
+ domain = "medical issues"
396
+ elif any(kw in error_lower for kw in ["legal", "law"]):
397
+ domain = "legal matters"
398
+ elif any(kw in error_lower for kw in ["investment", "financial"]):
399
+ domain = "investment advice"
400
+ # Then check failure trace if available
401
+ elif failure.failure_trace and failure.failure_trace.user_prompt:
402
+ prompt_lower = failure.failure_trace.user_prompt.lower()
403
+ if any(kw in prompt_lower for kw in ["medical", "health", "diagnosis", "treatment", "medicine"]):
404
+ domain = "medical issues"
405
+ elif any(kw in prompt_lower for kw in ["legal", "law", "attorney", "sue", "lawsuit"]):
406
+ domain = "legal matters"
407
+ elif any(kw in prompt_lower for kw in ["investment", "financial", "stock", "invest"]):
408
+ domain = "investment advice"
409
+
410
+ return f"CONSTITUTIONAL REFUSAL RULE: You must refuse to provide advice on {domain}. Politely decline and explain that you are not qualified to advise on such matters."
411
+
412
+ # Convert hint into a permanent rule for other glitches
413
+ if diagnosis.cognitive_glitch == CognitiveGlitch.PERMISSION_ERROR:
414
+ return "Always check permissions before attempting any action. Use validate_permissions() first."
415
+ elif diagnosis.cognitive_glitch == CognitiveGlitch.CONTEXT_GAP:
416
+ return "Before executing actions, ensure you have: 1) Complete schema information, 2) Permission requirements, 3) Clear action scope."
417
+ elif diagnosis.cognitive_glitch == CognitiveGlitch.HALLUCINATION:
418
+ return "Always verify entity names against the provided schema before using them. Never invent or assume entity names."
419
+ elif diagnosis.cognitive_glitch == CognitiveGlitch.SCHEMA_MISMATCH:
420
+ return "Verify all table and column names against the schema before use. Do not assume schema structure."
421
+ elif diagnosis.cognitive_glitch == CognitiveGlitch.LOGIC_ERROR:
422
+ return "When interpreting ambiguous terms like 'recent', 'delete', 'modify', ask for clarification before proceeding."
423
+
424
+ return "Proceed with caution and verify all assumptions before actions."
425
+
426
+ def _generate_rag_memory_content(
427
+ self,
428
+ diagnosis: Optional[DiagnosisJSON],
429
+ analysis: FailureAnalysis,
430
+ shadow_result: Optional[ShadowAgentResult]
431
+ ) -> Dict[str, Any]:
432
+ """
433
+ Generate RAG memory content (Hard Fix).
434
+
435
+ For Hallucination: Add negative constraint to the context.
436
+ Example: "Project_Alpha is deprecated" or "Entity X does not exist"
437
+ """
438
+ failure = analysis.failure
439
+
440
+ # Create a memory entry
441
+ memory_text = f"In {failure.timestamp.year}, "
442
+ negative_constraint = None
443
+
444
+ if failure.failure_trace:
445
+ memory_text += f"user asked: '{failure.failure_trace.user_prompt}', "
446
+ memory_text += f"and we failed with: {failure.error_message}. "
447
+
448
+ if diagnosis:
449
+ memory_text += f"The problem was {diagnosis.cognitive_glitch.value}: {diagnosis.deep_problem}. "
450
+
451
+ # For hallucinations, extract the hallucinated entity and create negative constraint
452
+ if diagnosis.cognitive_glitch == CognitiveGlitch.HALLUCINATION:
453
+ # Extract hallucinated entity from error message or failed action
454
+ hallucinated_entity = self._extract_hallucinated_entity(failure)
455
+ if hallucinated_entity:
456
+ negative_constraint = f"{hallucinated_entity} does not exist and is deprecated. Do not reference it."
457
+ memory_text += f"NEGATIVE CONSTRAINT: {negative_constraint} "
458
+
459
+ if shadow_result and shadow_result.verified:
460
+ memory_text += f"The correct approach is: {shadow_result.output}. "
461
+ if shadow_result.action_taken:
462
+ memory_text += f"Correct action: {shadow_result.action_taken}"
463
+ else:
464
+ memory_text += f"we encountered: {failure.error_message}. "
465
+ memory_text += f"The correct approach is: {analysis.suggested_fixes[0] if analysis.suggested_fixes else 'validate before action'}"
466
+
467
+ return {
468
+ "type": "rag_memory",
469
+ "failure_context": memory_text,
470
+ "correct_logic": shadow_result.output if shadow_result else analysis.suggested_fixes[0] if analysis.suggested_fixes else "Unknown",
471
+ "cognitive_glitch": diagnosis.cognitive_glitch.value if diagnosis else "unknown",
472
+ "negative_constraint": negative_constraint, # New field for hallucinations
473
+ "timestamp": datetime.utcnow().isoformat(),
474
+ "verified_by_shadow": shadow_result.verified if shadow_result else False
475
+ }
476
+
477
+ def _extract_hallucinated_entity(self, failure: AgentFailure) -> Optional[str]:
478
+ """Extract the hallucinated entity name from failure context."""
479
+ error_lower = failure.error_message.lower()
480
+
481
+ # Common patterns for hallucinations
482
+ # "Project_Alpha does not exist" -> "Project_Alpha"
483
+ # "Table 'recent_users' not found" -> "recent_users"
484
+ # "Unknown entity: XYZ" -> "XYZ"
485
+
486
+ import re
487
+
488
+ # Pattern: 'entity_name' or "entity_name" in error message
489
+ quoted_match = re.search(r"['\"]([^'\"]+)['\"]", failure.error_message)
490
+ if quoted_match:
491
+ return quoted_match.group(1)
492
+
493
+ # Pattern: Entity_Name or Project_Alpha (CamelCase or Snake_Case with underscores)
494
+ if failure.failure_trace and failure.failure_trace.failed_action:
495
+ action_str = str(failure.failure_trace.failed_action)
496
+ # Look for CamelCase or underscore-separated capitalized words
497
+ camel_match = re.search(r'\b([A-Z][a-z]*(?:_[A-Z][a-z]*)+)\b', action_str)
498
+ if camel_match:
499
+ return camel_match.group(1)
500
+ # Also try looking for simple CamelCase
501
+ camel_match2 = re.search(r'\b([A-Z][a-z]+[A-Z][a-z]+(?:[A-Z][a-z]+)*)\b', action_str)
502
+ if camel_match2:
503
+ return camel_match2.group(1)
504
+
505
+ # Try to find in error message
506
+ camel_match3 = re.search(r'\b([A-Z][a-z]*(?:_[A-Z][a-z]*)+)\b', failure.error_message)
507
+ if camel_match3:
508
+ return camel_match3.group(1)
509
+
510
+ return None
511
+
512
+ def _generate_code_change_content(
513
+ self,
514
+ analysis: FailureAnalysis,
515
+ simulation: SimulationResult
516
+ ) -> Dict[str, Any]:
517
+ """Generate code change content."""
518
+ failure_type = analysis.failure.failure_type.value
519
+
520
+ if failure_type == "blocked_by_control_plane":
521
+ return {
522
+ "type": "permission_check",
523
+ "changes": [
524
+ {
525
+ "location": "before_action",
526
+ "code": "if not validate_permissions(action, resource): raise PermissionError()",
527
+ "description": "Add permission validation"
528
+ },
529
+ {
530
+ "location": "action_handler",
531
+ "code": "with safe_context(): execute_action()",
532
+ "description": "Wrap action in safe context"
533
+ }
534
+ ],
535
+ "simulation_steps": simulation.alternative_path
536
+ }
537
+ else:
538
+ return {
539
+ "type": "generic_code_fix",
540
+ "suggested_fixes": analysis.suggested_fixes,
541
+ "simulation_steps": simulation.alternative_path
542
+ }
543
+
544
+ def _generate_config_content(
545
+ self,
546
+ analysis: FailureAnalysis,
547
+ simulation: SimulationResult
548
+ ) -> Dict[str, Any]:
549
+ """Generate configuration update content."""
550
+ return {
551
+ "type": "timeout_handling",
552
+ "config": {
553
+ "timeout_seconds": 30,
554
+ "enable_progress_monitoring": True,
555
+ "allow_partial_results": True
556
+ },
557
+ "simulation_steps": simulation.alternative_path
558
+ }
559
+
560
+ def _update_agent_state(self, agent_id: str, patch: CorrectionPatch):
561
+ """Update the state of an agent after patching."""
562
+ if agent_id not in self.agent_states:
563
+ self.agent_states[agent_id] = AgentState(
564
+ agent_id=agent_id,
565
+ status="running"
566
+ )
567
+
568
+ state = self.agent_states[agent_id]
569
+ state.status = "patched"
570
+ state.last_failure = patch.failure_analysis.failure
571
+
572
+ if patch.patch_id not in state.patches_applied:
573
+ state.patches_applied.append(patch.patch_id)
574
+
575
+ def get_patch_history(self, agent_id: Optional[str] = None) -> List[CorrectionPatch]:
576
+ """Get patch history, optionally filtered by agent_id."""
577
+ patches = list(self.patches.values())
578
+
579
+ if agent_id:
580
+ patches = [p for p in patches if p.agent_id == agent_id]
581
+
582
+ return sorted(patches, key=lambda p: p.applied_at or datetime.min, reverse=True)