@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,158 @@
1
+ """Agent prompt loader — the bridge between SSOT and the provider.
2
+
3
+ Every role in the engine (oracle, worker, architect, keymaker, …) has a
4
+ fully-written system prompt living in ``Agentik_SSOT/agents/<suite>/<role>.md``.
5
+ This module locates the file, strips any YAML frontmatter, and returns the
6
+ prompt text for the provider to inject as the ``system`` message.
7
+
8
+ The AISB suite — 13 named agents + the LMC protocol + per-agent checkers —
9
+ is shipped by the installer from ``bootstrap/templates/aisb/``. New suites
10
+ drop into ``Agentik_SSOT/agents/<name>/`` and are picked up by id.
11
+
12
+ Resolution order for a role:
13
+ 1. ``Agentik_SSOT/agents/aisb/<role>.md`` (the AISB suite)
14
+ 2. ``Agentik_SSOT/agents/<any-suite>/<role>.md`` (any other suite)
15
+ 3. None — the provider falls back to a minimal generic envelope.
16
+
17
+ The LMC protocol + shared protocols are concatenated into every agent's
18
+ system prompt so they always know the contract.
19
+ """
20
+ from __future__ import annotations
21
+
22
+ import re
23
+ from functools import lru_cache
24
+ from pathlib import Path
25
+
26
+
27
+ _FRONTMATTER_RE = re.compile(r"^---\s*\n.*?\n---\s*\n", re.DOTALL)
28
+
29
+
30
+ def _strip_frontmatter(text: str) -> str:
31
+ """Drop the leading YAML frontmatter block if present."""
32
+ match = _FRONTMATTER_RE.match(text)
33
+ return text[match.end():] if match else text
34
+
35
+
36
+ def _agents_root(omega_home: Path) -> Path:
37
+ return Path(omega_home) / "Agentik_SSOT" / "agents"
38
+
39
+
40
+ # Topology-name → AISB-suite-name aliases.
41
+ # The orchestration topology YAMLs use generic role names (`aisb`, `oracle`,
42
+ # `manager`, `worker`, `audit`) but the AISB suite ships its own canonical
43
+ # names (`niobe`, `oracle`, `keymaker`, `construct`, `seraph`). Without
44
+ # this map, ``load_agent_prompt("worker")`` returns None and the worker
45
+ # spawns with the engine's generic fallback envelope — losing the rich
46
+ # identity Gareth's home system relies on.
47
+ #
48
+ # Direction is topology → suite. Add entries here when a topology introduces
49
+ # a new role name that maps to an existing suite agent.
50
+ _ROLE_ALIASES: dict[str, str] = {
51
+ "aisb": "niobe", # the matriarch / root scope
52
+ "manager": "keymaker", # the planner
53
+ "worker": "construct", # the executor
54
+ "audit": "seraph", # the verifier
55
+ "verifier": "seraph", # synonym used by some topologies
56
+ "link": "link", # already canonical
57
+ }
58
+
59
+
60
+ @lru_cache(maxsize=64)
61
+ def _read_agent_file(path: str) -> str | None:
62
+ p = Path(path)
63
+ if not p.exists():
64
+ return None
65
+ try:
66
+ return _strip_frontmatter(p.read_text()).strip()
67
+ except OSError:
68
+ return None
69
+
70
+
71
+ def find_agent_file(omega_home: str | Path, role: str) -> Path | None:
72
+ """Return the on-disk path for a role's agent prompt, or None.
73
+
74
+ Resolution order:
75
+ 1. Direct match on the role name in the AISB suite.
76
+ 2. Alias-mapped name (e.g. ``worker`` → ``construct``).
77
+ 3. Direct match in any other suite.
78
+ 4. Alias-mapped match in any other suite.
79
+ """
80
+ root = _agents_root(Path(omega_home))
81
+ if not root.is_dir():
82
+ return None
83
+
84
+ candidates_for_role: list[str] = [role]
85
+ aliased = _ROLE_ALIASES.get(role)
86
+ if aliased and aliased != role:
87
+ candidates_for_role.append(aliased)
88
+
89
+ # 1+2. AISB suite first (the master), with alias fallback.
90
+ aisb_dir = root / "aisb"
91
+ if aisb_dir.is_dir():
92
+ for cand in candidates_for_role:
93
+ p = aisb_dir / f"{cand}.md"
94
+ if p.exists():
95
+ return p
96
+
97
+ # 3+4. Any other suite that names a file after the role (or its alias).
98
+ for suite in sorted(root.iterdir()):
99
+ if not suite.is_dir() or suite.name == "aisb":
100
+ continue
101
+ for cand in candidates_for_role:
102
+ p = suite / f"{cand}.md"
103
+ if p.exists():
104
+ return p
105
+ return None
106
+
107
+
108
+ def load_agent_prompt(omega_home: str | Path, role: str) -> str | None:
109
+ """Return the agent's full system prompt, or None if not shipped.
110
+
111
+ Includes the LMC + shared protocols when found, so every loaded agent
112
+ knows the contract without us repeating it in every file.
113
+ """
114
+ path = find_agent_file(omega_home, role)
115
+ if path is None:
116
+ return None
117
+ text = _read_agent_file(str(path))
118
+ if text is None:
119
+ return None
120
+
121
+ # Append any protocol files that live next to the agent.
122
+ suite_dir = path.parent
123
+ extras: list[str] = []
124
+ for proto in ("lmc-protocol.md",):
125
+ proto_path = suite_dir / proto
126
+ body = _read_agent_file(str(proto_path))
127
+ if body:
128
+ extras.append(f"\n\n--- PROTOCOL: {proto} ---\n\n{body}")
129
+ shared = suite_dir / "protocols" / "shared-protocol.md"
130
+ body = _read_agent_file(str(shared))
131
+ if body:
132
+ extras.append(f"\n\n--- SHARED PROTOCOL ---\n\n{body}")
133
+ return text + "".join(extras)
134
+
135
+
136
+ def list_available_agents(omega_home: str | Path) -> dict[str, list[str]]:
137
+ """Return ``{suite: [roles]}`` for every agent file shipped under
138
+ Agentik_SSOT/agents/."""
139
+ root = _agents_root(Path(omega_home))
140
+ out: dict[str, list[str]] = {}
141
+ if not root.is_dir():
142
+ return out
143
+ for suite in sorted(root.iterdir()):
144
+ if not suite.is_dir():
145
+ continue
146
+ roles = sorted(
147
+ p.stem for p in suite.glob("*.md")
148
+ if not p.stem.startswith(("checker-", "lmc-", "handoff-",
149
+ "shared-", "CLAUDE"))
150
+ )
151
+ if roles:
152
+ out[suite.name] = roles
153
+ return out
154
+
155
+
156
+ def clear_cache() -> None:
157
+ """Drop the prompt-file cache. Useful in tests and after re-installs."""
158
+ _read_agent_file.cache_clear()
@@ -1,12 +1,20 @@
1
1
  """The provider abstraction — one contract, any LLM.
2
2
 
3
3
  The executor talks only to `AgentProvider`. `MockProvider` makes the whole
4
- orchestration testable with no network. `ClaudeProvider` is the real adapter.
4
+ orchestration testable with no network. `ClaudeProvider` wraps Anthropic;
5
+ `GLMProvider`, `OpenAIProvider`, and `DeepSeekProvider` wrap the OpenAI
6
+ chat-completions wire format used by Zhipu/BigModel, OpenAI, and DeepSeek.
7
+
8
+ The real adapters use the stdlib only (`urllib.request`, `json`). They never
9
+ fail at construction — a missing API key only raises when `.run()` is called.
5
10
  """
6
11
  from __future__ import annotations
7
12
 
8
13
  import json
14
+ import os
9
15
  import re
16
+ import urllib.error
17
+ import urllib.request
10
18
  from dataclasses import dataclass, field
11
19
  from typing import Any, Protocol, runtime_checkable
12
20
 
@@ -14,8 +22,10 @@ from typing import Any, Protocol, runtime_checkable
14
22
  @dataclass
15
23
  class AgentRequest:
16
24
  role: str # "aisb" | "oracle" | "worker" | ...
17
- prompt: str
25
+ prompt: str # the user-facing message
18
26
  context: dict[str, Any] = field(default_factory=dict)
27
+ system: str | None = None # the role-aware system prompt
28
+ # (built by omega_engine.envelope)
19
29
 
20
30
 
21
31
  @dataclass
@@ -36,6 +46,144 @@ class AgentProvider(Protocol):
36
46
  def run(self, req: AgentRequest) -> AgentResult: ...
37
47
 
38
48
 
49
+ class ClaudeMaxProvider:
50
+ """The Claude Code Max subprocess provider — uses the operator's OAuth,
51
+ NOT an API key.
52
+
53
+ Spawns ``claude -p "<prompt>" --output-format json --model <model>`` and
54
+ parses the structured response. Authentication is whatever the
55
+ operator did via ``claude /login`` — no ANTHROPIC_API_KEY needed.
56
+ Token usage AND a real ``total_cost_usd`` are returned directly by
57
+ the Claude Code CLI (calculated against Max account billing).
58
+
59
+ System prompts go via ``--append-system-prompt`` so the envelope's
60
+ rich role-aware prompt still drives the agent.
61
+
62
+ Sessions: when ``session_id`` is set on the request context, we use
63
+ ``--resume <session-id>`` so multi-turn conversations work. The CLI's
64
+ own session-id is returned in the result and propagated back as
65
+ ``result.artifacts["session_id"]``.
66
+
67
+ Use this on any machine where ``claude`` CLI is installed and the
68
+ operator is logged in (verified via ``claude --version``).
69
+ """
70
+
71
+ id = "claude-max"
72
+
73
+ def __init__(
74
+ self,
75
+ model: str = "sonnet",
76
+ timeout_s: int = 600,
77
+ bin_path: str = "claude",
78
+ ) -> None:
79
+ self._model = model
80
+ self._timeout_s = timeout_s
81
+ self._bin = bin_path
82
+
83
+ def _model_for(self, role: str) -> str:
84
+ """Resolve the model for a role — explicit > role default > self."""
85
+ # Allow the request itself to override via context.model
86
+ try:
87
+ from omega_engine.worker import default_model_for_role
88
+ role_model = default_model_for_role(role)
89
+ except ImportError:
90
+ role_model = self._model
91
+ return role_model
92
+
93
+ @staticmethod
94
+ def is_available(bin_path: str = "claude") -> bool:
95
+ """True iff `claude` CLI is on PATH and answers --version."""
96
+ import shutil
97
+ if shutil.which(bin_path) is None:
98
+ return False
99
+ try:
100
+ import subprocess
101
+ proc = subprocess.run(
102
+ [bin_path, "--version"],
103
+ check=False, capture_output=True, text=True, timeout=15,
104
+ )
105
+ return proc.returncode == 0
106
+ except (OSError, subprocess.SubprocessError):
107
+ return False
108
+
109
+ def run(self, req: AgentRequest) -> AgentResult:
110
+ import subprocess
111
+ # Per-request model: explicit context.model > role default > self default
112
+ model = (req.context or {}).get("model") or self._model_for(req.role)
113
+ cmd = [
114
+ self._bin, "-p", req.prompt,
115
+ "--output-format", "json",
116
+ "--model", model,
117
+ # bypass tool-permission dialogs in headless mode — operator
118
+ # already set the default permission mode via settings.json
119
+ "--dangerously-skip-permissions",
120
+ ]
121
+ # The envelope's `system` becomes an --append-system-prompt so the
122
+ # default Claude Code system prompt + our role-specific identity +
123
+ # contract all merge.
124
+ if req.system:
125
+ cmd += ["--append-system-prompt", req.system]
126
+ # If the caller passes a session_id in the context, resume that
127
+ # session — turns the provider into a stateful conversation.
128
+ sid = (req.context or {}).get("session_id")
129
+ if sid:
130
+ cmd += ["--resume", str(sid)]
131
+
132
+ try:
133
+ proc = subprocess.run(
134
+ cmd, check=False, capture_output=True, text=True,
135
+ timeout=self._timeout_s,
136
+ )
137
+ except subprocess.TimeoutExpired:
138
+ raise RuntimeError(
139
+ f"claude -p timed out after {self._timeout_s}s"
140
+ )
141
+ if proc.returncode != 0:
142
+ raise RuntimeError(
143
+ f"claude -p exit {proc.returncode}: "
144
+ f"{(proc.stderr or proc.stdout or '').strip()[:500]}"
145
+ )
146
+
147
+ raw_text = (proc.stdout or "").strip()
148
+ try:
149
+ data = json.loads(raw_text)
150
+ except json.JSONDecodeError:
151
+ raise RuntimeError(
152
+ f"claude -p returned non-JSON: {raw_text[:200]}"
153
+ )
154
+
155
+ text = str(data.get("result", ""))
156
+ usage_in = data.get("usage", {}) or {}
157
+ artifacts: dict[str, Any] = {
158
+ "session_id": data.get("session_id", ""),
159
+ "stop_reason": data.get("stop_reason", ""),
160
+ "num_turns": int(data.get("num_turns", 0) or 0),
161
+ "duration_ms": int(data.get("duration_ms", 0) or 0),
162
+ "total_cost_usd": float(data.get("total_cost_usd", 0.0) or 0.0),
163
+ }
164
+ # Dispatcher roles still need to surface a plan when they
165
+ # produced one. Try a JSON parse of the text body.
166
+ plan = (
167
+ _extract_plan(text)
168
+ if req.role in ("aisb", "oracle", "manager") else []
169
+ )
170
+ return AgentResult(
171
+ text=text, claimed_done=True, plan=plan, artifacts=artifacts,
172
+ usage={
173
+ "input_tokens": int(usage_in.get("input_tokens", 0) or 0),
174
+ "output_tokens": int(usage_in.get("output_tokens", 0) or 0),
175
+ "cache_read_input_tokens": int(
176
+ usage_in.get("cache_read_input_tokens", 0) or 0
177
+ ),
178
+ "cache_creation_input_tokens": int(
179
+ usage_in.get("cache_creation_input_tokens", 0) or 0
180
+ ),
181
+ # Real Max cost — calculated by Claude Code itself.
182
+ "cost_usd": float(data.get("total_cost_usd", 0.0) or 0.0),
183
+ },
184
+ )
185
+
186
+
39
187
  class MockProvider:
40
188
  """Deterministic provider — makes the executor fully testable with no API.
41
189
 
@@ -47,6 +195,8 @@ class MockProvider:
47
195
 
48
196
  def __init__(self, plan_size: int = 2) -> None:
49
197
  self._plan_size = plan_size
198
+ self._grader_calls = 0
199
+ self._agent_calls = 0
50
200
 
51
201
  def run(self, req: AgentRequest) -> AgentResult:
52
202
  role = req.role
@@ -75,6 +225,67 @@ class MockProvider:
75
225
  "summary": "mock forensic audit — no falsifiable claims found",
76
226
  "findings": [], "fix_plan": [],
77
227
  }})
228
+ if role == "educator" or role.startswith("educator-"):
229
+ # a structured generation result — what the Educators expect.
230
+ # The mock returns a plausible artifact + self-critique score so the
231
+ # promotion pipeline has something real to gate on.
232
+ intent = req.context.get("intent", "generate")
233
+ kind = req.context.get("kind", "artifact")
234
+ educator = role.split("-", 1)[1] if "-" in role else "educator"
235
+ return AgentResult(
236
+ text=f"educator {educator} produced {kind} for: {intent}",
237
+ claimed_done=True,
238
+ artifacts={"proposal": {
239
+ "kind": kind,
240
+ "content": (
241
+ f"# {kind} for {intent}\n\n"
242
+ f"Generated by mock {educator} educator.\n"
243
+ ),
244
+ "score": 92,
245
+ "summary": f"mock {educator} artifact for '{intent}'",
246
+ "fix_plan": [],
247
+ }})
248
+
249
+ # --- RAG roles ---
250
+ if role == "rag-route":
251
+ # Default to hybrid (matches the architecture's "hybrid is the
252
+ # default" guidance). The router still applies its own heuristic
253
+ # for query-specific overrides.
254
+ return AgentResult(
255
+ text="route: hybrid", claimed_done=True,
256
+ artifacts={"strategy": "hybrid"},
257
+ )
258
+ if role == "rag-agent":
259
+ self._agent_calls += 1
260
+ # Terminate after one refinement hop — bounded behaviour, no loops.
261
+ original = req.context.get("original_query") or req.context.get(
262
+ "current_query", "")
263
+ done = self._agent_calls >= 2
264
+ return AgentResult(
265
+ text="agent step", claimed_done=True,
266
+ artifacts={
267
+ "next_query": f"deeper: {original}",
268
+ "done": done,
269
+ },
270
+ )
271
+ if role == "rag-grader":
272
+ self._grader_calls += 1
273
+ docs = req.context.get("documents", []) or []
274
+ # First call: every doc scores 40 (forces a Corrective retry).
275
+ # Second+ call: every doc scores 90 (lands above the threshold).
276
+ score = 40 if self._grader_calls == 1 else 90
277
+ return AgentResult(
278
+ text=f"graded {len(docs)} docs at {score}",
279
+ claimed_done=True,
280
+ artifacts={"scores": [score for _ in docs] or [score]},
281
+ )
282
+ if role == "rag-caption":
283
+ path = req.context.get("path", "")
284
+ return AgentResult(
285
+ text="captioned", claimed_done=True,
286
+ artifacts={"caption": f"mock caption for {path}"},
287
+ )
288
+
78
289
  return AgentResult(text="ok", claimed_done=True)
79
290
 
80
291
 
@@ -102,17 +313,26 @@ class ClaudeProvider:
102
313
  ) from exc
103
314
 
104
315
  client = anthropic.Anthropic(api_key=self._api_key) # reads env if None
105
- prompt = req.prompt
106
- if req.role in ("oracle", "manager", "aisb"):
107
- prompt += (
108
- "\n\nRespond with a JSON array of subtasks, each "
109
- '{"role":"worker","spec":{"task":"..."}}. JSON only.'
110
- )
111
- msg = client.messages.create(
112
- model=self._model,
113
- max_tokens=4096,
114
- messages=[{"role": "user", "content": prompt}],
115
- )
316
+ # Envelope path: when the executor passes an explicit `system`, use it
317
+ # verbatim and send the user prompt as-is. Otherwise fall back to the
318
+ # legacy single-message form so old callers keep working.
319
+ kwargs: dict[str, Any] = {
320
+ "model": self._model,
321
+ "max_tokens": 4096,
322
+ "messages": [{"role": "user", "content": req.prompt}],
323
+ }
324
+ if req.system:
325
+ kwargs["system"] = req.system
326
+ elif req.role in ("oracle", "manager", "aisb"):
327
+ # Legacy minimal dispatcher hint, only when no envelope was built.
328
+ kwargs["messages"] = [{
329
+ "role": "user",
330
+ "content": req.prompt + (
331
+ "\n\nRespond with a JSON array of subtasks, each "
332
+ '{"role":"worker","spec":{"task":"..."}}. JSON only.'
333
+ ),
334
+ }]
335
+ msg = client.messages.create(**kwargs)
116
336
  text = "".join(
117
337
  b.text for b in msg.content if getattr(b, "type", "") == "text"
118
338
  )
@@ -127,6 +347,181 @@ class ClaudeProvider:
127
347
  )
128
348
 
129
349
 
350
+ # ---------------------------------------------------------------------------
351
+ # OpenAI-compatible providers: GLM (BigModel/Zhipu), OpenAI, DeepSeek.
352
+ #
353
+ # All three speak the same chat-completions wire format. We share one tiny
354
+ # stdlib HTTP transport (`_post_json`) and one response parser, then expose
355
+ # three small adapter classes — each with its own id, default model, env key,
356
+ # and base URL.
357
+ # ---------------------------------------------------------------------------
358
+
359
+ _DEFAULT_TIMEOUT = 120.0
360
+
361
+
362
+ def _post_json(url: str, headers: dict[str, str], body: dict[str, Any],
363
+ timeout: float = _DEFAULT_TIMEOUT) -> dict[str, Any]:
364
+ """POST JSON, return parsed JSON. Raises RuntimeError on protocol errors.
365
+
366
+ Stdlib-only (`urllib.request`) so the providers stay dependency-free.
367
+ """
368
+ data = json.dumps(body).encode("utf-8")
369
+ headers = {"Content-Type": "application/json", **headers}
370
+ req = urllib.request.Request(url, data=data, headers=headers, method="POST")
371
+ try:
372
+ with urllib.request.urlopen(req, timeout=timeout) as resp:
373
+ raw = resp.read().decode("utf-8")
374
+ except urllib.error.HTTPError as exc:
375
+ detail = exc.read().decode("utf-8", errors="replace") if exc.fp else ""
376
+ raise RuntimeError(
377
+ f"HTTP {exc.code} from {url}: {detail[:500]}"
378
+ ) from exc
379
+ except urllib.error.URLError as exc:
380
+ raise RuntimeError(f"network error talking to {url}: {exc.reason}") from exc
381
+ try:
382
+ return json.loads(raw)
383
+ except json.JSONDecodeError as exc:
384
+ raise RuntimeError(
385
+ f"non-JSON response from {url}: {raw[:500]}"
386
+ ) from exc
387
+
388
+
389
+ def _parse_openai_chat_response(payload: dict[str, Any]) -> tuple[str, dict[str, int]]:
390
+ """Pull text + usage from an OpenAI-format chat completion response.
391
+
392
+ Returns ("", {}) if the structure is unexpected, rather than crashing.
393
+ """
394
+ text = ""
395
+ choices = payload.get("choices") or []
396
+ if choices and isinstance(choices, list):
397
+ first = choices[0] or {}
398
+ msg = first.get("message") or {}
399
+ content = msg.get("content")
400
+ if isinstance(content, str):
401
+ text = content
402
+ elif isinstance(content, list):
403
+ # GLM/anthropic-style content blocks: list of {"type": "text", "text": "..."}
404
+ parts: list[str] = []
405
+ for block in content:
406
+ if isinstance(block, dict):
407
+ val = block.get("text") or block.get("content") or ""
408
+ if isinstance(val, str):
409
+ parts.append(val)
410
+ text = "".join(parts)
411
+ usage_raw = payload.get("usage") or {}
412
+ usage = {
413
+ "input_tokens": int(usage_raw.get("prompt_tokens", 0) or 0),
414
+ "output_tokens": int(usage_raw.get("completion_tokens", 0) or 0),
415
+ }
416
+ return text, usage
417
+
418
+
419
+ class _OpenAICompatProvider:
420
+ """Shared transport for OpenAI-format chat completion APIs.
421
+
422
+ Subclasses set `id`, `_default_model`, `_env_var`, `_default_base_url`.
423
+ Construction never fails on missing key — `.run()` raises if it's still
424
+ missing when called.
425
+ """
426
+
427
+ id: str = "openai-compat"
428
+ _default_model: str = ""
429
+ _env_var: str = ""
430
+ _default_base_url: str = ""
431
+
432
+ def __init__(
433
+ self,
434
+ model: str | None = None,
435
+ api_key: str | None = None,
436
+ base_url: str | None = None,
437
+ ) -> None:
438
+ self._model = model or self._default_model
439
+ self._api_key = api_key
440
+ self._base_url = base_url or self._default_base_url
441
+
442
+ def _resolve_key(self) -> str:
443
+ key = self._api_key or os.environ.get(self._env_var)
444
+ if not key:
445
+ raise RuntimeError(
446
+ f"{type(self).__name__} requires an API key. "
447
+ f"Pass api_key=... or set {self._env_var} in the environment."
448
+ )
449
+ return key
450
+
451
+ def _build_messages(self, req: AgentRequest) -> list[dict[str, str]]:
452
+ prompt = req.prompt
453
+ if req.role in ("oracle", "manager", "aisb"):
454
+ prompt = prompt + (
455
+ "\n\nRespond with a JSON array of subtasks, each "
456
+ '{"role":"worker","spec":{"task":"..."}}. JSON only.'
457
+ )
458
+ return [{"role": "user", "content": prompt}]
459
+
460
+ def _extra_body(self) -> dict[str, Any]:
461
+ """Adapter-specific knobs (overridable). Default: no extras."""
462
+ return {}
463
+
464
+ def run(self, req: AgentRequest) -> AgentResult:
465
+ api_key = self._resolve_key()
466
+ body: dict[str, Any] = {
467
+ "model": self._model,
468
+ "messages": self._build_messages(req),
469
+ "max_tokens": 4096,
470
+ }
471
+ body.update(self._extra_body())
472
+ payload = _post_json(
473
+ self._base_url,
474
+ {"Authorization": f"Bearer {api_key}"},
475
+ body,
476
+ )
477
+ text, usage = _parse_openai_chat_response(payload)
478
+ return AgentResult(
479
+ text=text,
480
+ claimed_done=True,
481
+ plan=_extract_plan(text) if req.role in ("oracle", "manager", "aisb") else [],
482
+ usage=usage,
483
+ )
484
+
485
+
486
+ class GLMProvider(_OpenAICompatProvider):
487
+ """Zhipu / BigModel GLM via the OpenAI-compatible chat-completions API.
488
+
489
+ Endpoint: https://open.bigmodel.cn/api/paas/v4/chat/completions
490
+ Env: `GLM_API_KEY`.
491
+ """
492
+
493
+ id = "glm"
494
+ _default_model = "glm-4.6"
495
+ _env_var = "GLM_API_KEY"
496
+ _default_base_url = "https://open.bigmodel.cn/api/paas/v4/chat/completions"
497
+
498
+
499
+ class OpenAIProvider(_OpenAICompatProvider):
500
+ """OpenAI Chat Completions.
501
+
502
+ Endpoint: https://api.openai.com/v1/chat/completions
503
+ Env: `OPENAI_API_KEY`.
504
+ """
505
+
506
+ id = "openai"
507
+ _default_model = "gpt-4o"
508
+ _env_var = "OPENAI_API_KEY"
509
+ _default_base_url = "https://api.openai.com/v1/chat/completions"
510
+
511
+
512
+ class DeepSeekProvider(_OpenAICompatProvider):
513
+ """DeepSeek (OpenAI-compatible chat completions).
514
+
515
+ Endpoint: https://api.deepseek.com/v1/chat/completions
516
+ Env: `DEEPSEEK_API_KEY`.
517
+ """
518
+
519
+ id = "deepseek"
520
+ _default_model = "deepseek-chat"
521
+ _env_var = "DEEPSEEK_API_KEY"
522
+ _default_base_url = "https://api.deepseek.com/v1/chat/completions"
523
+
524
+
130
525
  def _extract_plan(text: str) -> list[dict[str, Any]]:
131
526
  """Pull a JSON subtask array out of an LLM response. Empty list if none."""
132
527
  match = re.search(r"\[.*\]", text, re.DOTALL)