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,394 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ """
5
+ Agent Hibernation - State-to-Disk Serialization
6
+
7
+ Feature: "Agent Hibernation (state-to-disk)"
8
+ Problem: Agents sitting idle in memory cost money (if hosted) or RAM.
9
+ Solution: Serialize the entire agent state (including caas pointer) to a JSON/Pickle file
10
+ and kill the process. Wake it up only when amb receives a message for it.
11
+ Result: Scale by Subtraction - Removes the need for "always-on" servers. Serverless Agents.
12
+
13
+ This module provides the infrastructure to hibernate idle agents by serializing
14
+ their complete state to disk and restoring them when needed.
15
+ """
16
+
17
+ from typing import Any, Dict, Optional, List
18
+ from dataclasses import dataclass, field, asdict
19
+ from datetime import datetime, timedelta
20
+ from enum import Enum
21
+ import json
22
+ import hmac
23
+ import hashlib
24
+ import os
25
+ import logging
26
+ from pathlib import Path
27
+
28
+
29
+ class HibernationFormat(Enum):
30
+ """Format for serializing agent state"""
31
+ JSON = "json"
32
+ PICKLE = "pickle"
33
+
34
+
35
+ class AgentState(Enum):
36
+ """State of an agent in the hibernation lifecycle"""
37
+ ACTIVE = "active"
38
+ HIBERNATING = "hibernating"
39
+ HIBERNATED = "hibernated"
40
+ WAKING = "waking"
41
+
42
+
43
+ @dataclass
44
+ class HibernatedAgentMetadata:
45
+ """Metadata about a hibernated agent"""
46
+ agent_id: str
47
+ session_id: str
48
+ hibernated_at: datetime
49
+ state_file_path: str
50
+ format: HibernationFormat
51
+ state_size_bytes: int
52
+ last_activity: datetime
53
+ context_pointer: Optional[str] = None # caas pointer
54
+ metadata: Dict[str, Any] = field(default_factory=dict)
55
+
56
+
57
+ @dataclass
58
+ class HibernationConfig:
59
+ """Configuration for agent hibernation"""
60
+ enabled: bool = True
61
+ idle_timeout_seconds: int = 300 # 5 minutes default
62
+ storage_path: str = "/tmp/agent_hibernation"
63
+ format: HibernationFormat = HibernationFormat.JSON
64
+ max_hibernated_agents: int = 1000
65
+ auto_cleanup_days: int = 7 # Clean up hibernated agents after 7 days
66
+ compress: bool = False
67
+
68
+
69
+ class HibernationManager:
70
+ """
71
+ Manages agent hibernation and wake-up operations.
72
+
73
+ This class handles:
74
+ - Serialization of complete agent state to disk
75
+ - Deserialization and restoration of agent state
76
+ - Tracking of hibernated agents
77
+ - Automatic cleanup of old hibernated states
78
+ """
79
+
80
+ def __init__(self, config: Optional[HibernationConfig] = None):
81
+ """
82
+ Initialize the hibernation manager.
83
+
84
+ Args:
85
+ config: Configuration for hibernation behavior
86
+ """
87
+ self.config = config or HibernationConfig()
88
+ self.logger = logging.getLogger("HibernationManager")
89
+
90
+ # Create storage directory if it doesn't exist
91
+ Path(self.config.storage_path).mkdir(parents=True, exist_ok=True)
92
+
93
+ # HMAC key for pickle integrity verification — generated per instance.
94
+ # In production, this should be persisted securely (e.g., Key Vault).
95
+ self._hmac_key = os.urandom(32)
96
+
97
+ # Create storage directory if it doesn't exist
98
+ Path(self.config.storage_path).mkdir(parents=True, exist_ok=True)
99
+
100
+ # Track hibernated agents
101
+ self.hibernated_agents: Dict[str, HibernatedAgentMetadata] = {}
102
+
103
+ # Track agent activity for idle detection
104
+ self.agent_activity: Dict[str, datetime] = {}
105
+
106
+ # Track agent states
107
+ self.agent_states: Dict[str, AgentState] = {}
108
+
109
+ self.logger.info(f"HibernationManager initialized with storage at {self.config.storage_path}")
110
+
111
+ def serialize_agent_state(
112
+ self,
113
+ agent_id: str,
114
+ agent_context: Any,
115
+ caas_pointer: Optional[str] = None,
116
+ additional_state: Optional[Dict[str, Any]] = None
117
+ ) -> Dict[str, Any]:
118
+ """
119
+ Serialize agent state to a dictionary.
120
+
121
+ Args:
122
+ agent_id: Unique identifier for the agent
123
+ agent_context: AgentContext object containing agent session data
124
+ caas_pointer: Optional pointer to context in caas (Context-as-a-Service)
125
+ additional_state: Optional additional state to serialize
126
+
127
+ Returns:
128
+ Dictionary containing serialized agent state
129
+ """
130
+ state = {
131
+ "agent_id": agent_id,
132
+ "session_id": agent_context.session_id,
133
+ "created_at": agent_context.created_at.isoformat(),
134
+ "permissions": {
135
+ str(k): v.value for k, v in agent_context.permissions.items()
136
+ },
137
+ "metadata": agent_context.metadata,
138
+ "caas_pointer": caas_pointer,
139
+ "hibernated_at": datetime.now().isoformat(),
140
+ "additional_state": additional_state or {}
141
+ }
142
+
143
+ return state
144
+
145
+ def deserialize_agent_state(self, state: Dict[str, Any]) -> Dict[str, Any]:
146
+ """
147
+ Deserialize agent state from a dictionary.
148
+
149
+ Args:
150
+ state: Dictionary containing serialized agent state
151
+
152
+ Returns:
153
+ Dictionary with deserialized state components
154
+ """
155
+ # Convert ISO format strings back to datetime
156
+ if "created_at" in state:
157
+ state["created_at"] = datetime.fromisoformat(state["created_at"])
158
+ if "hibernated_at" in state:
159
+ state["hibernated_at"] = datetime.fromisoformat(state["hibernated_at"])
160
+
161
+ return state
162
+
163
+ def hibernate_agent(
164
+ self,
165
+ agent_id: str,
166
+ agent_context: Any,
167
+ caas_pointer: Optional[str] = None,
168
+ additional_state: Optional[Dict[str, Any]] = None
169
+ ) -> HibernatedAgentMetadata:
170
+ """
171
+ Hibernate an agent by saving its state to disk.
172
+
173
+ Args:
174
+ agent_id: Unique identifier for the agent
175
+ agent_context: AgentContext object to serialize
176
+ caas_pointer: Optional pointer to context in caas
177
+ additional_state: Optional additional state to save
178
+
179
+ Returns:
180
+ Metadata about the hibernated agent
181
+ """
182
+ self.logger.info(f"Hibernating agent {agent_id}")
183
+
184
+ # Update agent state
185
+ self.agent_states[agent_id] = AgentState.HIBERNATING
186
+
187
+ # Serialize agent state
188
+ state = self.serialize_agent_state(agent_id, agent_context, caas_pointer, additional_state)
189
+
190
+ # Determine file path
191
+ file_name = f"{agent_id}_{agent_context.session_id}.{self.config.format.value}"
192
+ file_path = os.path.join(self.config.storage_path, file_name)
193
+
194
+ # Save to disk
195
+ try:
196
+ if self.config.format == HibernationFormat.JSON:
197
+ with open(file_path, 'w') as f:
198
+ json.dump(state, f, indent=2)
199
+ else: # PICKLE format — now uses JSON internally + HMAC signature
200
+ raw = json.dumps(state).encode('utf-8')
201
+ sig = hmac.new(self._hmac_key, raw, hashlib.sha256).hexdigest()
202
+ with open(file_path, 'wb') as f:
203
+ f.write(raw)
204
+ with open(file_path + ".sig", 'w', encoding='utf-8') as f:
205
+ f.write(sig)
206
+
207
+ # Get file size
208
+ state_size = os.path.getsize(file_path)
209
+
210
+ # Create metadata
211
+ metadata = HibernatedAgentMetadata(
212
+ agent_id=agent_id,
213
+ session_id=agent_context.session_id,
214
+ hibernated_at=datetime.now(),
215
+ state_file_path=file_path,
216
+ format=self.config.format,
217
+ state_size_bytes=state_size,
218
+ last_activity=self.agent_activity.get(agent_id, datetime.now()),
219
+ context_pointer=caas_pointer
220
+ )
221
+
222
+ # Track hibernated agent
223
+ self.hibernated_agents[agent_id] = metadata
224
+ self.agent_states[agent_id] = AgentState.HIBERNATED
225
+
226
+ self.logger.info(f"Agent {agent_id} hibernated successfully. State saved to {file_path} ({state_size} bytes)")
227
+
228
+ return metadata
229
+
230
+ except Exception as e:
231
+ self.logger.error(f"Failed to hibernate agent {agent_id}: {e}")
232
+ self.agent_states[agent_id] = AgentState.ACTIVE
233
+ raise
234
+
235
+ def wake_agent(self, agent_id: str) -> Dict[str, Any]:
236
+ """
237
+ Wake up a hibernated agent by restoring its state from disk.
238
+
239
+ Args:
240
+ agent_id: Unique identifier for the agent to wake
241
+
242
+ Returns:
243
+ Dictionary containing the restored agent state
244
+ """
245
+ if agent_id not in self.hibernated_agents:
246
+ raise ValueError(f"Agent {agent_id} is not hibernated")
247
+
248
+ self.logger.info(f"Waking agent {agent_id}")
249
+
250
+ # Update state
251
+ self.agent_states[agent_id] = AgentState.WAKING
252
+
253
+ metadata = self.hibernated_agents[agent_id]
254
+
255
+ try:
256
+ # Load state from disk
257
+ if metadata.format == HibernationFormat.JSON:
258
+ with open(metadata.state_file_path, 'r') as f:
259
+ state = json.load(f)
260
+ else: # PICKLE format — now uses JSON internally; verify HMAC before deserializing
261
+ sig_path = metadata.state_file_path + ".sig"
262
+ if not os.path.exists(sig_path):
263
+ raise ValueError(
264
+ f"Missing HMAC signature for {metadata.state_file_path} — "
265
+ "state file may have been tampered with"
266
+ )
267
+ with open(metadata.state_file_path, 'rb') as f:
268
+ raw = f.read()
269
+ with open(sig_path, 'r', encoding='utf-8') as f:
270
+ expected_sig = f.read().strip()
271
+ actual_sig = hmac.new(self._hmac_key, raw, hashlib.sha256).hexdigest()
272
+ if not hmac.compare_digest(actual_sig, expected_sig):
273
+ raise ValueError(
274
+ f"HMAC verification failed for {metadata.state_file_path} — "
275
+ "state file has been tampered with"
276
+ )
277
+ state = json.loads(raw.decode('utf-8'))
278
+
279
+ # Deserialize state
280
+ restored_state = self.deserialize_agent_state(state)
281
+
282
+ # Update tracking
283
+ self.agent_activity[agent_id] = datetime.now()
284
+ self.agent_states[agent_id] = AgentState.ACTIVE
285
+
286
+ # Remove from hibernated agents
287
+ del self.hibernated_agents[agent_id]
288
+
289
+ self.logger.info(f"Agent {agent_id} woken successfully")
290
+
291
+ return restored_state
292
+
293
+ except Exception as e:
294
+ self.logger.error(f"Failed to wake agent {agent_id}: {e}")
295
+ self.agent_states[agent_id] = AgentState.HIBERNATED
296
+ raise
297
+
298
+ def is_agent_hibernated(self, agent_id: str) -> bool:
299
+ """Check if an agent is currently hibernated"""
300
+ return agent_id in self.hibernated_agents
301
+
302
+ def get_hibernated_agents(self) -> List[HibernatedAgentMetadata]:
303
+ """Get list of all hibernated agents"""
304
+ return list(self.hibernated_agents.values())
305
+
306
+ def record_agent_activity(self, agent_id: str):
307
+ """Record activity for an agent (resets idle timer)"""
308
+ self.agent_activity[agent_id] = datetime.now()
309
+ if agent_id not in self.agent_states or self.agent_states[agent_id] == AgentState.HIBERNATED:
310
+ self.agent_states[agent_id] = AgentState.ACTIVE
311
+
312
+ def get_idle_agents(self, min_idle_seconds: Optional[int] = None) -> List[str]:
313
+ """
314
+ Get list of agent IDs that have been idle for the specified duration.
315
+
316
+ Args:
317
+ min_idle_seconds: Minimum idle time in seconds (uses config default if None)
318
+
319
+ Returns:
320
+ List of agent IDs that are idle
321
+ """
322
+ idle_threshold = min_idle_seconds or self.config.idle_timeout_seconds
323
+ now = datetime.now()
324
+ idle_agents = []
325
+
326
+ for agent_id, last_activity in self.agent_activity.items():
327
+ # Skip already hibernated agents
328
+ if self.is_agent_hibernated(agent_id):
329
+ continue
330
+
331
+ idle_time = (now - last_activity).total_seconds()
332
+ if idle_time >= idle_threshold:
333
+ idle_agents.append(agent_id)
334
+
335
+ return idle_agents
336
+
337
+ def cleanup_old_hibernated_agents(self, max_age_days: Optional[int] = None):
338
+ """
339
+ Clean up hibernated agents older than the specified age.
340
+
341
+ Args:
342
+ max_age_days: Maximum age in days (uses config default if None)
343
+ """
344
+ max_age = max_age_days or self.config.auto_cleanup_days
345
+ now = datetime.now()
346
+ cleanup_threshold = timedelta(days=max_age)
347
+
348
+ agents_to_cleanup = []
349
+ for agent_id, metadata in self.hibernated_agents.items():
350
+ age = now - metadata.hibernated_at
351
+ if age > cleanup_threshold:
352
+ agents_to_cleanup.append(agent_id)
353
+
354
+ for agent_id in agents_to_cleanup:
355
+ self._cleanup_hibernated_agent(agent_id)
356
+
357
+ def _cleanup_hibernated_agent(self, agent_id: str):
358
+ """Remove hibernated agent and delete its state file"""
359
+ if agent_id not in self.hibernated_agents:
360
+ return
361
+
362
+ metadata = self.hibernated_agents[agent_id]
363
+
364
+ try:
365
+ # Delete state file
366
+ if os.path.exists(metadata.state_file_path):
367
+ os.remove(metadata.state_file_path)
368
+
369
+ # Remove from tracking
370
+ del self.hibernated_agents[agent_id]
371
+ if agent_id in self.agent_states:
372
+ del self.agent_states[agent_id]
373
+ if agent_id in self.agent_activity:
374
+ del self.agent_activity[agent_id]
375
+
376
+ self.logger.info(f"Cleaned up hibernated agent {agent_id}")
377
+
378
+ except Exception as e:
379
+ self.logger.error(f"Failed to cleanup hibernated agent {agent_id}: {e}")
380
+
381
+ def get_statistics(self) -> Dict[str, Any]:
382
+ """Get statistics about hibernation"""
383
+ total_hibernated = len(self.hibernated_agents)
384
+ total_size = sum(m.state_size_bytes for m in self.hibernated_agents.values())
385
+
386
+ return {
387
+ "total_hibernated_agents": total_hibernated,
388
+ "total_state_size_bytes": total_size,
389
+ "total_state_size_mb": total_size / (1024 * 1024),
390
+ "active_agents": len([s for s in self.agent_states.values() if s == AgentState.ACTIVE]),
391
+ "storage_path": self.config.storage_path,
392
+ "format": self.config.format.value,
393
+ "idle_timeout_seconds": self.config.idle_timeout_seconds
394
+ }