@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.
- package/README.md +56 -14
- package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
- package/bootstrap/lib/claude-code-settings.py +176 -0
- package/bootstrap/lib/common.sh +457 -1
- package/bootstrap/lib/llm-clis.py +341 -0
- package/bootstrap/lib/manifest-helpers.py +384 -0
- package/bootstrap/lib/steps.sh +1000 -26
- package/bootstrap/manifest.example.yaml +93 -2
- package/bootstrap/templates/aisb/CLAUDE.md +305 -0
- package/bootstrap/templates/aisb/architect.md +204 -0
- package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
- package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
- package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
- package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
- package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
- package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
- package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
- package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
- package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
- package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
- package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
- package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
- package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
- package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
- package/bootstrap/templates/aisb/construct.md +135 -0
- package/bootstrap/templates/aisb/keymaker.md +227 -0
- package/bootstrap/templates/aisb/link.md +170 -0
- package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
- package/bootstrap/templates/aisb/merovingian.md +159 -0
- package/bootstrap/templates/aisb/morpheus.md +243 -0
- package/bootstrap/templates/aisb/neo.md +147 -0
- package/bootstrap/templates/aisb/niobe.md +197 -0
- package/bootstrap/templates/aisb/oracle.md +244 -0
- package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
- package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
- package/bootstrap/templates/aisb/pythia.md +153 -0
- package/bootstrap/templates/aisb/seraph.md +315 -0
- package/bootstrap/templates/aisb/smith.md +202 -0
- package/bootstrap/templates/aisb/zion.md +172 -0
- package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
- package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
- package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
- package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
- package/docs/AUDITS.md +85 -0
- package/docs/COMPLETION-PLAN.md +48 -0
- package/docs/GAP-ANALYSIS.md +214 -0
- package/docs/INSTALL.md +47 -9
- package/docs/MCP-AND-PLUGINS.md +31 -4
- package/docs/SIMULATION.md +171 -0
- package/docs/simulate.sh +211 -0
- package/install.sh +164 -17
- package/omega/Agentik_Engine/README.md +27 -10
- package/omega/Agentik_Engine/omega_engine/__init__.py +212 -2
- package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/account.py +502 -0
- package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
- package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
- package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
- package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
- package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
- package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
- package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
- package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
- package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
- package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
- package/omega/Agentik_Engine/omega_engine/autonomous.py +538 -0
- package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
- package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +4564 -56
- package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
- package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__init__.py +14 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/autonomous.py +56 -0
- package/omega/Agentik_Engine/omega_engine/daemons/engine.py +236 -0
- package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +315 -0
- package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
- package/omega/Agentik_Engine/omega_engine/educators/__init__.py +51 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/artifact.py +65 -0
- package/omega/Agentik_Engine/omega_engine/educators/automation.py +76 -0
- package/omega/Agentik_Engine/omega_engine/educators/base.py +327 -0
- package/omega/Agentik_Engine/omega_engine/educators/claudecode.py +71 -0
- package/omega/Agentik_Engine/omega_engine/educators/connection.py +75 -0
- package/omega/Agentik_Engine/omega_engine/educators/coworker.py +68 -0
- package/omega/Agentik_Engine/omega_engine/educators/loop.py +82 -0
- package/omega/Agentik_Engine/omega_engine/educators/prompt.py +68 -0
- package/omega/Agentik_Engine/omega_engine/educators/skill.py +69 -0
- package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
- package/omega/Agentik_Engine/omega_engine/executor.py +195 -16
- package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
- package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
- package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
- package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
- package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
- package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
- package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
- package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
- package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
- package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
- package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
- package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
- package/omega/Agentik_Engine/omega_engine/mission.py +29 -14
- package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
- package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
- package/omega/Agentik_Engine/omega_engine/provider.py +408 -13
- package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
- package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/__init__.py +21 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/agentic.py +83 -0
- package/omega/Agentik_Engine/omega_engine/rag/base.py +42 -0
- package/omega/Agentik_Engine/omega_engine/rag/corrective.py +119 -0
- package/omega/Agentik_Engine/omega_engine/rag/graph.py +169 -0
- package/omega/Agentik_Engine/omega_engine/rag/hybrid.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/multimodal.py +136 -0
- package/omega/Agentik_Engine/omega_engine/rag/router.py +110 -0
- package/omega/Agentik_Engine/omega_engine/reducer.py +21 -3
- package/omega/Agentik_Engine/omega_engine/router.py +28 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
- package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
- package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
- package/omega/Agentik_Engine/omega_engine/store.py +132 -25
- package/omega/Agentik_Engine/omega_engine/sync.py +445 -0
- package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
- package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
- package/omega/Agentik_Engine/omega_engine/tools.py +272 -0
- package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
- package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
- package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
- package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
- package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
- package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/test_account.py +338 -0
- package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
- package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
- package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
- package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
- package/omega/Agentik_Engine/tests/test_autonomous.py +361 -0
- package/omega/Agentik_Engine/tests/test_educators.py +233 -0
- package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
- package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
- package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
- package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
- package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
- package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
- package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
- package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
- package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
- package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
- package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
- package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
- package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
- package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
- package/omega/Agentik_Engine/tests/test_rag.py +287 -0
- package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
- package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
- package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
- package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
- package/omega/Agentik_Engine/tests/test_snapshot_partial.py +172 -0
- package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
- package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
- package/omega/Agentik_Engine/tests/test_tools_and_sync.py +312 -0
- package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
- package/omega/Agentik_Engine/tests/test_vault.py +173 -0
- package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
- package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
- package/omega/Agentik_Runtime/audits.db +0 -0
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
- package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
- package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
- package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
- package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
- package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
- package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
- package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
- package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
- package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
- package/omega/Agentik_SSOT/skills/rag-route.md +82 -0
- package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
- package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
- package/package.json +2 -2
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""Tests for the Agentik OS native primitives `pursue` and `cadence`.
|
|
2
|
+
|
|
3
|
+
These are the Agentik OS equivalents of Claude Code's bundled /goal and
|
|
4
|
+
/loop, re-implemented as engine primitives that run on the Claude Code Max
|
|
5
|
+
subscription with no per-API-call surcharge. The tests exercise:
|
|
6
|
+
|
|
7
|
+
* `pursue()` — goal-driven loop. Uses the MockProvider so we can drive
|
|
8
|
+
the loop deterministically + a verify_cmd whose exit code we control
|
|
9
|
+
by touching a sentinel file.
|
|
10
|
+
* `cadence` — charter persistence (schedule / list / disable / remove)
|
|
11
|
+
and the round-trip with the autonomous supervisor on disk.
|
|
12
|
+
* `sync` — the directory-based SKILL.md layout is picked up and
|
|
13
|
+
projected to a Claude Code-shaped skills tree.
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import sys
|
|
18
|
+
import tempfile
|
|
19
|
+
import unittest
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
import yaml
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
HERE = Path(__file__).resolve().parent
|
|
26
|
+
sys.path.insert(0, str(HERE.parent))
|
|
27
|
+
|
|
28
|
+
from omega_engine.cadence import ( # noqa: E402
|
|
29
|
+
disable_cadence,
|
|
30
|
+
list_cadences,
|
|
31
|
+
remove_cadence,
|
|
32
|
+
schedule_cadence,
|
|
33
|
+
)
|
|
34
|
+
from omega_engine.done_signal import read_done # noqa: E402
|
|
35
|
+
from omega_engine.provider import MockProvider # noqa: E402
|
|
36
|
+
from omega_engine.pursue import pursue # noqa: E402
|
|
37
|
+
from omega_engine.router import ModelRouter # noqa: E402
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TestPursueSuccessOnFirstIteration(unittest.TestCase):
|
|
41
|
+
def test_verify_passes_first_try(self):
|
|
42
|
+
with tempfile.TemporaryDirectory() as td:
|
|
43
|
+
home = Path(td)
|
|
44
|
+
router = ModelRouter.single(MockProvider())
|
|
45
|
+
result = pursue(
|
|
46
|
+
intent="hello world",
|
|
47
|
+
verify_cmd="true", # always exits 0
|
|
48
|
+
omega_home=home,
|
|
49
|
+
max_iterations=3,
|
|
50
|
+
router=router,
|
|
51
|
+
cwd=str(home),
|
|
52
|
+
)
|
|
53
|
+
self.assertEqual(result.status, "done_clean")
|
|
54
|
+
self.assertEqual(result.iterations, 1)
|
|
55
|
+
self.assertEqual(result.final_verify_exit, 0)
|
|
56
|
+
self.assertTrue(result.log_path.exists())
|
|
57
|
+
self.assertTrue(result.done_path.exists())
|
|
58
|
+
sig = read_done(home, result.task_id)
|
|
59
|
+
self.assertEqual(sig.status, "done_clean")
|
|
60
|
+
self.assertIn("hello world", sig.summary)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class TestPursueExhaustsBudget(unittest.TestCase):
|
|
64
|
+
def test_verify_never_passes_returns_failed(self):
|
|
65
|
+
with tempfile.TemporaryDirectory() as td:
|
|
66
|
+
home = Path(td)
|
|
67
|
+
router = ModelRouter.single(MockProvider())
|
|
68
|
+
result = pursue(
|
|
69
|
+
intent="impossible",
|
|
70
|
+
verify_cmd="false", # always exits 1
|
|
71
|
+
omega_home=home,
|
|
72
|
+
max_iterations=3,
|
|
73
|
+
router=router,
|
|
74
|
+
cwd=str(home),
|
|
75
|
+
)
|
|
76
|
+
self.assertEqual(result.status, "failed")
|
|
77
|
+
self.assertEqual(result.iterations, 3)
|
|
78
|
+
self.assertEqual(result.final_verify_exit, 1)
|
|
79
|
+
# Per-iteration log has 3 lines
|
|
80
|
+
lines = result.log_path.read_text().strip().splitlines()
|
|
81
|
+
self.assertEqual(len(lines), 3)
|
|
82
|
+
sig = read_done(home, result.task_id)
|
|
83
|
+
self.assertEqual(sig.status, "failed")
|
|
84
|
+
self.assertEqual(len(sig.artifacts["attempts"]), 3)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class TestPursueEventualSuccess(unittest.TestCase):
|
|
88
|
+
def test_sentinel_appears_mid_run(self):
|
|
89
|
+
"""A verify_cmd that passes only after a sentinel file exists.
|
|
90
|
+
|
|
91
|
+
We simulate "the agent's edit landed at iter N" by pre-creating the
|
|
92
|
+
sentinel file after the loop starts is impossible (synchronous test),
|
|
93
|
+
so we use a verify_cmd whose first call fails and second call passes
|
|
94
|
+
via a touch in the cmd itself (every odd attempt creates, every even
|
|
95
|
+
attempt reads — but exit-code 0 only when the file already existed).
|
|
96
|
+
"""
|
|
97
|
+
with tempfile.TemporaryDirectory() as td:
|
|
98
|
+
home = Path(td)
|
|
99
|
+
sentinel = home / "GOAL"
|
|
100
|
+
# First call: touch the file, exit 1. Second call: file exists, exit 0.
|
|
101
|
+
verify_cmd = (
|
|
102
|
+
f"test -f {sentinel} || (touch {sentinel} && exit 1)"
|
|
103
|
+
)
|
|
104
|
+
router = ModelRouter.single(MockProvider())
|
|
105
|
+
result = pursue(
|
|
106
|
+
intent="reach the sentinel",
|
|
107
|
+
verify_cmd=verify_cmd,
|
|
108
|
+
omega_home=home,
|
|
109
|
+
max_iterations=5,
|
|
110
|
+
router=router,
|
|
111
|
+
cwd=str(home),
|
|
112
|
+
)
|
|
113
|
+
self.assertEqual(result.status, "done_clean")
|
|
114
|
+
self.assertEqual(result.iterations, 2)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class TestCadenceSchedule(unittest.TestCase):
|
|
118
|
+
def test_schedule_cron_writes_yaml(self):
|
|
119
|
+
with tempfile.TemporaryDirectory() as td:
|
|
120
|
+
home = Path(td)
|
|
121
|
+
path = schedule_cadence(
|
|
122
|
+
intent="ping the API",
|
|
123
|
+
trigger_type="cron",
|
|
124
|
+
schedule="*/5 * * * *",
|
|
125
|
+
omega_home=home,
|
|
126
|
+
)
|
|
127
|
+
self.assertTrue(path.exists())
|
|
128
|
+
data = yaml.safe_load(path.read_text())
|
|
129
|
+
self.assertTrue(data["id"].startswith("cadence-"))
|
|
130
|
+
self.assertEqual(data["trigger"]["type"], "cron")
|
|
131
|
+
self.assertEqual(data["trigger"]["schedule"], "*/5 * * * *")
|
|
132
|
+
self.assertEqual(data["spec"]["intent"], "ping the API")
|
|
133
|
+
self.assertTrue(data["enabled"])
|
|
134
|
+
|
|
135
|
+
def test_schedule_delay_validates_integer(self):
|
|
136
|
+
with tempfile.TemporaryDirectory() as td:
|
|
137
|
+
home = Path(td)
|
|
138
|
+
with self.assertRaises(ValueError):
|
|
139
|
+
schedule_cadence(
|
|
140
|
+
intent="x", trigger_type="delay", schedule="not-int",
|
|
141
|
+
omega_home=home,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def test_schedule_rejects_unknown_trigger(self):
|
|
145
|
+
with tempfile.TemporaryDirectory() as td:
|
|
146
|
+
home = Path(td)
|
|
147
|
+
with self.assertRaises(ValueError):
|
|
148
|
+
schedule_cadence(
|
|
149
|
+
intent="x", trigger_type="hourly", schedule="1",
|
|
150
|
+
omega_home=home,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
def test_list_returns_each_charter(self):
|
|
154
|
+
with tempfile.TemporaryDirectory() as td:
|
|
155
|
+
home = Path(td)
|
|
156
|
+
schedule_cadence("first", "cron", "* * * * *", omega_home=home,
|
|
157
|
+
charter_id="cadence-aaa")
|
|
158
|
+
schedule_cadence("second", "delay", "60", omega_home=home,
|
|
159
|
+
charter_id="cadence-bbb")
|
|
160
|
+
entries = list_cadences(home)
|
|
161
|
+
ids = {e["id"] for e in entries}
|
|
162
|
+
self.assertEqual(ids, {"cadence-aaa", "cadence-bbb"})
|
|
163
|
+
|
|
164
|
+
def test_disable_flips_enabled_field(self):
|
|
165
|
+
with tempfile.TemporaryDirectory() as td:
|
|
166
|
+
home = Path(td)
|
|
167
|
+
schedule_cadence("x", "cron", "* * * * *", omega_home=home,
|
|
168
|
+
charter_id="cadence-x")
|
|
169
|
+
self.assertTrue(disable_cadence("cadence-x", omega_home=home))
|
|
170
|
+
entries = list_cadences(home)
|
|
171
|
+
self.assertFalse(entries[0]["enabled"])
|
|
172
|
+
# Second disable is a no-op.
|
|
173
|
+
self.assertFalse(disable_cadence("cadence-x", omega_home=home))
|
|
174
|
+
|
|
175
|
+
def test_remove_deletes_charter(self):
|
|
176
|
+
with tempfile.TemporaryDirectory() as td:
|
|
177
|
+
home = Path(td)
|
|
178
|
+
schedule_cadence("x", "cron", "* * * * *", omega_home=home,
|
|
179
|
+
charter_id="cadence-x")
|
|
180
|
+
self.assertTrue(remove_cadence("cadence-x", omega_home=home))
|
|
181
|
+
self.assertEqual(list_cadences(home), [])
|
|
182
|
+
self.assertFalse(remove_cadence("cadence-x", omega_home=home))
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class TestSyncSkillProjection(unittest.TestCase):
|
|
186
|
+
def test_directory_layout_projected_to_claude_code(self):
|
|
187
|
+
"""A SKILL.md in a sub-directory must be projected to the native shape."""
|
|
188
|
+
from omega_engine.sync import SyncEngine
|
|
189
|
+
with tempfile.TemporaryDirectory() as td:
|
|
190
|
+
home = Path(td)
|
|
191
|
+
# Source layout: Agentik_SSOT/skills/pursue/SKILL.md (+ supporting)
|
|
192
|
+
src_skill = home / "Agentik_SSOT" / "skills" / "pursue"
|
|
193
|
+
src_skill.mkdir(parents=True)
|
|
194
|
+
(src_skill / "SKILL.md").write_text("---\nname: pursue\n---\n# pursue")
|
|
195
|
+
(src_skill / "examples.md").write_text("an example")
|
|
196
|
+
(src_skill / "scripts").mkdir()
|
|
197
|
+
(src_skill / "scripts" / "helper.sh").write_text("#!/bin/sh\n")
|
|
198
|
+
# Run sync directly against this home.
|
|
199
|
+
outcomes = SyncEngine().sync_all(home)
|
|
200
|
+
# We just need to know the projection didn't crash + skills were written.
|
|
201
|
+
self.assertTrue(any(o.get("skills_written", 0) >= 1 for o in outcomes),
|
|
202
|
+
msg=f"no skill projected; outcomes={outcomes}")
|
|
203
|
+
|
|
204
|
+
def test_flat_layout_still_works(self):
|
|
205
|
+
from omega_engine.sync import SyncEngine
|
|
206
|
+
with tempfile.TemporaryDirectory() as td:
|
|
207
|
+
home = Path(td)
|
|
208
|
+
src_dir = home / "Agentik_SSOT" / "skills"
|
|
209
|
+
src_dir.mkdir(parents=True)
|
|
210
|
+
(src_dir / "legacy.md").write_text("# legacy flat skill")
|
|
211
|
+
outcomes = SyncEngine().sync_all(home)
|
|
212
|
+
self.assertTrue(any(o.get("skills_written", 0) >= 1 for o in outcomes),
|
|
213
|
+
msg=f"flat layout not projected; outcomes={outcomes}")
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
if __name__ == "__main__":
|
|
217
|
+
unittest.main(verbosity=2)
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"""Tests for the multi-RAG subsystem — five real retrievers + router.
|
|
2
|
+
|
|
3
|
+
Every retriever is exercised end-to-end on real data:
|
|
4
|
+
|
|
5
|
+
* HybridRetriever indexes a small corpus into a temp SQLite WAL store and
|
|
6
|
+
the right doc surfaces for a known-good query.
|
|
7
|
+
* GraphRetriever adds typed edges and asserts depth-limited expansion.
|
|
8
|
+
* AgenticRetriever multi-hops on top of HybridRetriever, terminates within
|
|
9
|
+
`max_hops`, and accumulates docs without duplicates.
|
|
10
|
+
* CorrectiveRetriever exercises the refine-on-low-score path (the
|
|
11
|
+
MockProvider returns 40 then 90, so a retry MUST happen).
|
|
12
|
+
* RAGRouter classifies, picks an inner strategy, wraps it in CRAG, and
|
|
13
|
+
returns a `RetrievalResult` with a strategy string that names the pick.
|
|
14
|
+
|
|
15
|
+
Standalone runner: `python3 tests/test_rag.py`. Temp dir cleans up at end.
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import shutil
|
|
20
|
+
import sys
|
|
21
|
+
import tempfile
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
25
|
+
|
|
26
|
+
from omega_engine.provider import MockProvider # noqa: E402
|
|
27
|
+
from omega_engine.rag import ( # noqa: E402
|
|
28
|
+
AgenticRetriever,
|
|
29
|
+
CorrectiveRetriever,
|
|
30
|
+
Document,
|
|
31
|
+
GraphRetriever,
|
|
32
|
+
HybridRetriever,
|
|
33
|
+
RAGRouter,
|
|
34
|
+
RetrievalResult,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Three docs whose lexical and semantic separation is clear enough that a
|
|
39
|
+
# simple BM25+cosine blend should rank the right one first for a focused query.
|
|
40
|
+
_CORPUS: list[Document] = [
|
|
41
|
+
Document(
|
|
42
|
+
id="payments",
|
|
43
|
+
text=("The pricing service computes invoice totals and applies "
|
|
44
|
+
"promotional discounts before sending receipts."),
|
|
45
|
+
metadata={"topic": "billing"},
|
|
46
|
+
),
|
|
47
|
+
Document(
|
|
48
|
+
id="auth",
|
|
49
|
+
text=("The authentication module validates JWT tokens, manages "
|
|
50
|
+
"session refresh, and enforces role-based access control."),
|
|
51
|
+
metadata={"topic": "auth"},
|
|
52
|
+
),
|
|
53
|
+
Document(
|
|
54
|
+
id="telemetry",
|
|
55
|
+
text=("The telemetry layer emits structured events to the SQLite "
|
|
56
|
+
"WAL store and exposes a Prometheus endpoint."),
|
|
57
|
+
metadata={"topic": "ops"},
|
|
58
|
+
),
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _hybrid(tmp_dir: Path, alpha: float = 0.5) -> HybridRetriever:
|
|
63
|
+
"""Helper — build a HybridRetriever with the corpus already indexed."""
|
|
64
|
+
h = HybridRetriever(tmp_dir / "rag.db", alpha=alpha)
|
|
65
|
+
n = h.index(_CORPUS)
|
|
66
|
+
assert n == len(_CORPUS), f"indexed {n}, expected {len(_CORPUS)}"
|
|
67
|
+
return h
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_hybrid_surfaces_the_right_doc():
|
|
71
|
+
tmp = Path(tempfile.mkdtemp(prefix="omega_rag_"))
|
|
72
|
+
h = _hybrid(tmp)
|
|
73
|
+
try:
|
|
74
|
+
result = h.retrieve("how is the JWT session refresh handled?", k=3)
|
|
75
|
+
assert isinstance(result, RetrievalResult)
|
|
76
|
+
assert result.strategy == "hybrid"
|
|
77
|
+
assert result.documents, "expected at least one document"
|
|
78
|
+
# The auth doc is the only one that talks about JWT/session.
|
|
79
|
+
top_ids = [d.id for d in result.documents]
|
|
80
|
+
assert top_ids[0] == "auth", f"got {top_ids}"
|
|
81
|
+
# And every result carries its blended score in metadata.
|
|
82
|
+
assert "score" in result.documents[0].metadata
|
|
83
|
+
# k=3 means we should see up to 3 — never more.
|
|
84
|
+
assert len(result.documents) <= 3
|
|
85
|
+
finally:
|
|
86
|
+
h.close()
|
|
87
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_hybrid_dense_and_sparse_both_contribute():
|
|
91
|
+
"""At alpha=1 (dense only) and alpha=0 (sparse only) the top doc for an
|
|
92
|
+
auth-flavoured query stays the auth doc — both legs are real.
|
|
93
|
+
|
|
94
|
+
Uses dim=4096 because the hashing-trick collision rate at the default
|
|
95
|
+
dim=256 is too high for short documents to reliably separate. In a
|
|
96
|
+
real corpus you'd pick dim per the expected vocabulary size; for a
|
|
97
|
+
3-doc test we want headroom.
|
|
98
|
+
"""
|
|
99
|
+
tmp = Path(tempfile.mkdtemp(prefix="omega_rag_"))
|
|
100
|
+
try:
|
|
101
|
+
for a in (0.0, 1.0):
|
|
102
|
+
h = HybridRetriever(tmp / f"rag_{a}.db", alpha=a, dim=4096)
|
|
103
|
+
h.index(_CORPUS)
|
|
104
|
+
r = h.retrieve("JWT token validation", k=1)
|
|
105
|
+
assert r.documents, f"alpha={a}: empty result"
|
|
106
|
+
assert r.documents[0].id == "auth", (
|
|
107
|
+
f"alpha={a}: top doc was {r.documents[0].id}"
|
|
108
|
+
)
|
|
109
|
+
h.close()
|
|
110
|
+
finally:
|
|
111
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_graph_expansion_and_persistence():
|
|
115
|
+
tmp = Path(tempfile.mkdtemp(prefix="omega_rag_"))
|
|
116
|
+
try:
|
|
117
|
+
g = GraphRetriever(tmp / "graph.json")
|
|
118
|
+
g.add_node("auth", text="authentication service",
|
|
119
|
+
metadata={"owner": "alice"})
|
|
120
|
+
g.add_node("payments", text="payments service",
|
|
121
|
+
metadata={"owner": "bob"})
|
|
122
|
+
g.add_node("billing", text="billing dashboard")
|
|
123
|
+
g.add_node("telemetry", text="metrics + tracing")
|
|
124
|
+
g.add_edge("auth", "payments", "depends_on")
|
|
125
|
+
g.add_edge("payments", "billing", "renders_into")
|
|
126
|
+
g.add_edge("billing", "telemetry", "emits_to")
|
|
127
|
+
|
|
128
|
+
# Depth 1 from auth = direct neighbours only.
|
|
129
|
+
n1 = g.neighbors("auth", depth=1)
|
|
130
|
+
assert "payments" in n1 and "billing" not in n1, n1
|
|
131
|
+
# Depth 2 reaches one more hop.
|
|
132
|
+
n2 = g.neighbors("auth", depth=2)
|
|
133
|
+
assert "billing" in n2 and "telemetry" not in n2, n2
|
|
134
|
+
# Depth 3 spans the whole graph.
|
|
135
|
+
n3 = g.neighbors("auth", depth=3)
|
|
136
|
+
assert {"payments", "billing", "telemetry"}.issubset(set(n3)), n3
|
|
137
|
+
|
|
138
|
+
# Query path: seed picks `auth` (token match), depth=2 expansion.
|
|
139
|
+
r = g.retrieve("what does auth depend on?", k=4, depth=2)
|
|
140
|
+
ids = [d.id for d in r.documents]
|
|
141
|
+
assert "auth" in ids and "payments" in ids, ids
|
|
142
|
+
assert r.strategy == "graph"
|
|
143
|
+
|
|
144
|
+
# Persistence: a fresh GraphRetriever on the same path should see
|
|
145
|
+
# every edge we just wrote.
|
|
146
|
+
g2 = GraphRetriever(tmp / "graph.json")
|
|
147
|
+
assert "billing" in g2.neighbors("payments", depth=1)
|
|
148
|
+
finally:
|
|
149
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def test_agentic_multihop_terminates():
|
|
153
|
+
tmp = Path(tempfile.mkdtemp(prefix="omega_rag_"))
|
|
154
|
+
h = _hybrid(tmp)
|
|
155
|
+
try:
|
|
156
|
+
provider = MockProvider() # rag-agent terminates after 2 calls
|
|
157
|
+
a = AgenticRetriever(h, provider, max_hops=3, k_per_hop=2)
|
|
158
|
+
r = a.retrieve("explain authentication", k=4)
|
|
159
|
+
assert r.strategy == "agentic"
|
|
160
|
+
assert r.documents, "agentic returned no docs"
|
|
161
|
+
# Hop metadata stamped on every doc.
|
|
162
|
+
hops = {d.metadata.get("hop") for d in r.documents}
|
|
163
|
+
# Must have at least one hop and never more than max_hops - 1
|
|
164
|
+
# (since hop indices are 0-based).
|
|
165
|
+
assert hops, "no hop metadata"
|
|
166
|
+
assert max(hops) <= 2, f"hops={hops}"
|
|
167
|
+
# De-duplication: every id appears once.
|
|
168
|
+
ids = [d.id for d in r.documents]
|
|
169
|
+
assert len(ids) == len(set(ids)), f"duplicates in {ids}"
|
|
170
|
+
finally:
|
|
171
|
+
h.close()
|
|
172
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def test_corrective_grades_and_retries_on_low_score():
|
|
176
|
+
"""MockProvider returns 40 (below threshold) then 90 — the Corrective
|
|
177
|
+
envelope MUST call the inner retriever twice."""
|
|
178
|
+
tmp = Path(tempfile.mkdtemp(prefix="omega_rag_"))
|
|
179
|
+
h = _hybrid(tmp)
|
|
180
|
+
try:
|
|
181
|
+
provider = MockProvider()
|
|
182
|
+
c = CorrectiveRetriever(h, provider, threshold=70.0, max_retries=2)
|
|
183
|
+
r = c.retrieve("auth", k=3)
|
|
184
|
+
assert r.documents, "corrective returned no docs"
|
|
185
|
+
assert r.strategy.startswith("corrective+"), r.strategy
|
|
186
|
+
# The grader stamps `grader_avg` on each document; final value must
|
|
187
|
+
# be the SECOND call's score (90), proving the retry happened.
|
|
188
|
+
avgs = {d.metadata.get("grader_avg") for d in r.documents}
|
|
189
|
+
assert avgs == {90.0}, f"grader_avg={avgs} (retry never fired?)"
|
|
190
|
+
# Provider call counter is the most direct proof.
|
|
191
|
+
assert provider._grader_calls == 2, provider._grader_calls
|
|
192
|
+
finally:
|
|
193
|
+
h.close()
|
|
194
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def test_corrective_settles_quickly_when_score_is_already_high():
|
|
198
|
+
"""If the first grade is already above threshold, no retry happens."""
|
|
199
|
+
tmp = Path(tempfile.mkdtemp(prefix="omega_rag_"))
|
|
200
|
+
h = _hybrid(tmp)
|
|
201
|
+
try:
|
|
202
|
+
provider = MockProvider()
|
|
203
|
+
# threshold below the FIRST grade (40) → corrective is satisfied
|
|
204
|
+
# on the first try and never refines.
|
|
205
|
+
c = CorrectiveRetriever(h, provider, threshold=30.0, max_retries=2)
|
|
206
|
+
r = c.retrieve("auth", k=3)
|
|
207
|
+
assert r.documents
|
|
208
|
+
assert provider._grader_calls == 1, provider._grader_calls
|
|
209
|
+
assert r.strategy.startswith("corrective+"), r.strategy
|
|
210
|
+
finally:
|
|
211
|
+
h.close()
|
|
212
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def test_router_classifies_and_wraps_in_corrective():
|
|
216
|
+
tmp = Path(tempfile.mkdtemp(prefix="omega_rag_"))
|
|
217
|
+
h = _hybrid(tmp)
|
|
218
|
+
try:
|
|
219
|
+
g = GraphRetriever(tmp / "graph.json")
|
|
220
|
+
g.add_edge("auth", "payments", "depends_on")
|
|
221
|
+
provider = MockProvider()
|
|
222
|
+
router = RAGRouter(
|
|
223
|
+
strategies={"hybrid": h, "graph": g},
|
|
224
|
+
provider=provider,
|
|
225
|
+
default="hybrid",
|
|
226
|
+
threshold=70.0,
|
|
227
|
+
max_retries=2,
|
|
228
|
+
)
|
|
229
|
+
r = router.retrieve("JWT session refresh", k=3)
|
|
230
|
+
assert isinstance(r, RetrievalResult)
|
|
231
|
+
assert r.documents, "router returned no docs"
|
|
232
|
+
# Strategy string names the inner pick AND the corrective wrap.
|
|
233
|
+
assert r.strategy.startswith("router(")
|
|
234
|
+
assert "corrective+" in r.strategy, r.strategy
|
|
235
|
+
# Provider override returned "hybrid", and the heuristic also
|
|
236
|
+
# defaults to hybrid for this query — so the inner pick is hybrid.
|
|
237
|
+
assert "router(hybrid)" in r.strategy, r.strategy
|
|
238
|
+
finally:
|
|
239
|
+
h.close()
|
|
240
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def test_router_heuristic_picks_graph_for_relational_query():
|
|
244
|
+
tmp = Path(tempfile.mkdtemp(prefix="omega_rag_"))
|
|
245
|
+
h = _hybrid(tmp)
|
|
246
|
+
try:
|
|
247
|
+
g = GraphRetriever(tmp / "graph.json")
|
|
248
|
+
g.add_edge("auth", "payments", "depends_on")
|
|
249
|
+
|
|
250
|
+
# Stub provider that returns no override → heuristic decides.
|
|
251
|
+
class HeuristicOnlyProvider(MockProvider):
|
|
252
|
+
def run(self, req): # type: ignore[override]
|
|
253
|
+
if req.role == "rag-route":
|
|
254
|
+
# Return empty artifact so router falls back to heuristic.
|
|
255
|
+
from omega_engine.provider import AgentResult
|
|
256
|
+
return AgentResult(text="no override", claimed_done=True,
|
|
257
|
+
artifacts={})
|
|
258
|
+
return super().run(req)
|
|
259
|
+
|
|
260
|
+
provider = HeuristicOnlyProvider()
|
|
261
|
+
router = RAGRouter(
|
|
262
|
+
strategies={"hybrid": h, "graph": g},
|
|
263
|
+
provider=provider,
|
|
264
|
+
corrective=False, # disable corrective for cleaner assertion
|
|
265
|
+
)
|
|
266
|
+
# Query has "depend" and "between" — graph heuristic must fire.
|
|
267
|
+
chosen = router.classify("what does auth depend on?")
|
|
268
|
+
assert chosen == "graph", chosen
|
|
269
|
+
finally:
|
|
270
|
+
h.close()
|
|
271
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def _run_all() -> bool:
|
|
275
|
+
tests = [v for k, v in sorted(globals().items())
|
|
276
|
+
if k.startswith("test_") and callable(v)]
|
|
277
|
+
passed = 0
|
|
278
|
+
for t in tests:
|
|
279
|
+
t()
|
|
280
|
+
print(f" PASS {t.__name__}")
|
|
281
|
+
passed += 1
|
|
282
|
+
print(f"\n{passed}/{len(tests)} rag tests passed")
|
|
283
|
+
return passed == len(tests)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
if __name__ == "__main__":
|
|
287
|
+
sys.exit(0 if _run_all() else 1)
|