@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,363 @@
1
+ """Tests for omega_engine.managed_agent — Anthropic Managed Agents wrapper.
2
+
3
+ Strategy: mock urllib.request.urlopen at the boundary so we exercise the
4
+ real serialization, header injection, error handling, SSE stream parser,
5
+ cache, and Provider integration without ever hitting the network.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import io
10
+ import json
11
+ import os
12
+ import sys
13
+ import tempfile
14
+ import unittest
15
+ from pathlib import Path
16
+ from unittest import mock
17
+
18
+
19
+ HERE = Path(__file__).resolve().parent
20
+ sys.path.insert(0, str(HERE.parent))
21
+
22
+ from omega_engine import managed_agent as MA # noqa: E402
23
+
24
+
25
+ # ---------------------------------------------------------------------------
26
+ # Fake urllib helpers
27
+ # ---------------------------------------------------------------------------
28
+
29
+
30
+ class _FakeResponse:
31
+ """Minimal stand-in for the object returned by urlopen()."""
32
+
33
+ def __init__(self, body: bytes, status: int = 200):
34
+ self._buf = io.BytesIO(body)
35
+ self.status = status
36
+
37
+ def read(self) -> bytes:
38
+ return self._buf.read()
39
+
40
+ def __iter__(self):
41
+ # Yield line by line (with trailing \n) — matches what SSE does.
42
+ self._buf.seek(0)
43
+ for raw in self._buf:
44
+ yield raw
45
+
46
+ def __enter__(self):
47
+ return self
48
+
49
+ def __exit__(self, *a):
50
+ return False
51
+
52
+ def close(self):
53
+ self._buf.close()
54
+
55
+
56
+ def _json_response(payload: dict) -> _FakeResponse:
57
+ return _FakeResponse(json.dumps(payload).encode("utf-8"))
58
+
59
+
60
+ def _sse_response(events: list[dict]) -> _FakeResponse:
61
+ """Build a fake SSE body from a list of event dicts."""
62
+ body = b""
63
+ for ev in events:
64
+ body += b"data: " + json.dumps(ev).encode("utf-8") + b"\n\n"
65
+ return _FakeResponse(body)
66
+
67
+
68
+ # ---------------------------------------------------------------------------
69
+ # Client — REST shape
70
+ # ---------------------------------------------------------------------------
71
+
72
+
73
+ class TestClientHeaders(unittest.TestCase):
74
+ def _captured_request(self, urlopen_patch):
75
+ # urlopen_patch.call_args[0][0] is the Request object.
76
+ req = urlopen_patch.call_args[0][0]
77
+ return req
78
+
79
+ def test_create_agent_sends_beta_header(self):
80
+ c = MA.ManagedAgentClient(api_key="sk-test")
81
+ with mock.patch("urllib.request.urlopen",
82
+ return_value=_json_response({"id": "agent_1", "version": 1})) as uo:
83
+ c.create_agent(name="x", model="claude-opus-4-7", system="hi")
84
+ req = self._captured_request(uo)
85
+ self.assertEqual(req.get_header("X-api-key"), "sk-test")
86
+ self.assertEqual(req.get_header("Anthropic-beta"),
87
+ "managed-agents-2026-04-01")
88
+ self.assertEqual(req.get_header("Anthropic-version"), "2023-06-01")
89
+ # Body is the agent definition
90
+ body = json.loads(req.data.decode("utf-8"))
91
+ self.assertEqual(body["name"], "x")
92
+ self.assertEqual(body["model"], "claude-opus-4-7")
93
+ self.assertEqual(body["system"], "hi")
94
+ self.assertEqual(body["tools"], [{"type": "agent_toolset_20260401"}])
95
+
96
+ def test_create_agent_defaults_tools_to_full_toolset(self):
97
+ c = MA.ManagedAgentClient(api_key="sk-test")
98
+ with mock.patch("urllib.request.urlopen",
99
+ return_value=_json_response({"id": "agent_2"})) as uo:
100
+ c.create_agent(name="x")
101
+ body = json.loads(uo.call_args[0][0].data.decode("utf-8"))
102
+ self.assertEqual(body["tools"], [{"type": "agent_toolset_20260401"}])
103
+
104
+ def test_create_environment_defaults_to_cloud_unrestricted(self):
105
+ c = MA.ManagedAgentClient(api_key="sk-test")
106
+ with mock.patch("urllib.request.urlopen",
107
+ return_value=_json_response({"id": "env_1"})) as uo:
108
+ c.create_environment(name="quickstart")
109
+ body = json.loads(uo.call_args[0][0].data.decode("utf-8"))
110
+ self.assertEqual(body["name"], "quickstart")
111
+ self.assertEqual(body["config"]["type"], "cloud")
112
+ self.assertEqual(body["config"]["networking"]["type"], "unrestricted")
113
+
114
+ def test_send_user_message_shape(self):
115
+ c = MA.ManagedAgentClient(api_key="sk-test")
116
+ with mock.patch("urllib.request.urlopen",
117
+ return_value=_json_response({})) as uo:
118
+ c.send_user_message("sess_1", "hello world")
119
+ body = json.loads(uo.call_args[0][0].data.decode("utf-8"))
120
+ self.assertEqual(body["events"][0]["type"], "user.message")
121
+ self.assertEqual(body["events"][0]["content"][0]["text"], "hello world")
122
+
123
+ def test_http_error_raises_managed_agent_error(self):
124
+ import urllib.error
125
+ c = MA.ManagedAgentClient(api_key="sk-test")
126
+ err = urllib.error.HTTPError(
127
+ "http://x", 401,
128
+ "Unauthorized", {}, io.BytesIO(b'{"error":"bad key"}'),
129
+ )
130
+ with mock.patch("urllib.request.urlopen", side_effect=err):
131
+ with self.assertRaises(MA.ManagedAgentError) as ctx:
132
+ c.create_agent(name="x")
133
+ self.assertIn("HTTP 401", str(ctx.exception))
134
+
135
+
136
+ # ---------------------------------------------------------------------------
137
+ # SSE stream parser
138
+ # ---------------------------------------------------------------------------
139
+
140
+
141
+ class TestStreamParser(unittest.TestCase):
142
+ def test_stream_yields_each_event(self):
143
+ c = MA.ManagedAgentClient(api_key="sk-test")
144
+ events = [
145
+ {"type": "agent.message",
146
+ "content": [{"type": "text", "text": "hi"}]},
147
+ {"type": "agent.tool_use", "name": "bash"},
148
+ {"type": "session.status_idle"},
149
+ ]
150
+ with mock.patch("urllib.request.urlopen",
151
+ return_value=_sse_response(events)):
152
+ out = list(c.stream_events("sess_x"))
153
+ self.assertEqual(len(out), 3)
154
+ self.assertEqual(out[0]["type"], "agent.message")
155
+ self.assertEqual(out[2]["type"], "session.status_idle")
156
+
157
+ def test_stream_stops_on_idle_when_stop_on_idle(self):
158
+ c = MA.ManagedAgentClient(api_key="sk-test")
159
+ events = [
160
+ {"type": "agent.message",
161
+ "content": [{"type": "text", "text": "a"}]},
162
+ {"type": "session.status_idle"},
163
+ # These MUST be ignored when stop_on_idle=True
164
+ {"type": "agent.message",
165
+ "content": [{"type": "text", "text": "leak"}]},
166
+ ]
167
+ with mock.patch("urllib.request.urlopen",
168
+ return_value=_sse_response(events)):
169
+ out = list(c.stream_events("sess_x", stop_on_idle=True))
170
+ self.assertEqual(len(out), 2)
171
+ self.assertEqual(out[-1]["type"], "session.status_idle")
172
+
173
+ def test_stream_ignores_malformed_lines(self):
174
+ c = MA.ManagedAgentClient(api_key="sk-test")
175
+ body = (
176
+ b"\n" # blank
177
+ b": comment\n" # SSE comment
178
+ b"data: not-json\n\n" # malformed payload
179
+ b'data: {"type":"agent.message","content":[{"type":"text","text":"ok"}]}\n\n'
180
+ b'data: {"type":"session.status_idle"}\n\n'
181
+ )
182
+ with mock.patch("urllib.request.urlopen",
183
+ return_value=_FakeResponse(body)):
184
+ out = list(c.stream_events("sess_x"))
185
+ # Two valid events parsed; malformed line silently skipped
186
+ self.assertEqual(len(out), 2)
187
+ self.assertEqual(out[0]["type"], "agent.message")
188
+
189
+
190
+ # ---------------------------------------------------------------------------
191
+ # Cache
192
+ # ---------------------------------------------------------------------------
193
+
194
+
195
+ class TestCache(unittest.TestCase):
196
+ def test_round_trip(self):
197
+ with tempfile.TemporaryDirectory() as tmp:
198
+ cache = MA.ManagedAgentCache(Path(tmp))
199
+ self.assertIsNone(cache.get_agent("a"))
200
+ cache.set_agent("a", "agent_123")
201
+ cache.set_environment("env-a", "env_456")
202
+ self.assertEqual(cache.get_agent("a"), "agent_123")
203
+ self.assertEqual(cache.get_environment("env-a"), "env_456")
204
+
205
+ def test_atomic_write_no_tmp_left_behind(self):
206
+ with tempfile.TemporaryDirectory() as tmp:
207
+ cache = MA.ManagedAgentCache(Path(tmp))
208
+ cache.set_agent("x", "agent_1")
209
+ p = MA._cache_path(Path(tmp))
210
+ # No .tmp.* siblings
211
+ leftovers = list(p.parent.glob("*.tmp.*"))
212
+ self.assertEqual(leftovers, [])
213
+
214
+ def test_corrupt_cache_yields_empty(self):
215
+ with tempfile.TemporaryDirectory() as tmp:
216
+ p = MA._cache_path(Path(tmp))
217
+ p.parent.mkdir(parents=True, exist_ok=True)
218
+ p.write_text("{not valid")
219
+ cache = MA.ManagedAgentCache(Path(tmp))
220
+ self.assertIsNone(cache.get_agent("x"))
221
+
222
+
223
+ # ---------------------------------------------------------------------------
224
+ # Provider — full path
225
+ # ---------------------------------------------------------------------------
226
+
227
+
228
+ class TestProvider(unittest.TestCase):
229
+ def test_run_creates_agent_env_session_and_aggregates_text(self):
230
+ from omega_engine.provider import AgentRequest
231
+
232
+ # Mock the network: 1 POST /agents + 1 POST /environments +
233
+ # 1 POST /sessions + 1 POST /sessions/<id>/events + 1 GET /stream (SSE)
234
+ calls: list[str] = []
235
+
236
+ def fake_urlopen(req, timeout=None):
237
+ url = req.full_url
238
+ calls.append(req.get_method() or "GET")
239
+ if url.endswith("/agents") and req.get_method() == "POST":
240
+ return _json_response({"id": "agent_X", "version": 1})
241
+ if url.endswith("/environments") and req.get_method() == "POST":
242
+ return _json_response({"id": "env_X"})
243
+ if url.endswith("/sessions") and req.get_method() == "POST":
244
+ return _json_response({"id": "sess_X"})
245
+ if "events" in url and req.get_method() == "POST":
246
+ return _json_response({})
247
+ if "stream" in url:
248
+ return _sse_response([
249
+ {"type": "agent.message",
250
+ "content": [{"type": "text", "text": "hello "},
251
+ {"type": "text", "text": "world"}]},
252
+ {"type": "agent.tool_use", "name": "bash"},
253
+ {"type": "session.status_idle"},
254
+ ])
255
+ raise AssertionError(f"unmocked: {req.get_method()} {url}")
256
+
257
+ with tempfile.TemporaryDirectory() as tmp:
258
+ with mock.patch("urllib.request.urlopen",
259
+ side_effect=fake_urlopen):
260
+ p = MA.ManagedAgentProvider(
261
+ api_key="sk-test", omega_home=Path(tmp),
262
+ )
263
+ result = p.run(AgentRequest(
264
+ role="worker", prompt="do the thing",
265
+ system="", context=None,
266
+ ))
267
+ self.assertEqual(result.text, "hello world")
268
+ self.assertEqual(result.artifacts["managed_agent"]["session_id"],
269
+ "sess_X")
270
+ self.assertEqual(result.artifacts["managed_agent"]["tool_uses"],
271
+ ["bash"])
272
+
273
+ def test_run_reuses_cached_agent_and_env_on_second_call(self):
274
+ """Second run should NOT re-POST /agents or /environments."""
275
+ from omega_engine.provider import AgentRequest
276
+
277
+ post_calls: list[str] = []
278
+
279
+ def fake_urlopen(req, timeout=None):
280
+ url = req.full_url
281
+ if req.get_method() == "POST":
282
+ post_calls.append(url)
283
+ if url.endswith("/agents") and req.get_method() == "POST":
284
+ return _json_response({"id": "agent_A"})
285
+ if url.endswith("/environments") and req.get_method() == "POST":
286
+ return _json_response({"id": "env_A"})
287
+ if url.endswith("/sessions") and req.get_method() == "POST":
288
+ return _json_response({"id": "sess_Y"})
289
+ if "events" in url and req.get_method() == "POST":
290
+ return _json_response({})
291
+ if "stream" in url:
292
+ return _sse_response([
293
+ {"type": "agent.message",
294
+ "content": [{"type": "text", "text": "ok"}]},
295
+ {"type": "session.status_idle"},
296
+ ])
297
+ raise AssertionError(f"unmocked: {req.get_method()} {url}")
298
+
299
+ with tempfile.TemporaryDirectory() as tmp:
300
+ with mock.patch("urllib.request.urlopen",
301
+ side_effect=fake_urlopen):
302
+ p = MA.ManagedAgentProvider(api_key="sk-test", omega_home=Path(tmp))
303
+ p.run(AgentRequest(role="worker", prompt="one", system="", context=None))
304
+ # Reset post_calls — only count the second invocation
305
+ post_calls.clear()
306
+ p2 = MA.ManagedAgentProvider(api_key="sk-test", omega_home=Path(tmp))
307
+ p2.run(AgentRequest(role="worker", prompt="two", system="", context=None))
308
+ # Second run: NO /agents, NO /environments. Only /sessions + /events.
309
+ for url in post_calls:
310
+ self.assertFalse(
311
+ url.endswith("/agents"), f"unexpected re-create: {url}")
312
+ self.assertFalse(
313
+ url.endswith("/environments"), f"unexpected re-create: {url}")
314
+
315
+ def test_constructor_rejects_missing_api_key(self):
316
+ # Patch env to be empty
317
+ with mock.patch.dict(os.environ, {}, clear=True):
318
+ with self.assertRaises(ValueError):
319
+ MA.ManagedAgentProvider(api_key=None)
320
+
321
+ def test_is_available_reflects_env(self):
322
+ with mock.patch.dict(os.environ, {"ANTHROPIC_API_KEY": "sk-x"}):
323
+ self.assertTrue(MA.ManagedAgentProvider.is_available())
324
+ with mock.patch.dict(os.environ, {}, clear=True):
325
+ self.assertFalse(MA.ManagedAgentProvider.is_available())
326
+
327
+ def test_run_with_system_prompt_prepended(self):
328
+ from omega_engine.provider import AgentRequest
329
+
330
+ captured_event_body = {}
331
+
332
+ def fake_urlopen(req, timeout=None):
333
+ url = req.full_url
334
+ if url.endswith("/agents"):
335
+ return _json_response({"id": "agent_S"})
336
+ if url.endswith("/environments"):
337
+ return _json_response({"id": "env_S"})
338
+ if url.endswith("/sessions"):
339
+ return _json_response({"id": "sess_S"})
340
+ if "events" in url:
341
+ captured_event_body["body"] = json.loads(
342
+ req.data.decode("utf-8")
343
+ )
344
+ return _json_response({})
345
+ if "stream" in url:
346
+ return _sse_response([{"type": "session.status_idle"}])
347
+ raise AssertionError(f"unmocked: {url}")
348
+
349
+ with tempfile.TemporaryDirectory() as tmp:
350
+ with mock.patch("urllib.request.urlopen",
351
+ side_effect=fake_urlopen):
352
+ p = MA.ManagedAgentProvider(api_key="sk-test", omega_home=Path(tmp))
353
+ p.run(AgentRequest(
354
+ role="worker", prompt="do X",
355
+ system="be careful", context=None,
356
+ ))
357
+ text = captured_event_body["body"]["events"][0]["content"][0]["text"]
358
+ self.assertIn("[system] be careful", text)
359
+ self.assertIn("do X", text)
360
+
361
+
362
+ if __name__ == "__main__":
363
+ unittest.main()
@@ -0,0 +1,231 @@
1
+ """Tests for the ClaudeMaxProvider + the interactive menu wiring.
2
+
3
+ The Max provider subprocesses ``claude -p`` — we don't actually run real
4
+ Claude in tests (cost + dependency). We mock subprocess.run to feed the
5
+ provider a canned JSON response and verify it parses correctly.
6
+
7
+ For the menu, we test the wiring: bare `omega` invocation dispatches to
8
+ ``cmd_menu``, and ``run_menu`` refuses cleanly when whiptail is missing.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ import shutil
14
+ import subprocess
15
+ import sys
16
+ import tempfile
17
+ import unittest
18
+ from pathlib import Path
19
+ from unittest import mock
20
+
21
+
22
+ HERE = Path(__file__).resolve().parent
23
+ sys.path.insert(0, str(HERE.parent))
24
+
25
+
26
+ # ---------------------------------------------------------------------------
27
+ # ClaudeMaxProvider
28
+ # ---------------------------------------------------------------------------
29
+
30
+
31
+ _CANNED_CLAUDE_JSON = {
32
+ "type": "result", "subtype": "success", "is_error": False,
33
+ "duration_ms": 4344, "duration_api_ms": 1760, "num_turns": 1,
34
+ "result": "Done.",
35
+ "stop_reason": "end_turn",
36
+ "session_id": "fake-session-abc",
37
+ "total_cost_usd": 0.0123,
38
+ "usage": {
39
+ "input_tokens": 12, "output_tokens": 34,
40
+ "cache_read_input_tokens": 0,
41
+ "cache_creation_input_tokens": 100,
42
+ },
43
+ "modelUsage": {"claude-opus-4-7": {"costUSD": 0.0123}},
44
+ }
45
+
46
+
47
+ def _fake_proc(stdout: str = "", returncode: int = 0, stderr: str = ""):
48
+ return subprocess.CompletedProcess(
49
+ args=[], returncode=returncode, stdout=stdout, stderr=stderr,
50
+ )
51
+
52
+
53
+ class TestClaudeMaxAvailability(unittest.TestCase):
54
+ def test_unavailable_when_claude_missing(self):
55
+ from omega_engine.provider import ClaudeMaxProvider
56
+ with mock.patch("shutil.which", return_value=None):
57
+ self.assertFalse(ClaudeMaxProvider.is_available())
58
+
59
+ def test_available_when_version_responds(self):
60
+ from omega_engine.provider import ClaudeMaxProvider
61
+ with mock.patch("shutil.which", return_value="/usr/bin/claude"), \
62
+ mock.patch("subprocess.run", return_value=_fake_proc("claude 1.0.0", 0)):
63
+ self.assertTrue(ClaudeMaxProvider.is_available())
64
+
65
+
66
+ class TestClaudeMaxRun(unittest.TestCase):
67
+ def _provider(self):
68
+ from omega_engine.provider import ClaudeMaxProvider
69
+ return ClaudeMaxProvider(model="sonnet")
70
+
71
+ def test_parses_canned_response(self):
72
+ from omega_engine.provider import AgentRequest
73
+ p = self._provider()
74
+ with mock.patch(
75
+ "subprocess.run",
76
+ return_value=_fake_proc(json.dumps(_CANNED_CLAUDE_JSON), 0),
77
+ ):
78
+ result = p.run(AgentRequest(
79
+ role="worker", prompt="say done",
80
+ ))
81
+ self.assertEqual(result.text, "Done.")
82
+ self.assertTrue(result.claimed_done)
83
+ self.assertEqual(result.usage["input_tokens"], 12)
84
+ self.assertEqual(result.usage["output_tokens"], 34)
85
+ self.assertAlmostEqual(result.usage["cost_usd"], 0.0123)
86
+ self.assertEqual(result.artifacts["session_id"], "fake-session-abc")
87
+ self.assertEqual(result.artifacts["num_turns"], 1)
88
+
89
+ def test_subprocess_command_carries_system_prompt(self):
90
+ from omega_engine.provider import AgentRequest
91
+ p = self._provider()
92
+ captured: dict = {}
93
+
94
+ def fake_run(cmd, **kw):
95
+ captured["cmd"] = cmd
96
+ return _fake_proc(json.dumps(_CANNED_CLAUDE_JSON), 0)
97
+
98
+ with mock.patch("subprocess.run", side_effect=fake_run):
99
+ p.run(AgentRequest(
100
+ role="worker", prompt="hi",
101
+ system="You are a focused worker.",
102
+ ))
103
+ # --append-system-prompt is on the command line
104
+ self.assertIn("--append-system-prompt", captured["cmd"])
105
+ self.assertIn("You are a focused worker.", captured["cmd"])
106
+ # --dangerously-skip-permissions is set (headless Max)
107
+ self.assertIn("--dangerously-skip-permissions", captured["cmd"])
108
+ # --output-format json is on
109
+ self.assertIn("--output-format", captured["cmd"])
110
+ self.assertIn("json", captured["cmd"])
111
+
112
+ def test_resume_session(self):
113
+ from omega_engine.provider import AgentRequest
114
+ p = self._provider()
115
+ captured: dict = {}
116
+
117
+ def fake_run(cmd, **kw):
118
+ captured["cmd"] = cmd
119
+ return _fake_proc(json.dumps(_CANNED_CLAUDE_JSON), 0)
120
+
121
+ with mock.patch("subprocess.run", side_effect=fake_run):
122
+ p.run(AgentRequest(
123
+ role="oracle", prompt="next step",
124
+ context={"session_id": "prev-abc"},
125
+ ))
126
+ self.assertIn("--resume", captured["cmd"])
127
+ self.assertIn("prev-abc", captured["cmd"])
128
+
129
+ def test_failure_surfaces_clean_error(self):
130
+ from omega_engine.provider import AgentRequest
131
+ p = self._provider()
132
+ with mock.patch(
133
+ "subprocess.run",
134
+ return_value=_fake_proc("", 1, "rate limit hit"),
135
+ ):
136
+ with self.assertRaises(RuntimeError) as ctx:
137
+ p.run(AgentRequest(role="worker", prompt="hi"))
138
+ self.assertIn("rate limit", str(ctx.exception))
139
+
140
+
141
+ class TestRouterAuto(unittest.TestCase):
142
+ def test_auto_picks_claude_max_when_available(self):
143
+ from omega_engine.router import ModelRouter
144
+ from omega_engine.provider import ClaudeMaxProvider
145
+ with mock.patch.object(ClaudeMaxProvider, "is_available",
146
+ return_value=True):
147
+ router = ModelRouter.auto()
148
+ self.assertEqual(router.resolve("worker").id, "claude-max")
149
+
150
+ def test_auto_falls_back_to_api_when_max_unavailable(self):
151
+ from omega_engine.router import ModelRouter
152
+ from omega_engine.provider import ClaudeMaxProvider
153
+ with mock.patch.object(ClaudeMaxProvider, "is_available",
154
+ return_value=False), \
155
+ mock.patch.dict("os.environ", {"ANTHROPIC_API_KEY": "sk-x"}):
156
+ router = ModelRouter.auto()
157
+ self.assertEqual(router.resolve("worker").id, "claude")
158
+
159
+ def test_auto_falls_back_to_mock_when_nothing(self):
160
+ from omega_engine.router import ModelRouter
161
+ from omega_engine.provider import ClaudeMaxProvider
162
+ with mock.patch.object(ClaudeMaxProvider, "is_available",
163
+ return_value=False), \
164
+ mock.patch.dict("os.environ", {}, clear=True):
165
+ router = ModelRouter.auto()
166
+ self.assertEqual(router.resolve("worker").id, "mock")
167
+
168
+
169
+ # ---------------------------------------------------------------------------
170
+ # Menu wiring
171
+ # ---------------------------------------------------------------------------
172
+
173
+
174
+ class TestMenuDispatch(unittest.TestCase):
175
+ def test_bare_omega_dispatches_to_menu(self):
176
+ """parse_args([]) should set fn to cmd_menu — i.e. `omega`
177
+ with no subcommand opens the interactive menu, doesn't error."""
178
+ from omega_engine.cli import _build_parser, cmd_menu
179
+ parser = _build_parser()
180
+ # argparse with optional subparser → no args parses cleanly
181
+ args = parser.parse_args([])
182
+ self.assertEqual(args.fn, cmd_menu)
183
+
184
+ def test_run_menu_falls_back_to_text_when_whiptail_missing(self):
185
+ """Behaviour changed in v0.19.4: a bare `omega` MUST NEVER exit
186
+ silently when whiptail is missing — it falls back to a stdin/stdout
187
+ text menu. Without this fix, Mac users hit `omega` and got nothing
188
+ ("se passe rien" — the v0.19.3 regression)."""
189
+ from omega_engine.menu import run_menu
190
+ import io, contextlib
191
+ # whiptail absent → text fallback. User picks "0" (quit).
192
+ with mock.patch("omega_engine.menu._have", return_value=False), \
193
+ mock.patch("builtins.input", side_effect=["0"]):
194
+ with contextlib.redirect_stdout(io.StringIO()) as buf:
195
+ rc = run_menu()
196
+ self.assertEqual(rc, 0, "text fallback must exit cleanly on user quit")
197
+ # The text menu must actually print SOMETHING — the silent return
198
+ # was the bug we're guarding against.
199
+ self.assertIn("Omega OS", buf.getvalue())
200
+
201
+ def test_run_menu_quits_cleanly(self):
202
+ from omega_engine.menu import run_menu
203
+ # Simulate user choosing "quit" from the main menu.
204
+ with mock.patch("omega_engine.menu._have", return_value=True), \
205
+ mock.patch("omega_engine.menu._whiptail_menu",
206
+ return_value="quit"):
207
+ rc = run_menu()
208
+ self.assertEqual(rc, 0)
209
+
210
+
211
+ class TestMenuHelpers(unittest.TestCase):
212
+ def test_run_capture_invokes_omega_bin(self):
213
+ from omega_engine.menu import _run_capture
214
+
215
+ captured: dict = {}
216
+
217
+ def fake_run(cmd, **kw):
218
+ captured["cmd"] = cmd
219
+ return _fake_proc("ok\n", 0)
220
+
221
+ with mock.patch("subprocess.run", side_effect=fake_run):
222
+ out = _run_capture("doctor")
223
+ self.assertEqual(out, "ok")
224
+ # The omega args land in cmd[1:], whatever the binary path is.
225
+ self.assertEqual(captured["cmd"][1], "doctor")
226
+ # The first arg is a real path (resolved omega bin or sys.argv[0]).
227
+ self.assertGreater(len(captured["cmd"][0]), 0)
228
+
229
+
230
+ if __name__ == "__main__":
231
+ unittest.main(verbosity=2)
@@ -0,0 +1,72 @@
1
+ """Coverage tests for the interactive menu — make sure the new v0.19.1
2
+ entries (genesis, plan, worker, handoff, hermes, hermes-desktop,
3
+ memory, learn, update, ua, ma) all have:
4
+
5
+ * an entry in _MAIN_ITEMS
6
+ * a corresponding _menu_<name> function
7
+ * a dispatch arm in run_menu
8
+
9
+ So the next time we add a top-level CLI command, the test reminds the
10
+ maintainer to wire it into the menu too.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import sys
15
+ from pathlib import Path
16
+ import unittest
17
+
18
+ HERE = Path(__file__).resolve().parent
19
+ sys.path.insert(0, str(HERE.parent))
20
+
21
+ from omega_engine import menu as M # noqa: E402
22
+
23
+
24
+ # Every key here MUST appear in _MAIN_ITEMS AND have a _menu_<key>
25
+ # function (with the hyphen normalised to underscore for the func name).
26
+ _EXPECTED_KEYS_V019 = {
27
+ "mission", "genesis", "plan", "worker", "handoff",
28
+ "hermes", "hermes-desktop", "tmux", "aisb-chat",
29
+ "projects", "accounts", "audit", "skills",
30
+ "memory", "learn", "update", "ua", "ma",
31
+ "maintenance", "settings", "status", "doctor",
32
+ }
33
+
34
+
35
+ class TestMenuCoverage(unittest.TestCase):
36
+ def test_main_items_count(self):
37
+ """We added 11 new entries in v0.19.1. Floor: 22 (not counting quit)."""
38
+ non_quit = [k for k, _ in M._MAIN_ITEMS if k != "quit"]
39
+ self.assertGreaterEqual(len(non_quit), 22,
40
+ f"main menu shrank below 22 entries: {non_quit}")
41
+
42
+ def test_all_expected_keys_present(self):
43
+ keys = {k for k, _ in M._MAIN_ITEMS}
44
+ missing = _EXPECTED_KEYS_V019 - keys
45
+ self.assertEqual(missing, set(),
46
+ f"missing menu entries: {missing}")
47
+
48
+ def test_every_main_item_has_handler_or_is_leaf(self):
49
+ """For every non-leaf entry, _menu_<name> MUST exist."""
50
+ # 'quit', 'status', 'doctor' are leaves (no sub-menu).
51
+ leaves = {"quit", "status", "doctor"}
52
+ for key, _ in M._MAIN_ITEMS:
53
+ if key in leaves:
54
+ continue
55
+ func_name = "_menu_" + key.replace("-", "_")
56
+ self.assertTrue(
57
+ hasattr(M, func_name),
58
+ f"main menu entry {key!r} has no {func_name}() function",
59
+ )
60
+
61
+ def test_no_duplicate_keys(self):
62
+ keys = [k for k, _ in M._MAIN_ITEMS]
63
+ self.assertEqual(len(keys), len(set(keys)),
64
+ "duplicate menu keys")
65
+
66
+ def test_quit_is_present(self):
67
+ keys = {k for k, _ in M._MAIN_ITEMS}
68
+ self.assertIn("quit", keys)
69
+
70
+
71
+ if __name__ == "__main__":
72
+ unittest.main()