@agentikos/omega-os 0.2.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 (367) hide show
  1. package/README.md +33 -3
  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 +790 -21
  10. package/bootstrap/manifest.example.yaml +87 -1
  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/GAP-ANALYSIS.md +214 -0
  48. package/docs/INSTALL.md +47 -9
  49. package/docs/MCP-AND-PLUGINS.md +31 -4
  50. package/docs/SIMULATION.md +171 -0
  51. package/docs/simulate.sh +211 -0
  52. package/install.sh +164 -17
  53. package/omega/Agentik_Engine/README.md +4 -2
  54. package/omega/Agentik_Engine/omega_engine/__init__.py +147 -1
  55. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  56. package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
  57. package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
  58. package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
  59. package/omega/Agentik_Engine/omega_engine/__pycache__/audit.cpython-313.pyc +0 -0
  60. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_arsenal.cpython-313.pyc +0 -0
  61. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
  62. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
  63. package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
  64. package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
  65. package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
  66. package/omega/Agentik_Engine/omega_engine/__pycache__/barrier.cpython-313.pyc +0 -0
  67. package/omega/Agentik_Engine/omega_engine/__pycache__/bus.cpython-313.pyc +0 -0
  68. package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
  69. package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
  70. package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
  71. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  72. package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
  73. package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
  74. package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
  75. package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
  76. package/omega/Agentik_Engine/omega_engine/__pycache__/events.cpython-313.pyc +0 -0
  77. package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
  78. package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
  79. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
  80. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
  81. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
  82. package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
  83. package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
  84. package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
  85. package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
  86. package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
  87. package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
  88. package/omega/Agentik_Engine/omega_engine/__pycache__/progress.cpython-313.pyc +0 -0
  89. package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
  90. package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
  91. package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
  92. package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
  93. package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
  94. package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
  95. package/omega/Agentik_Engine/omega_engine/__pycache__/report.cpython-313.pyc +0 -0
  96. package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
  97. package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
  98. package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
  99. package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
  100. package/omega/Agentik_Engine/omega_engine/__pycache__/supervisor.cpython-313.pyc +0 -0
  101. package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
  102. package/omega/Agentik_Engine/omega_engine/__pycache__/task.cpython-313.pyc +0 -0
  103. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram.cpython-313.pyc +0 -0
  104. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
  105. package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
  106. package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
  107. package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
  108. package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
  109. package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
  110. package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
  111. package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
  112. package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
  113. package/omega/Agentik_Engine/omega_engine/account.py +28 -31
  114. package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
  115. package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
  116. package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
  117. package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
  118. package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
  119. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
  120. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
  121. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
  122. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
  123. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
  124. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
  125. package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
  126. package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
  127. package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
  128. package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
  129. package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
  130. package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
  131. package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
  132. package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
  133. package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
  134. package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
  135. package/omega/Agentik_Engine/omega_engine/cli.py +4156 -86
  136. package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
  137. package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
  138. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
  139. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
  140. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
  141. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
  142. package/omega/Agentik_Engine/omega_engine/daemons/engine.py +53 -4
  143. package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +101 -17
  144. package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
  145. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
  146. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
  147. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
  148. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
  149. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
  150. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
  151. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
  152. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
  153. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
  154. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
  155. package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
  156. package/omega/Agentik_Engine/omega_engine/executor.py +149 -10
  157. package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
  158. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
  159. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
  160. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
  161. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
  162. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
  163. package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
  164. package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
  165. package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
  166. package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
  167. package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
  168. package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
  169. package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
  170. package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
  171. package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
  172. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
  173. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
  174. package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
  175. package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
  176. package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
  177. package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
  178. package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
  179. package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
  180. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
  181. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
  182. package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
  183. package/omega/Agentik_Engine/omega_engine/mission.py +16 -13
  184. package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
  185. package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
  186. package/omega/Agentik_Engine/omega_engine/provider.py +161 -12
  187. package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
  188. package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
  189. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
  190. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
  191. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
  192. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
  193. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
  194. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
  195. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
  196. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
  197. package/omega/Agentik_Engine/omega_engine/router.py +28 -0
  198. package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
  199. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
  200. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
  201. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
  202. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
  203. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
  204. package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
  205. package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
  206. package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
  207. package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
  208. package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
  209. package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
  210. package/omega/Agentik_Engine/omega_engine/store.py +88 -41
  211. package/omega/Agentik_Engine/omega_engine/sync.py +142 -1
  212. package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
  213. package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
  214. package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
  215. package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
  216. package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
  217. package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
  218. package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
  219. package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
  220. package/omega/Agentik_Engine/pyproject.toml +1 -1
  221. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
  222. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
  223. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
  224. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
  225. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
  226. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
  227. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
  228. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313.pyc +0 -0
  229. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
  230. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
  231. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
  232. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
  233. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
  234. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
  235. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
  236. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
  237. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
  238. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313.pyc +0 -0
  239. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
  240. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
  241. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
  242. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
  243. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
  244. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
  245. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
  246. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
  247. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
  248. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
  249. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
  250. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
  251. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
  252. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
  253. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
  254. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
  255. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
  256. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
  257. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
  258. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
  259. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
  260. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
  261. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
  262. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
  263. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
  264. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
  265. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
  266. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313.pyc +0 -0
  267. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
  268. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313.pyc +0 -0
  269. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
  270. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313.pyc +0 -0
  271. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
  272. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
  273. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
  274. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
  275. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
  276. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313.pyc +0 -0
  277. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
  278. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313.pyc +0 -0
  279. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
  280. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
  281. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
  282. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
  283. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
  284. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
  285. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
  286. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
  287. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
  288. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
  289. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
  290. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
  291. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
  292. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
  293. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
  294. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
  295. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
  296. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
  297. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
  298. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
  299. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
  300. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
  301. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
  302. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
  303. package/omega/Agentik_Engine/tests/test_account.py +8 -3
  304. package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
  305. package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
  306. package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
  307. package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
  308. package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
  309. package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
  310. package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
  311. package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
  312. package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
  313. package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
  314. package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
  315. package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
  316. package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
  317. package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
  318. package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
  319. package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
  320. package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
  321. package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
  322. package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
  323. package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
  324. package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
  325. package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
  326. package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
  327. package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
  328. package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
  329. package/omega/Agentik_Engine/tests/test_vault.py +173 -0
  330. package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
  331. package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
  332. package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
  333. package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
  334. package/omega/Agentik_Runtime/audits.db +0 -0
  335. package/omega/Agentik_SSOT/VERSION +1 -1
  336. package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
  337. package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
  338. package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
  339. package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
  340. package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
  341. package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
  342. package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
  343. package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
  344. package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
  345. package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
  346. package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
  347. package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
  348. package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
  349. package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
  350. package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
  351. package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
  352. package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
  353. package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
  354. package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
  355. package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
  356. package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
  357. package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
  358. package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
  359. package/omega/Agentik_SSOT/skills/rag-route.md +9 -0
  360. package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
  361. package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
  362. package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
  363. package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
  364. package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
  365. package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
  366. package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
  367. package/package.json +2 -2
@@ -0,0 +1,189 @@
1
+ """Tests for omega_engine.skill_routing — role → skills resolution + the
2
+ system-prompt skill block.
3
+
4
+ The routing module is pure (no I/O for the role map, single Read for the
5
+ description extraction) so these tests stay fast: ~30 ms total.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+ import tempfile
11
+ import unittest
12
+ from pathlib import Path
13
+
14
+
15
+ HERE = Path(__file__).resolve().parent
16
+ sys.path.insert(0, str(HERE.parent))
17
+
18
+ from omega_engine import skill_routing as SR # noqa: E402
19
+ from omega_engine import worker as W # noqa: E402
20
+
21
+
22
+ class TestRoleDefaults(unittest.TestCase):
23
+ def test_worker_includes_pursue_and_audits(self):
24
+ recs = SR.recommend("worker")
25
+ self.assertIn("pursue", recs)
26
+ self.assertIn("codeaudit", recs)
27
+ self.assertIn("debugaudit", recs)
28
+
29
+ def test_oracle_includes_dispatch(self):
30
+ self.assertIn("dispatch", SR.recommend("oracle"))
31
+
32
+ def test_classifier_is_empty(self):
33
+ self.assertEqual(SR.recommend("classifier"), [])
34
+
35
+ def test_unknown_role_returns_empty_list(self):
36
+ self.assertEqual(SR.recommend("does-not-exist"), [])
37
+
38
+ def test_recommend_returns_copy(self):
39
+ # Mutating the return value must not pollute the global map.
40
+ a = SR.recommend("worker")
41
+ a.append("garbage")
42
+ self.assertNotIn("garbage", SR.recommend("worker"))
43
+
44
+ def test_power_skills_listed(self):
45
+ # The constant exists, includes the obvious ones, has stable ordering.
46
+ self.assertIn("dispatch", SR.POWER_SKILLS)
47
+ self.assertIn("pursue", SR.POWER_SKILLS)
48
+ self.assertIn("codeaudit", SR.POWER_SKILLS)
49
+
50
+
51
+ class TestResolution(unittest.TestCase):
52
+ def test_explicit_wins(self):
53
+ out = SR.skills_for("worker", explicit=["only-this"])
54
+ self.assertEqual(out, ["only-this"])
55
+
56
+ def test_topology_wins_over_role_default(self):
57
+ out = SR.skills_for("worker", topology_skills=["mission-skill"])
58
+ self.assertEqual(out, ["mission-skill"])
59
+
60
+ def test_explicit_wins_over_topology(self):
61
+ out = SR.skills_for("worker", explicit=["a"], topology_skills=["b"])
62
+ self.assertEqual(out, ["a"])
63
+
64
+ def test_falls_back_to_role_default(self):
65
+ out = SR.skills_for("oracle")
66
+ self.assertIn("dispatch", out)
67
+
68
+
69
+ class TestCatalog(unittest.TestCase):
70
+ def test_empty_home_returns_empty(self):
71
+ with tempfile.TemporaryDirectory() as tmp:
72
+ self.assertEqual(SR.catalog_for_home(tmp), [])
73
+
74
+ def test_lists_skill_dirs_and_files(self):
75
+ with tempfile.TemporaryDirectory() as tmp:
76
+ root = Path(tmp) / "Agentik_SSOT" / "skills"
77
+ (root / "pursue").mkdir(parents=True)
78
+ (root / "pursue" / "SKILL.md").write_text("---\nname: pursue\n---")
79
+ (root / "codeaudit").mkdir()
80
+ (root / "codeaudit" / "SKILL.md").write_text("---\nname: codeaudit\n---")
81
+ (root / "no-skillmd").mkdir() # not a real skill, must be skipped
82
+ (root / "rag-route.md").write_text("---\nname: rag-route\n---")
83
+ out = SR.catalog_for_home(tmp)
84
+ self.assertIn("pursue", out)
85
+ self.assertIn("codeaudit", out)
86
+ self.assertIn("rag-route", out)
87
+ self.assertNotIn("no-skillmd", out)
88
+
89
+
90
+ class TestSkillBlock(unittest.TestCase):
91
+ def test_empty_returns_empty(self):
92
+ self.assertEqual(SR.format_skill_block([]), "")
93
+
94
+ def test_block_lists_skill_ids_and_header(self):
95
+ block = SR.format_skill_block(["pursue", "codeaudit"])
96
+ self.assertIn("## Skills available", block)
97
+ self.assertIn("/pursue", block)
98
+ self.assertIn("/codeaudit", block)
99
+ self.assertIn("invoke them as slash", block)
100
+
101
+ def test_block_includes_descriptions_when_skillmd_present(self):
102
+ with tempfile.TemporaryDirectory() as tmp:
103
+ root = Path(tmp) / "Agentik_SSOT" / "skills"
104
+ (root / "pursue").mkdir(parents=True)
105
+ (root / "pursue" / "SKILL.md").write_text(
106
+ "---\nname: pursue\n"
107
+ "description: Goal-driven loop until verify exits 0.\n"
108
+ "---\n# pursue\n"
109
+ )
110
+ block = SR.format_skill_block(["pursue"], home=tmp)
111
+ self.assertIn("Goal-driven loop", block)
112
+
113
+ def test_description_too_long_is_truncated(self):
114
+ with tempfile.TemporaryDirectory() as tmp:
115
+ root = Path(tmp) / "Agentik_SSOT" / "skills"
116
+ (root / "huge").mkdir(parents=True)
117
+ long_desc = "x" * 200
118
+ (root / "huge" / "SKILL.md").write_text(
119
+ f"---\nname: huge\ndescription: {long_desc}\n---"
120
+ )
121
+ block = SR.format_skill_block(["huge"], home=tmp)
122
+ self.assertIn("...", block)
123
+
124
+
125
+ class TestWorkerBriefSkills(unittest.TestCase):
126
+ def test_default_role_resolves_to_role_skills(self):
127
+ b = W.WorkerBrief(task_id="t1", role="worker", intent="x")
128
+ skills = b.resolved_skills()
129
+ self.assertIn("pursue", skills)
130
+
131
+ def test_explicit_skills_override(self):
132
+ b = W.WorkerBrief(task_id="t1", role="worker", intent="x",
133
+ skills=["only-this"])
134
+ self.assertEqual(b.resolved_skills(), ["only-this"])
135
+
136
+ def test_classifier_role_empty_by_default(self):
137
+ b = W.WorkerBrief(task_id="t1", role="classifier", intent="x")
138
+ self.assertEqual(b.resolved_skills(), [])
139
+
140
+ def test_json_round_trip_preserves_skills(self):
141
+ import json
142
+ b = W.WorkerBrief(task_id="t1", role="worker", intent="x",
143
+ skills=["pursue", "codeaudit"])
144
+ loaded = W.WorkerBrief.from_dict(json.loads(b.to_json()))
145
+ self.assertEqual(loaded.skills, ["pursue", "codeaudit"])
146
+
147
+
148
+ class TestRunBriefEmbedsSkillBlock(unittest.TestCase):
149
+ """When the brief carries skills, the system_prompt sent to claude
150
+ contains the skill block."""
151
+
152
+ def test_system_prompt_includes_skill_section(self):
153
+ import json as _json
154
+ from unittest import mock
155
+ with tempfile.TemporaryDirectory() as tmp:
156
+ home = Path(tmp)
157
+ brief = W.WorkerBrief(
158
+ task_id="t-sk", role="worker", intent="x",
159
+ skills=["pursue", "codeaudit"],
160
+ )
161
+ W.write_brief(home, brief)
162
+ captured = {}
163
+
164
+ def fake_run(cmd, **kw):
165
+ captured["cmd"] = cmd
166
+ import subprocess
167
+ return subprocess.CompletedProcess(
168
+ args=cmd, returncode=0,
169
+ stdout=_json.dumps({
170
+ "result": "ok", "session_id": "s",
171
+ "usage": {}, "total_cost_usd": 0.0,
172
+ }),
173
+ stderr="",
174
+ )
175
+
176
+ with mock.patch.object(W.subprocess, "run", side_effect=fake_run):
177
+ W.run_brief(home, "t-sk")
178
+ cmd = captured["cmd"]
179
+ # --append-system-prompt is present
180
+ self.assertIn("--append-system-prompt", cmd)
181
+ idx = cmd.index("--append-system-prompt")
182
+ block = cmd[idx + 1]
183
+ self.assertIn("## Skills available", block)
184
+ self.assertIn("/pursue", block)
185
+ self.assertIn("/codeaudit", block)
186
+
187
+
188
+ if __name__ == "__main__":
189
+ unittest.main()
@@ -0,0 +1,209 @@
1
+ """Tests for the per-topic conversation-history layer.
2
+
3
+ The Telegram daemon used to forget everything between turns. This module
4
+ adds a SQLite-backed history. The tests verify the round-trip, the
5
+ chronological ordering, the context-prompt builder, and the DM refusal
6
+ path in the daemon router.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import sys
11
+ import tempfile
12
+ import time
13
+ import unittest
14
+ from pathlib import Path
15
+ from unittest import mock
16
+
17
+
18
+ HERE = Path(__file__).resolve().parent
19
+ sys.path.insert(0, str(HERE.parent))
20
+
21
+ from omega_engine.telegram_history import ( # noqa: E402
22
+ Message,
23
+ build_context_prompt,
24
+ prune,
25
+ record_inbound,
26
+ record_outbound,
27
+ recent_messages,
28
+ topic_stats,
29
+ )
30
+
31
+
32
+ class TestRecordAndRecent(unittest.TestCase):
33
+ def test_round_trip(self):
34
+ with tempfile.TemporaryDirectory() as td:
35
+ record_inbound(td, topic_id=42, text="hi", message_id=1)
36
+ record_outbound(td, topic_id=42, text="hello", message_id=2)
37
+ history = recent_messages(td, topic_id=42)
38
+ self.assertEqual(len(history), 2)
39
+ self.assertEqual(history[0].role, "user")
40
+ self.assertEqual(history[0].text, "hi")
41
+ self.assertEqual(history[1].role, "bot")
42
+ self.assertEqual(history[1].text, "hello")
43
+
44
+ def test_recent_is_chronological(self):
45
+ with tempfile.TemporaryDirectory() as td:
46
+ for i in range(5):
47
+ record_inbound(td, topic_id=7, text=f"msg{i}")
48
+ time.sleep(0.01)
49
+ history = recent_messages(td, topic_id=7)
50
+ self.assertEqual(
51
+ [m.text for m in history],
52
+ ["msg0", "msg1", "msg2", "msg3", "msg4"],
53
+ )
54
+
55
+ def test_recent_respects_limit(self):
56
+ with tempfile.TemporaryDirectory() as td:
57
+ for i in range(20):
58
+ record_inbound(td, topic_id=8, text=f"m{i}")
59
+ history = recent_messages(td, topic_id=8, limit=5)
60
+ self.assertEqual(len(history), 5)
61
+ # The 5 most recent, in chronological order.
62
+ self.assertEqual(
63
+ [m.text for m in history],
64
+ ["m15", "m16", "m17", "m18", "m19"],
65
+ )
66
+
67
+ def test_topics_are_isolated(self):
68
+ with tempfile.TemporaryDirectory() as td:
69
+ record_inbound(td, topic_id=1, text="topic1-a")
70
+ record_inbound(td, topic_id=2, text="topic2-a")
71
+ t1 = recent_messages(td, topic_id=1)
72
+ t2 = recent_messages(td, topic_id=2)
73
+ self.assertEqual([m.text for m in t1], ["topic1-a"])
74
+ self.assertEqual([m.text for m in t2], ["topic2-a"])
75
+
76
+ def test_record_rejects_unknown_role(self):
77
+ with tempfile.TemporaryDirectory() as td:
78
+ from omega_engine.telegram_history import _record
79
+ with self.assertRaises(ValueError):
80
+ _record(td, topic_id=1, role="alien", text="x", message_id=None)
81
+
82
+
83
+ class TestContextPrompt(unittest.TestCase):
84
+ def test_cold_topic_returns_intent_unchanged(self):
85
+ with tempfile.TemporaryDirectory() as td:
86
+ out = build_context_prompt(td, topic_id=99, new_intent="hello")
87
+ self.assertEqual(out, "hello")
88
+
89
+ def test_warm_topic_prepends_history(self):
90
+ with tempfile.TemporaryDirectory() as td:
91
+ record_inbound(td, topic_id=1, text="please fix the login bug")
92
+ record_outbound(td, topic_id=1, text="ok, I'm starting now")
93
+ out = build_context_prompt(td, topic_id=1,
94
+ new_intent="any progress?")
95
+ self.assertIn("Conversation history in topic 1", out)
96
+ self.assertIn("please fix the login bug", out)
97
+ self.assertIn("ok, I'm starting now", out)
98
+ self.assertIn("any progress?", out)
99
+ self.assertIn("user (just now)", out)
100
+
101
+ def test_context_format_carries_roles_and_age(self):
102
+ with tempfile.TemporaryDirectory() as td:
103
+ record_inbound(td, topic_id=2, text="how do I configure age?")
104
+ out = build_context_prompt(td, topic_id=2,
105
+ new_intent="also tell me about vault")
106
+ # role markers present
107
+ self.assertIn("user (", out)
108
+ # short human-time present (we just wrote it; should be "0s ago" or similar)
109
+ self.assertTrue("ago" in out)
110
+
111
+
112
+ class TestPrune(unittest.TestCase):
113
+ def test_prune_drops_old_rows(self):
114
+ with tempfile.TemporaryDirectory() as td:
115
+ from omega_engine.telegram_history import _connect
116
+ # Inject an artificially old row.
117
+ conn = _connect(td)
118
+ conn.execute(
119
+ "INSERT INTO messages (topic_id, role, text, message_id, timestamp) "
120
+ "VALUES (?, ?, ?, ?, ?)",
121
+ (1, "user", "ancient", None, 0), # epoch 0 — very old
122
+ )
123
+ conn.commit()
124
+ conn.close()
125
+ record_inbound(td, topic_id=1, text="recent")
126
+ removed = prune(td, older_than_days=30)
127
+ self.assertEqual(removed, 1)
128
+ history = recent_messages(td, topic_id=1)
129
+ self.assertEqual([m.text for m in history], ["recent"])
130
+
131
+
132
+ class TestTopicStats(unittest.TestCase):
133
+ def test_stats_groups_per_topic(self):
134
+ with tempfile.TemporaryDirectory() as td:
135
+ record_inbound(td, topic_id=1, text="a")
136
+ record_inbound(td, topic_id=1, text="b")
137
+ record_outbound(td, topic_id=1, text="c")
138
+ record_inbound(td, topic_id=2, text="x")
139
+ stats = topic_stats(td)
140
+ by_topic = {s["topic_id"]: s for s in stats}
141
+ self.assertEqual(by_topic[1]["messages"], 3)
142
+ self.assertEqual(by_topic[2]["messages"], 1)
143
+
144
+
145
+ class TestDaemonDMRefusal(unittest.TestCase):
146
+ """The daemon must refuse to start a mission from a DM."""
147
+ def test_dm_message_is_refused(self):
148
+ from omega_engine.daemons.telegram import _route_one
149
+
150
+ class _FakeBridge:
151
+ def __init__(self):
152
+ self.calls: list[dict] = []
153
+ def _call(self, method, fields, **_kw):
154
+ self.calls.append({"method": method, "fields": fields})
155
+ return {"message_id": 1}
156
+
157
+ class _FakeSupervisor:
158
+ def on_channel_message(self, topic_id, text):
159
+ return []
160
+
161
+ with tempfile.TemporaryDirectory() as td:
162
+ home = Path(td)
163
+ bridge = _FakeBridge()
164
+ tag = _route_one(
165
+ topic_id=None, text="hi from DM",
166
+ message_id=5, chat_id=12345,
167
+ supervisor=_FakeSupervisor(),
168
+ project_map={},
169
+ home=home,
170
+ telegram_bridge=bridge,
171
+ )
172
+ self.assertEqual(tag, "dm:refused")
173
+ # We replied to the user with the redirect message.
174
+ self.assertEqual(len(bridge.calls), 1)
175
+ self.assertEqual(bridge.calls[0]["method"], "sendMessage")
176
+ self.assertEqual(
177
+ str(bridge.calls[0]["fields"]["chat_id"]), "12345",
178
+ )
179
+ self.assertIn("project topic", bridge.calls[0]["fields"]["text"])
180
+
181
+ def test_topic_message_records_history(self):
182
+ from omega_engine.daemons.telegram import _route_one
183
+
184
+ class _FakeBridge: pass
185
+ class _FakeSupervisor:
186
+ def on_channel_message(self, topic_id, text):
187
+ return []
188
+
189
+ with tempfile.TemporaryDirectory() as td:
190
+ home = Path(td)
191
+ # No project mapped → topic:unknown path. But the inbound
192
+ # message should still be recorded.
193
+ tag = _route_one(
194
+ topic_id=99, text="curious question",
195
+ message_id=11, chat_id=12345,
196
+ supervisor=_FakeSupervisor(),
197
+ project_map={},
198
+ home=home,
199
+ telegram_bridge=_FakeBridge(),
200
+ )
201
+ self.assertEqual(tag, "topic:unknown")
202
+ history = recent_messages(home, topic_id=99)
203
+ self.assertEqual(len(history), 1)
204
+ self.assertEqual(history[0].text, "curious question")
205
+ self.assertEqual(history[0].role, "user")
206
+
207
+
208
+ if __name__ == "__main__":
209
+ unittest.main(verbosity=2)
@@ -0,0 +1,223 @@
1
+ """Tests for the tmux orchestrator + AISB chat-loop fallback."""
2
+ from __future__ import annotations
3
+
4
+ import sys
5
+ import tempfile
6
+ import unittest
7
+ from pathlib import Path
8
+ from unittest import mock
9
+
10
+
11
+ HERE = Path(__file__).resolve().parent
12
+ sys.path.insert(0, str(HERE.parent))
13
+
14
+ from omega_engine import tmux # noqa: E402
15
+
16
+
17
+ # ---------------------------------------------------------------------------
18
+ # Categorisation
19
+ # ---------------------------------------------------------------------------
20
+
21
+
22
+ class TestCategorize(unittest.TestCase):
23
+ def test_aisb(self):
24
+ for n in ("AISB-master", "AISB-ORACLE", "aisb-chat"):
25
+ self.assertEqual(tmux.categorize(n), "aisb")
26
+
27
+ def test_oracle(self):
28
+ for n in ("Kommu-oracle", "DentistryGPT-oracle-2",
29
+ "AgentikOS-oracle"):
30
+ self.assertEqual(tmux.categorize(n), "oracle")
31
+
32
+ def test_worker(self):
33
+ for n in ("Kommu-worker-1-audit-codeaudit",
34
+ "DentistryGPT-worker-2-fix-login",
35
+ "Project-oracle-2-worker-1-task"):
36
+ self.assertEqual(tmux.categorize(n), "worker")
37
+
38
+ def test_dev(self):
39
+ for n in ("Causio-dev-feat", "Causio-fix-CAU-42", "K-work-x"):
40
+ self.assertEqual(tmux.categorize(n), "dev")
41
+
42
+ def test_linear(self):
43
+ self.assertEqual(tmux.categorize("Kommu-linear"), "linear")
44
+
45
+ def test_home(self):
46
+ for n in ("Home", "Home-2", "Home-3"):
47
+ self.assertEqual(tmux.categorize(n), "home")
48
+
49
+ def test_other(self):
50
+ for n in ("misc", "ssh-tunnel", "random-session-name"):
51
+ self.assertEqual(tmux.categorize(n), "other")
52
+
53
+ def test_project_extraction(self):
54
+ self.assertEqual(tmux.project_from("Kommu-oracle"), "Kommu")
55
+ self.assertEqual(tmux.project_from("DentistryGPT-worker-1-x"),
56
+ "DentistryGPT")
57
+ self.assertEqual(tmux.project_from("Causio-fix-CAU-42"), "Causio")
58
+ self.assertIsNone(tmux.project_from("Home"))
59
+
60
+
61
+ # ---------------------------------------------------------------------------
62
+ # Subprocess wrapper (mocked)
63
+ # ---------------------------------------------------------------------------
64
+
65
+
66
+ def _fake_proc(stdout: str, returncode: int = 0):
67
+ import subprocess
68
+ return subprocess.CompletedProcess(args=[], returncode=returncode,
69
+ stdout=stdout, stderr="")
70
+
71
+
72
+ class TestListSessions(unittest.TestCase):
73
+ def test_list_empty_when_tmux_missing(self):
74
+ with mock.patch("shutil.which", return_value=None):
75
+ sessions = tmux.list_sessions()
76
+ self.assertEqual(sessions, [])
77
+
78
+ def test_list_parses_format(self):
79
+ # Two sessions: Kommu-oracle (detached, 2 windows), Home (attached)
80
+ canned = (
81
+ "Kommu-oracle\t0\t2\t1700000000\n"
82
+ "Home\t1\t1\t1700000100\n"
83
+ )
84
+ with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
85
+ mock.patch("subprocess.run", return_value=_fake_proc(canned, 0)):
86
+ sessions = tmux.list_sessions()
87
+ self.assertEqual(len(sessions), 2)
88
+ self.assertEqual(sessions[0].name, "Kommu-oracle")
89
+ self.assertEqual(sessions[0].category, "oracle")
90
+ self.assertEqual(sessions[0].project, "Kommu")
91
+ self.assertFalse(sessions[0].attached)
92
+ self.assertEqual(sessions[0].windows, 2)
93
+ self.assertTrue(sessions[1].attached)
94
+ self.assertEqual(sessions[1].category, "home")
95
+
96
+
97
+ class TestSpawn(unittest.TestCase):
98
+ def test_refuses_existing_session(self):
99
+ with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
100
+ mock.patch("subprocess.run", return_value=_fake_proc("", 0)):
101
+ # is_alive returns True (rc=0) so spawn refuses.
102
+ self.assertFalse(tmux.spawn("Kommu-oracle"))
103
+
104
+ def test_spawn_oracle_naming(self):
105
+ captured: list = []
106
+
107
+ def fake_run(cmd, **kw):
108
+ captured.append(cmd)
109
+ # First call (has-session) returns 1 (not alive).
110
+ # Second call (new-session) returns 0.
111
+ rc = 1 if "has-session" in cmd else 0
112
+ return _fake_proc("", rc)
113
+
114
+ with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
115
+ mock.patch("subprocess.run", side_effect=fake_run):
116
+ name = tmux.spawn_oracle("Kommu")
117
+ self.assertEqual(name, "Kommu-oracle")
118
+ # The new-session command carries the right session name
119
+ new_session_cmd = next(c for c in captured if "new-session" in c)
120
+ self.assertIn("Kommu-oracle", new_session_cmd)
121
+
122
+ def test_spawn_worker_with_oracle_id(self):
123
+ with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
124
+ mock.patch("subprocess.run", return_value=_fake_proc("", 1)):
125
+ n1 = tmux.spawn_worker("Kommu", "audit-codeaudit",
126
+ worker_id=1, oracle_id=1)
127
+ n2 = tmux.spawn_worker("Kommu", "audit-secaudit",
128
+ worker_id=1, oracle_id=2)
129
+ self.assertEqual(n1, "Kommu-worker-1-audit-codeaudit")
130
+ self.assertEqual(n2, "Kommu-oracle-2-worker-1-audit-secaudit")
131
+
132
+
133
+ class TestHealth(unittest.TestCase):
134
+ def test_health_without_tmux(self):
135
+ with mock.patch("shutil.which", return_value=None):
136
+ r = tmux.health_report()
137
+ self.assertFalse(r["tmux_installed"])
138
+
139
+ def test_health_groups_categories(self):
140
+ canned = (
141
+ "AISB-master\t0\t1\t1700000000\n"
142
+ "Kommu-oracle\t0\t1\t1700000000\n"
143
+ "Kommu-worker-1-codeaudit\t0\t1\t1700000000\n"
144
+ )
145
+ with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
146
+ mock.patch("subprocess.run", return_value=_fake_proc(canned, 0)):
147
+ r = tmux.health_report()
148
+ self.assertEqual(r["sessions"], 3)
149
+ self.assertIn("oracle", r["by_category"])
150
+ self.assertIn("worker", r["by_category"])
151
+ self.assertIn("aisb", r["by_category"])
152
+
153
+
154
+ class TestCleanupStale(unittest.TestCase):
155
+ def test_dry_run_lists_but_no_kill(self):
156
+ # Worker created at epoch 0 → very old.
157
+ canned = "Kommu-worker-1-stuck\t0\t1\t0\n"
158
+ with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
159
+ mock.patch("subprocess.run", return_value=_fake_proc(canned, 0)):
160
+ r = tmux.cleanup_stale(older_than_hours=1, dry_run=True)
161
+ self.assertEqual(r["candidates"], ["Kommu-worker-1-stuck"])
162
+ self.assertEqual(r["killed"], [])
163
+
164
+
165
+ # ---------------------------------------------------------------------------
166
+ # Default config writes a file with the prefix+Z popup
167
+ # ---------------------------------------------------------------------------
168
+
169
+
170
+ class TestDefaultConfig(unittest.TestCase):
171
+ def test_writes_file_with_prefix_z_binding(self):
172
+ with tempfile.TemporaryDirectory() as td:
173
+ path = tmux.write_default_config(Path(td) / "tmux.conf")
174
+ self.assertTrue(path.exists())
175
+ text = path.read_text()
176
+ self.assertIn("bind-key Z", text)
177
+ self.assertIn("omega tmux menu", text)
178
+
179
+
180
+ # ---------------------------------------------------------------------------
181
+ # AISB chat-loop wiring
182
+ # ---------------------------------------------------------------------------
183
+
184
+
185
+ class TestAisbChat(unittest.TestCase):
186
+ def test_chat_records_inbound_and_outbound(self):
187
+ from omega_engine import aisb_chat
188
+ from omega_engine.telegram_history import recent_messages
189
+
190
+ # Mock input(): one user line then /quit.
191
+ responses = iter(["fix the login bug", "/quit"])
192
+
193
+ def fake_input(prompt=""):
194
+ return next(responses)
195
+
196
+ # Mock the provider so we don't actually call Claude.
197
+ class _FakeResult:
198
+ text = "ok, will look into it"
199
+ class _FakeProvider:
200
+ id = "fake"
201
+ def run(self, req): return _FakeResult()
202
+ class _FakeRouter:
203
+ def resolve(self, role): return _FakeProvider()
204
+
205
+ with tempfile.TemporaryDirectory() as td, \
206
+ mock.patch("builtins.input", side_effect=fake_input), \
207
+ mock.patch("omega_engine.router.ModelRouter.auto",
208
+ return_value=_FakeRouter()), \
209
+ mock.patch.dict("os.environ", {"OMEGA_HOME": td}):
210
+ rc = aisb_chat.run_chat_loop()
211
+ self.assertEqual(rc, 0)
212
+ # Assertions MUST be inside the with block — temp dir is
213
+ # deleted on context exit.
214
+ history = recent_messages(td, topic_id=aisb_chat.CHAT_TOPIC)
215
+ self.assertEqual(len(history), 2)
216
+ self.assertEqual(history[0].role, "user")
217
+ self.assertEqual(history[0].text, "fix the login bug")
218
+ self.assertEqual(history[1].role, "bot")
219
+ self.assertEqual(history[1].text, "ok, will look into it")
220
+
221
+
222
+ if __name__ == "__main__":
223
+ unittest.main(verbosity=2)