@agentikos/omega-os 0.1.0 → 0.19.5

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 (379) hide show
  1. package/README.md +56 -14
  2. package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
  3. package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
  4. package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
  5. package/bootstrap/lib/claude-code-settings.py +176 -0
  6. package/bootstrap/lib/common.sh +457 -1
  7. package/bootstrap/lib/llm-clis.py +341 -0
  8. package/bootstrap/lib/manifest-helpers.py +384 -0
  9. package/bootstrap/lib/steps.sh +1000 -26
  10. package/bootstrap/manifest.example.yaml +93 -2
  11. package/bootstrap/templates/aisb/CLAUDE.md +305 -0
  12. package/bootstrap/templates/aisb/architect.md +204 -0
  13. package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
  14. package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
  15. package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
  16. package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
  17. package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
  18. package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
  19. package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
  20. package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
  21. package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
  22. package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
  23. package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
  24. package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
  25. package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
  26. package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
  27. package/bootstrap/templates/aisb/construct.md +135 -0
  28. package/bootstrap/templates/aisb/keymaker.md +227 -0
  29. package/bootstrap/templates/aisb/link.md +170 -0
  30. package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
  31. package/bootstrap/templates/aisb/merovingian.md +159 -0
  32. package/bootstrap/templates/aisb/morpheus.md +243 -0
  33. package/bootstrap/templates/aisb/neo.md +147 -0
  34. package/bootstrap/templates/aisb/niobe.md +197 -0
  35. package/bootstrap/templates/aisb/oracle.md +244 -0
  36. package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
  37. package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
  38. package/bootstrap/templates/aisb/pythia.md +153 -0
  39. package/bootstrap/templates/aisb/seraph.md +315 -0
  40. package/bootstrap/templates/aisb/smith.md +202 -0
  41. package/bootstrap/templates/aisb/zion.md +172 -0
  42. package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
  43. package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
  44. package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
  45. package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
  46. package/docs/AUDITS.md +85 -0
  47. package/docs/COMPLETION-PLAN.md +48 -0
  48. package/docs/GAP-ANALYSIS.md +214 -0
  49. package/docs/INSTALL.md +47 -9
  50. package/docs/MCP-AND-PLUGINS.md +31 -4
  51. package/docs/SIMULATION.md +171 -0
  52. package/docs/simulate.sh +211 -0
  53. package/install.sh +164 -17
  54. package/omega/Agentik_Engine/README.md +27 -10
  55. package/omega/Agentik_Engine/omega_engine/__init__.py +212 -2
  56. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  57. package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
  58. package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
  59. package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
  60. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
  61. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
  62. package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
  63. package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
  64. package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
  65. package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
  66. package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
  67. package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
  68. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  69. package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
  70. package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
  71. package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
  72. package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
  73. package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
  74. package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
  75. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
  76. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
  77. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
  78. package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
  79. package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
  80. package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
  81. package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
  82. package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
  83. package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
  84. package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
  85. package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
  86. package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
  87. package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
  88. package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
  89. package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
  90. package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
  91. package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
  92. package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
  93. package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
  94. package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
  95. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
  96. package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
  97. package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
  98. package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
  99. package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
  100. package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
  101. package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
  102. package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
  103. package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
  104. package/omega/Agentik_Engine/omega_engine/account.py +502 -0
  105. package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
  106. package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
  107. package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
  108. package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
  109. package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
  110. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
  111. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
  112. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
  113. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
  114. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
  115. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
  116. package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
  117. package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
  118. package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
  119. package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
  120. package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
  121. package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
  122. package/omega/Agentik_Engine/omega_engine/autonomous.py +538 -0
  123. package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
  124. package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
  125. package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
  126. package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
  127. package/omega/Agentik_Engine/omega_engine/cli.py +4564 -56
  128. package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
  129. package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
  130. package/omega/Agentik_Engine/omega_engine/daemons/__init__.py +14 -0
  131. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
  132. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
  133. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
  134. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
  135. package/omega/Agentik_Engine/omega_engine/daemons/autonomous.py +56 -0
  136. package/omega/Agentik_Engine/omega_engine/daemons/engine.py +236 -0
  137. package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +315 -0
  138. package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
  139. package/omega/Agentik_Engine/omega_engine/educators/__init__.py +51 -0
  140. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
  141. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
  142. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
  143. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
  144. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
  145. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
  146. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
  147. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
  148. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
  149. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
  150. package/omega/Agentik_Engine/omega_engine/educators/artifact.py +65 -0
  151. package/omega/Agentik_Engine/omega_engine/educators/automation.py +76 -0
  152. package/omega/Agentik_Engine/omega_engine/educators/base.py +327 -0
  153. package/omega/Agentik_Engine/omega_engine/educators/claudecode.py +71 -0
  154. package/omega/Agentik_Engine/omega_engine/educators/connection.py +75 -0
  155. package/omega/Agentik_Engine/omega_engine/educators/coworker.py +68 -0
  156. package/omega/Agentik_Engine/omega_engine/educators/loop.py +82 -0
  157. package/omega/Agentik_Engine/omega_engine/educators/prompt.py +68 -0
  158. package/omega/Agentik_Engine/omega_engine/educators/skill.py +69 -0
  159. package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
  160. package/omega/Agentik_Engine/omega_engine/executor.py +195 -16
  161. package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
  162. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
  163. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
  164. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
  165. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
  166. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
  167. package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
  168. package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
  169. package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
  170. package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
  171. package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
  172. package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
  173. package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
  174. package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
  175. package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
  176. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
  177. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
  178. package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
  179. package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
  180. package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
  181. package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
  182. package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
  183. package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
  184. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
  185. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
  186. package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
  187. package/omega/Agentik_Engine/omega_engine/mission.py +29 -14
  188. package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
  189. package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
  190. package/omega/Agentik_Engine/omega_engine/provider.py +408 -13
  191. package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
  192. package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
  193. package/omega/Agentik_Engine/omega_engine/rag/__init__.py +21 -0
  194. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
  195. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
  196. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
  197. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
  198. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
  199. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
  200. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
  201. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
  202. package/omega/Agentik_Engine/omega_engine/rag/agentic.py +83 -0
  203. package/omega/Agentik_Engine/omega_engine/rag/base.py +42 -0
  204. package/omega/Agentik_Engine/omega_engine/rag/corrective.py +119 -0
  205. package/omega/Agentik_Engine/omega_engine/rag/graph.py +169 -0
  206. package/omega/Agentik_Engine/omega_engine/rag/hybrid.py +205 -0
  207. package/omega/Agentik_Engine/omega_engine/rag/multimodal.py +136 -0
  208. package/omega/Agentik_Engine/omega_engine/rag/router.py +110 -0
  209. package/omega/Agentik_Engine/omega_engine/reducer.py +21 -3
  210. package/omega/Agentik_Engine/omega_engine/router.py +28 -0
  211. package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
  212. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
  213. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
  214. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
  215. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
  216. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
  217. package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
  218. package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
  219. package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
  220. package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
  221. package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
  222. package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
  223. package/omega/Agentik_Engine/omega_engine/store.py +132 -25
  224. package/omega/Agentik_Engine/omega_engine/sync.py +445 -0
  225. package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
  226. package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
  227. package/omega/Agentik_Engine/omega_engine/tools.py +272 -0
  228. package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
  229. package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
  230. package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
  231. package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
  232. package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
  233. package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
  234. package/omega/Agentik_Engine/pyproject.toml +1 -1
  235. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
  236. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
  237. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
  238. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
  239. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
  240. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
  241. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
  242. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
  243. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
  244. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
  245. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
  246. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
  247. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
  248. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
  249. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
  250. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
  251. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
  252. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
  253. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
  254. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
  255. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
  256. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
  257. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
  258. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
  259. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
  260. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
  261. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
  262. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
  263. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
  264. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
  265. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
  266. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
  267. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
  268. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
  269. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
  270. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
  271. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
  272. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
  273. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
  274. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
  275. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
  276. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
  277. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
  278. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
  279. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
  280. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
  281. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
  282. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
  283. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
  284. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
  285. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
  286. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
  287. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
  288. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
  289. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
  290. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
  291. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
  292. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
  293. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
  294. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
  295. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
  296. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
  297. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
  298. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
  299. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
  300. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
  301. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
  302. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
  303. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
  304. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
  305. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
  306. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
  307. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
  308. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
  309. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
  310. package/omega/Agentik_Engine/tests/test_account.py +338 -0
  311. package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
  312. package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
  313. package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
  314. package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
  315. package/omega/Agentik_Engine/tests/test_autonomous.py +361 -0
  316. package/omega/Agentik_Engine/tests/test_educators.py +233 -0
  317. package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
  318. package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
  319. package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
  320. package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
  321. package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
  322. package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
  323. package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
  324. package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
  325. package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
  326. package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
  327. package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
  328. package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
  329. package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
  330. package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
  331. package/omega/Agentik_Engine/tests/test_rag.py +287 -0
  332. package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
  333. package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
  334. package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
  335. package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
  336. package/omega/Agentik_Engine/tests/test_snapshot_partial.py +172 -0
  337. package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
  338. package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
  339. package/omega/Agentik_Engine/tests/test_tools_and_sync.py +312 -0
  340. package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
  341. package/omega/Agentik_Engine/tests/test_vault.py +173 -0
  342. package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
  343. package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
  344. package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
  345. package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
  346. package/omega/Agentik_Runtime/audits.db +0 -0
  347. package/omega/Agentik_SSOT/VERSION +1 -1
  348. package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
  349. package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
  350. package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
  351. package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
  352. package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
  353. package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
  354. package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
  355. package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
  356. package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
  357. package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
  358. package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
  359. package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
  360. package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
  361. package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
  362. package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
  363. package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
  364. package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
  365. package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
  366. package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
  367. package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
  368. package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
  369. package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
  370. package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
  371. package/omega/Agentik_SSOT/skills/rag-route.md +82 -0
  372. package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
  373. package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
  374. package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
  375. package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
  376. package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
  377. package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
  378. package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
  379. package/package.json +2 -2
@@ -0,0 +1,538 @@
1
+ """Autonomous-agent supervisor — first-class persistent nodes of the engine.
2
+
3
+ An autonomous agent is a `Task` with `lifecycle: persistent` and a `Trigger`.
4
+ Charters live as YAML files in `Agentik_Orchestration/autonomous/`. The
5
+ supervisor loads every charter, schedules each agent, and — when a trigger
6
+ fires — opens a mission via the same `run_mission()` pipeline the rest of the
7
+ engine uses. The autonomous agent inherits verified completion and the deadman
8
+ for free; it is *our* architecture, configured.
9
+
10
+ Four trigger types are honoured:
11
+
12
+ * ``cron`` -- a 5-field schedule (`m h d M w`). Numeric, ``*``, ``*/N``,
13
+ comma lists. The supervisor's main loop polls due agents.
14
+ * ``event`` -- subscribed to the event bus; fires when an event matches the
15
+ configured ``event_type`` pattern.
16
+ * ``webhook`` -- the supervisor exposes :meth:`wake_webhook` — an external
17
+ HTTP shim invokes it when a request arrives at the agent's
18
+ webhook_path.
19
+ * ``channel`` -- the Telegram daemon calls :meth:`on_channel_message` for
20
+ messages on the agent's bound topic.
21
+
22
+ The supervisor is deliberately stdlib-only: it can run on a fresh VPS with no
23
+ extra Python deps beyond pyyaml (already an engine dep).
24
+ """
25
+ from __future__ import annotations
26
+
27
+ import logging
28
+ import os
29
+ import signal
30
+ import threading
31
+ import time
32
+ from dataclasses import dataclass, field
33
+ from pathlib import Path
34
+ from typing import Any, Callable, Optional
35
+
36
+ import yaml
37
+
38
+ from omega_engine.events import Event
39
+ from omega_engine.task import Lifecycle
40
+
41
+ logger = logging.getLogger("omega.autonomous")
42
+
43
+
44
+ # ─────────────────────────────────────────────────────────────────────────────
45
+ # Charter
46
+ # ─────────────────────────────────────────────────────────────────────────────
47
+
48
+ @dataclass
49
+ class Charter:
50
+ """A persistent agent's contract — one YAML file = one charter.
51
+
52
+ The dataclass mirrors the fields documented in
53
+ ``docs/AUTONOMOUS-AGENTS.md`` §3. Missing optional fields fall back to the
54
+ same defaults the example charters use.
55
+ """
56
+
57
+ id: str
58
+ role: str
59
+ trigger_type: str # "cron" | "event" | "webhook" | "channel"
60
+ trigger_config: dict[str, Any] = field(default_factory=dict)
61
+ charter: str = ""
62
+ lifecycle: str = Lifecycle.PERSISTENT.value
63
+ channel_topic: Optional[int] = None
64
+ max_iterations: int = 5
65
+ heartbeat_interval_s: int = 300
66
+ provider: Optional[str] = None
67
+ allowed_skills: list[str] = field(default_factory=list)
68
+ allowed_mcp: list[str] = field(default_factory=list)
69
+ allowed_topologies: list[str] = field(default_factory=list)
70
+ may_spawn_missions: bool = True
71
+ may_ship: bool = False
72
+ source_file: Optional[str] = None # filled by load_charters for diagnostics
73
+
74
+
75
+ def _is_charter_mapping(value: Any) -> bool:
76
+ """A YAML top-level mapping is a charter iff it has id + role + trigger.
77
+
78
+ This is what lets a single file hold both worked examples and the template
79
+ block (which lacks an ``id``/``role`` — the template is a placeholder, not
80
+ a charter).
81
+ """
82
+ if not isinstance(value, dict):
83
+ return False
84
+ if not value.get("id") or not value.get("role"):
85
+ return False
86
+ trig = value.get("trigger")
87
+ if not isinstance(trig, dict) or not trig.get("type"):
88
+ return False
89
+ return True
90
+
91
+
92
+ def _charter_from_mapping(data: dict[str, Any], *,
93
+ source_file: str | None = None) -> Charter:
94
+ trig = data.get("trigger") or {}
95
+ chan = data.get("channel") or {}
96
+ budget = data.get("budget") or {}
97
+ allowed = data.get("allowed") or {}
98
+ guard = data.get("guardrails") or {}
99
+ return Charter(
100
+ id=str(data["id"]),
101
+ role=str(data["role"]),
102
+ trigger_type=str(trig.get("type", "")),
103
+ trigger_config=dict(trig.get("config") or {}),
104
+ charter=str(data.get("charter", "")).strip(),
105
+ lifecycle=str(data.get("lifecycle", Lifecycle.PERSISTENT.value)),
106
+ channel_topic=chan.get("telegram_topic"),
107
+ max_iterations=int(budget.get("max_iterations", 5)),
108
+ heartbeat_interval_s=int(budget.get("heartbeat_interval_s", 300)),
109
+ provider=data.get("provider"),
110
+ allowed_skills=list(allowed.get("skills") or []),
111
+ allowed_mcp=list(allowed.get("mcp") or []),
112
+ allowed_topologies=list(allowed.get("topologies") or []),
113
+ may_spawn_missions=bool(guard.get("may_spawn_missions", True)),
114
+ may_ship=bool(guard.get("may_ship", False)),
115
+ source_file=source_file,
116
+ )
117
+
118
+
119
+ def load_charters(directory: str | Path) -> list[Charter]:
120
+ """Load every charter under ``directory`` — recursively scans ``*.yaml``.
121
+
122
+ A YAML file may hold ONE charter at top level OR a mapping-of-mappings where
123
+ each value is a charter (the example file uses the second form). Entries
124
+ that do not look like a charter (e.g. the ``template:`` placeholder block in
125
+ the example) are silently skipped — they're documentation, not agents.
126
+ """
127
+ base = Path(directory)
128
+ out: list[Charter] = []
129
+ if not base.is_dir():
130
+ return out
131
+
132
+ for path in sorted(base.rglob("*.yaml")):
133
+ try:
134
+ data = yaml.safe_load(path.read_text()) or {}
135
+ except yaml.YAMLError as exc:
136
+ logger.warning("autonomous: cannot parse %s: %s", path, exc)
137
+ continue
138
+
139
+ if not isinstance(data, dict):
140
+ continue
141
+
142
+ # case 1: the whole file IS a single charter
143
+ if _is_charter_mapping(data):
144
+ out.append(_charter_from_mapping(data, source_file=str(path)))
145
+ continue
146
+
147
+ # case 2: mapping of named charters (the example file). Each value that
148
+ # looks like a charter is loaded; everything else (template, comments)
149
+ # is skipped.
150
+ for key, value in data.items():
151
+ if key == "template":
152
+ # the template block is explicitly documentation
153
+ continue
154
+ if _is_charter_mapping(value):
155
+ out.append(_charter_from_mapping(value, source_file=str(path)))
156
+
157
+ return out
158
+
159
+
160
+ # ─────────────────────────────────────────────────────────────────────────────
161
+ # Minimal cron parser
162
+ # ─────────────────────────────────────────────────────────────────────────────
163
+
164
+ # Field order: minute hour day-of-month month day-of-week
165
+ # Ranges: m=0-59 h=0-23 dom=1-31 mo=1-12 dow=0-6 (Sun=0)
166
+ _FIELD_RANGES: list[tuple[int, int]] = [
167
+ (0, 59), (0, 23), (1, 31), (1, 12), (0, 6),
168
+ ]
169
+
170
+
171
+ def _parse_field(spec: str, lo: int, hi: int) -> set[int]:
172
+ """Parse one cron field into the set of integers it matches.
173
+
174
+ Supported forms (covers every form used by the example charters):
175
+ *
176
+ N
177
+ a,b,c
178
+ */N
179
+ a-b (range — same syntax as standard cron)
180
+ """
181
+ spec = spec.strip()
182
+ if spec == "*":
183
+ return set(range(lo, hi + 1))
184
+
185
+ if spec.startswith("*/"):
186
+ step = int(spec[2:])
187
+ if step <= 0:
188
+ raise ValueError(f"step must be positive: {spec}")
189
+ return {n for n in range(lo, hi + 1) if (n - lo) % step == 0}
190
+
191
+ out: set[int] = set()
192
+ for piece in spec.split(","):
193
+ piece = piece.strip()
194
+ if "-" in piece:
195
+ a, b = piece.split("-", 1)
196
+ ai, bi = int(a), int(b)
197
+ if ai > bi or ai < lo or bi > hi:
198
+ raise ValueError(f"bad range {piece} for field [{lo},{hi}]")
199
+ out.update(range(ai, bi + 1))
200
+ else:
201
+ n = int(piece)
202
+ if n < lo or n > hi:
203
+ raise ValueError(f"value {n} outside [{lo},{hi}]")
204
+ out.add(n)
205
+ return out
206
+
207
+
208
+ def parse_cron(spec: str) -> tuple[set[int], ...]:
209
+ """Parse a 5-field cron spec into 5 sets — one per field."""
210
+ parts = spec.split()
211
+ if len(parts) != 5:
212
+ raise ValueError(
213
+ f"cron spec must have 5 fields, got {len(parts)}: {spec!r}"
214
+ )
215
+ return tuple(
216
+ _parse_field(parts[i], *_FIELD_RANGES[i]) for i in range(5)
217
+ )
218
+
219
+
220
+ def next_fire(spec: str, now: float) -> float:
221
+ """Return the next epoch second at or after ``now`` when ``spec`` fires.
222
+
223
+ Naive but correct: walk forward minute-by-minute. The example charters fire
224
+ at most a handful of times a day; the search is always bounded by the
225
+ longest legal gap (year + 1 day for safety). For the spec ``*/5 * * * *``
226
+ this returns now+~5min.
227
+ """
228
+ minute, hour, dom, month, dow = parse_cron(spec)
229
+ # round up to next minute boundary
230
+ t = time.localtime(now)
231
+ candidate = time.mktime((
232
+ t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, 0,
233
+ 0, 0, -1,
234
+ )) + 60 # next minute (drop seconds)
235
+
236
+ # 5 years bounded search — way past any reasonable schedule
237
+ cutoff = candidate + 366 * 24 * 60 * 60 * 5
238
+ while candidate < cutoff:
239
+ ct = time.localtime(candidate)
240
+ # cron weekday: Sun=0..Sat=6; struct_tm tm_wday: Mon=0..Sun=6
241
+ c_dow = (ct.tm_wday + 1) % 7
242
+ if (ct.tm_min in minute
243
+ and ct.tm_hour in hour
244
+ and ct.tm_mday in dom
245
+ and ct.tm_mon in month
246
+ and c_dow in dow):
247
+ return candidate
248
+ candidate += 60
249
+ raise RuntimeError(f"no cron fire within 5 years for {spec!r}")
250
+
251
+
252
+ # ─────────────────────────────────────────────────────────────────────────────
253
+ # Supervisor
254
+ # ─────────────────────────────────────────────────────────────────────────────
255
+
256
+ @dataclass
257
+ class _Schedule:
258
+ """Per-charter scheduler bookkeeping. Only used internally."""
259
+
260
+ charter: Charter
261
+ next_fire_at: Optional[float] = None # cron only
262
+ last_run_at: Optional[float] = None
263
+ runs: int = 0
264
+ errors: int = 0
265
+ last_error: Optional[str] = None
266
+
267
+
268
+ # default runner type — what fires when a trigger trips
269
+ MissionRunner = Callable[..., Any]
270
+
271
+
272
+ def _default_runner(*, intent: str,
273
+ omega_home: str | Path | None,
274
+ topic_id: int | None,
275
+ telegram: Any | None,
276
+ charter: Charter) -> Any:
277
+ """The production runner — delegates to :func:`run_mission` lazily.
278
+
279
+ Imported lazily so unit tests can build a supervisor without dragging the
280
+ full executor stack into the test fixture.
281
+ """
282
+ from omega_engine.mission import run_mission
283
+
284
+ return run_mission(
285
+ intent=intent,
286
+ omega_home=omega_home,
287
+ topic_id=topic_id,
288
+ telegram=telegram,
289
+ )
290
+
291
+
292
+ class AutonomousSupervisor:
293
+ """Loads charters, schedules them, runs forever.
294
+
295
+ The supervisor is deliberately single-threaded: it polls its schedule on a
296
+ tick, dispatches due missions synchronously, and surfaces any per-charter
297
+ failure as a logged error — never as a process exit. One bad charter cannot
298
+ take the whole supervisor down.
299
+ """
300
+
301
+ def __init__(
302
+ self,
303
+ charters: list[Charter],
304
+ *,
305
+ omega_home: str | Path | None = None,
306
+ telegram: Any | None = None,
307
+ bus: Any | None = None,
308
+ runner: MissionRunner | None = None,
309
+ tick_seconds: float = 5.0,
310
+ ) -> None:
311
+ self._omega_home = omega_home
312
+ self._telegram = telegram
313
+ self._bus = bus
314
+ self._runner: MissionRunner = runner or _default_runner
315
+ self._tick = max(0.5, float(tick_seconds))
316
+ self._schedules: dict[str, _Schedule] = {
317
+ c.id: _Schedule(c) for c in charters
318
+ }
319
+ self._stop = threading.Event()
320
+ self._lock = threading.Lock()
321
+ # event-triggered agents register a bus subscription on .run()
322
+ # webhook + channel triggers are awakened by external callers
323
+ self._init_cron_schedules()
324
+ if bus is not None:
325
+ self._wire_event_subscribers()
326
+
327
+ # -- public surface ------------------------------------------------------
328
+
329
+ def charters(self) -> list[Charter]:
330
+ with self._lock:
331
+ return [s.charter for s in self._schedules.values()]
332
+
333
+ def stats(self) -> dict[str, dict[str, Any]]:
334
+ """For ``omega status`` / diagnostics."""
335
+ with self._lock:
336
+ return {
337
+ cid: {
338
+ "trigger": s.charter.trigger_type,
339
+ "next_fire_at": s.next_fire_at,
340
+ "last_run_at": s.last_run_at,
341
+ "runs": s.runs,
342
+ "errors": s.errors,
343
+ "last_error": s.last_error,
344
+ }
345
+ for cid, s in self._schedules.items()
346
+ }
347
+
348
+ def stop(self) -> None:
349
+ """Request a graceful shutdown. ``run()`` returns on the next tick."""
350
+ self._stop.set()
351
+
352
+ def run(self) -> None:
353
+ """Main loop. Returns only when :meth:`stop` is called or SIGTERM/SIGINT
354
+ is received. Crashes inside a single charter never escape this loop."""
355
+ # one-time SIGTERM/SIGINT wiring — only if we're on the main thread
356
+ # (so the daemon CLI installs them; tests can drive run() differently).
357
+ try:
358
+ signal.signal(signal.SIGTERM, lambda *_: self.stop())
359
+ signal.signal(signal.SIGINT, lambda *_: self.stop())
360
+ except ValueError:
361
+ # not on the main thread — caller handles signals
362
+ pass
363
+
364
+ logger.info("autonomous supervisor: %d charter(s) active",
365
+ len(self._schedules))
366
+ while not self._stop.is_set():
367
+ self._tick_once()
368
+ self._stop.wait(self._tick)
369
+ logger.info("autonomous supervisor: stopping cleanly")
370
+
371
+ # explicit single-tick variant — used by tests to step the loop
372
+ def tick(self, now: float | None = None) -> list[str]:
373
+ """Run one schedule pass; return the charter ids that fired this tick."""
374
+ return self._tick_once(now=now)
375
+
376
+ # -- trigger entry points ------------------------------------------------
377
+
378
+ def on_channel_message(self, topic_id: int, text: str) -> list[str]:
379
+ """Wake every charter bound to ``topic_id`` (channel trigger).
380
+
381
+ The Telegram daemon calls this for every inbound message it sees. The
382
+ text becomes the mission intent — the charter's role + channel binding
383
+ is what makes it an autonomous-agent action and not a one-shot call.
384
+ """
385
+ fired: list[str] = []
386
+ for sched in self._schedules.values():
387
+ c = sched.charter
388
+ if c.trigger_type != "channel":
389
+ continue
390
+ cfg_topic = c.trigger_config.get("telegram_topic", c.channel_topic)
391
+ if cfg_topic is None or int(cfg_topic) != int(topic_id):
392
+ continue
393
+ self._fire(sched, intent=text)
394
+ fired.append(c.id)
395
+ return fired
396
+
397
+ def wake_webhook(self, path: str, payload: dict[str, Any] | None = None
398
+ ) -> list[str]:
399
+ """Wake every charter whose webhook trigger matches ``path``.
400
+
401
+ The supervisor does NOT itself bind a port — an external HTTP shim is
402
+ responsible for that. The shim calls this method on a hit; one charter
403
+ ↔ one path (matched on ``webhook_path`` in its trigger config).
404
+ """
405
+ payload = payload or {}
406
+ fired: list[str] = []
407
+ for sched in self._schedules.values():
408
+ c = sched.charter
409
+ if c.trigger_type != "webhook":
410
+ continue
411
+ wp = c.trigger_config.get("webhook_path")
412
+ if not wp or wp != path:
413
+ continue
414
+ intent = payload.get("intent") or f"{c.role}: webhook fired ({path})"
415
+ self._fire(sched, intent=intent, extra_context={"payload": payload})
416
+ fired.append(c.id)
417
+ return fired
418
+
419
+ # -- internals -----------------------------------------------------------
420
+
421
+ def _init_cron_schedules(self) -> None:
422
+ now = time.time()
423
+ for sched in self._schedules.values():
424
+ if sched.charter.trigger_type != "cron":
425
+ continue
426
+ spec = sched.charter.trigger_config.get("schedule")
427
+ if not spec:
428
+ logger.warning("autonomous: charter %s has cron trigger but no "
429
+ "schedule — skipping", sched.charter.id)
430
+ continue
431
+ try:
432
+ sched.next_fire_at = next_fire(spec, now)
433
+ except (ValueError, RuntimeError) as exc:
434
+ sched.last_error = f"cron parse: {exc}"
435
+ sched.errors += 1
436
+ logger.warning("autonomous: charter %s has bad cron %r: %s",
437
+ sched.charter.id, spec, exc)
438
+
439
+ def _wire_event_subscribers(self) -> None:
440
+ """Hook the engine's event bus for charters with an event trigger."""
441
+ for sched in self._schedules.values():
442
+ c = sched.charter
443
+ if c.trigger_type != "event":
444
+ continue
445
+ pattern = c.trigger_config.get("event_type", "")
446
+ if not pattern:
447
+ continue
448
+ self._bus.subscribe(self._make_event_handler(sched, pattern))
449
+
450
+ def _make_event_handler(self, sched: _Schedule, pattern: str
451
+ ) -> Callable[[Event], None]:
452
+ def handler(event: Event) -> None:
453
+ etype = event.type.value if hasattr(event.type, "value") else str(event.type)
454
+ # support exact match and a trailing wildcard (``task.*``)
455
+ if pattern.endswith("*"):
456
+ if not etype.startswith(pattern[:-1]):
457
+ return
458
+ elif etype != pattern:
459
+ return
460
+ intent = f"{sched.charter.role}: event {etype} on {event.task_id}"
461
+ self._fire(sched, intent=intent,
462
+ extra_context={"event_task_id": event.task_id,
463
+ "event_type": etype,
464
+ "event_payload": event.payload})
465
+ return handler
466
+
467
+ def _tick_once(self, now: float | None = None) -> list[str]:
468
+ now = now if now is not None else time.time()
469
+ fired: list[str] = []
470
+ with self._lock:
471
+ scheds = list(self._schedules.values())
472
+ for sched in scheds:
473
+ if sched.charter.trigger_type != "cron":
474
+ continue
475
+ if sched.next_fire_at is None:
476
+ continue
477
+ if now >= sched.next_fire_at:
478
+ spec = sched.charter.trigger_config.get("schedule", "")
479
+ intent = (f"{sched.charter.role}: cron tick "
480
+ f"({spec}) — {time.strftime('%Y-%m-%d %H:%M')}")
481
+ self._fire(sched, intent=intent,
482
+ extra_context={"cron_schedule": spec, "fired_at": now})
483
+ fired.append(sched.charter.id)
484
+ # reschedule for next fire
485
+ try:
486
+ sched.next_fire_at = next_fire(spec, now + 60)
487
+ except (ValueError, RuntimeError) as exc:
488
+ sched.last_error = f"reschedule: {exc}"
489
+ sched.errors += 1
490
+ sched.next_fire_at = None
491
+ return fired
492
+
493
+ def _fire(self, sched: _Schedule, *, intent: str,
494
+ extra_context: dict[str, Any] | None = None) -> None:
495
+ """Invoke the runner once; absorb every exception per charter."""
496
+ c = sched.charter
497
+ sched.runs += 1
498
+ sched.last_run_at = time.time()
499
+ logger.info("autonomous: firing %s (%s) — intent=%r",
500
+ c.id, c.trigger_type, intent[:120])
501
+ try:
502
+ self._runner(
503
+ intent=intent,
504
+ omega_home=self._omega_home,
505
+ topic_id=c.channel_topic,
506
+ telegram=self._telegram,
507
+ charter=c,
508
+ )
509
+ except Exception as exc: # noqa: BLE001 — never let one bad charter kill us
510
+ sched.errors += 1
511
+ sched.last_error = f"{type(exc).__name__}: {exc}"
512
+ logger.exception("autonomous: charter %s crashed during fire", c.id)
513
+
514
+
515
+ # ─────────────────────────────────────────────────────────────────────────────
516
+ # Convenience — build a supervisor straight from OMEGA_HOME
517
+ # ─────────────────────────────────────────────────────────────────────────────
518
+
519
+ def build_supervisor_from_home(
520
+ omega_home: str | Path | None = None,
521
+ *,
522
+ telegram: Any | None = None,
523
+ bus: Any | None = None,
524
+ runner: MissionRunner | None = None,
525
+ ) -> AutonomousSupervisor:
526
+ """Discover charters in ``$OMEGA_HOME/Agentik_Orchestration/autonomous/`` and
527
+ return a ready-to-run supervisor."""
528
+ home = Path(omega_home or os.environ.get(
529
+ "OMEGA_HOME", str(Path.home() / "Omega")))
530
+ charter_dir = home / "Agentik_Orchestration" / "autonomous"
531
+ charters = load_charters(charter_dir)
532
+ return AutonomousSupervisor(
533
+ charters,
534
+ omega_home=home,
535
+ telegram=telegram,
536
+ bus=bus,
537
+ runner=runner,
538
+ )