@agentikos/omega-os 0.2.0 → 0.19.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -3
- 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 +790 -21
- package/bootstrap/manifest.example.yaml +87 -1
- 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/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 +4 -2
- package/omega/Agentik_Engine/omega_engine/__init__.py +147 -1
- 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.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_arsenal.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__/barrier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/bus.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__/events.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__/progress.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__/report.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__/supervisor.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__/task.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram.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 +28 -31
- 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/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 +4156 -86
- 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/__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/engine.py +53 -4
- package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +101 -17
- package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -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/envelope.py +219 -0
- package/omega/Agentik_Engine/omega_engine/executor.py +149 -10
- 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 +16 -13
- 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 +161 -12
- 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/__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/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 +88 -41
- package/omega/Agentik_Engine/omega_engine/sync.py +142 -1
- 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/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_audit_arsenal.cpython-313.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_executor.cpython-313.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_mission.cpython-313.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_progress.cpython-313.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_project.cpython-313.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_reducer.cpython-313.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_report.cpython-313.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 +8 -3
- 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_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_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_telegram_history.py +209 -0
- package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -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 +9 -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,189 @@
|
|
|
1
|
+
"""Tests for omega_engine.skill_routing — role → skills resolution + the
|
|
2
|
+
system-prompt skill block.
|
|
3
|
+
|
|
4
|
+
The routing module is pure (no I/O for the role map, single Read for the
|
|
5
|
+
description extraction) so these tests stay fast: ~30 ms total.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
import tempfile
|
|
11
|
+
import unittest
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
HERE = Path(__file__).resolve().parent
|
|
16
|
+
sys.path.insert(0, str(HERE.parent))
|
|
17
|
+
|
|
18
|
+
from omega_engine import skill_routing as SR # noqa: E402
|
|
19
|
+
from omega_engine import worker as W # noqa: E402
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TestRoleDefaults(unittest.TestCase):
|
|
23
|
+
def test_worker_includes_pursue_and_audits(self):
|
|
24
|
+
recs = SR.recommend("worker")
|
|
25
|
+
self.assertIn("pursue", recs)
|
|
26
|
+
self.assertIn("codeaudit", recs)
|
|
27
|
+
self.assertIn("debugaudit", recs)
|
|
28
|
+
|
|
29
|
+
def test_oracle_includes_dispatch(self):
|
|
30
|
+
self.assertIn("dispatch", SR.recommend("oracle"))
|
|
31
|
+
|
|
32
|
+
def test_classifier_is_empty(self):
|
|
33
|
+
self.assertEqual(SR.recommend("classifier"), [])
|
|
34
|
+
|
|
35
|
+
def test_unknown_role_returns_empty_list(self):
|
|
36
|
+
self.assertEqual(SR.recommend("does-not-exist"), [])
|
|
37
|
+
|
|
38
|
+
def test_recommend_returns_copy(self):
|
|
39
|
+
# Mutating the return value must not pollute the global map.
|
|
40
|
+
a = SR.recommend("worker")
|
|
41
|
+
a.append("garbage")
|
|
42
|
+
self.assertNotIn("garbage", SR.recommend("worker"))
|
|
43
|
+
|
|
44
|
+
def test_power_skills_listed(self):
|
|
45
|
+
# The constant exists, includes the obvious ones, has stable ordering.
|
|
46
|
+
self.assertIn("dispatch", SR.POWER_SKILLS)
|
|
47
|
+
self.assertIn("pursue", SR.POWER_SKILLS)
|
|
48
|
+
self.assertIn("codeaudit", SR.POWER_SKILLS)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class TestResolution(unittest.TestCase):
|
|
52
|
+
def test_explicit_wins(self):
|
|
53
|
+
out = SR.skills_for("worker", explicit=["only-this"])
|
|
54
|
+
self.assertEqual(out, ["only-this"])
|
|
55
|
+
|
|
56
|
+
def test_topology_wins_over_role_default(self):
|
|
57
|
+
out = SR.skills_for("worker", topology_skills=["mission-skill"])
|
|
58
|
+
self.assertEqual(out, ["mission-skill"])
|
|
59
|
+
|
|
60
|
+
def test_explicit_wins_over_topology(self):
|
|
61
|
+
out = SR.skills_for("worker", explicit=["a"], topology_skills=["b"])
|
|
62
|
+
self.assertEqual(out, ["a"])
|
|
63
|
+
|
|
64
|
+
def test_falls_back_to_role_default(self):
|
|
65
|
+
out = SR.skills_for("oracle")
|
|
66
|
+
self.assertIn("dispatch", out)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class TestCatalog(unittest.TestCase):
|
|
70
|
+
def test_empty_home_returns_empty(self):
|
|
71
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
72
|
+
self.assertEqual(SR.catalog_for_home(tmp), [])
|
|
73
|
+
|
|
74
|
+
def test_lists_skill_dirs_and_files(self):
|
|
75
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
76
|
+
root = Path(tmp) / "Agentik_SSOT" / "skills"
|
|
77
|
+
(root / "pursue").mkdir(parents=True)
|
|
78
|
+
(root / "pursue" / "SKILL.md").write_text("---\nname: pursue\n---")
|
|
79
|
+
(root / "codeaudit").mkdir()
|
|
80
|
+
(root / "codeaudit" / "SKILL.md").write_text("---\nname: codeaudit\n---")
|
|
81
|
+
(root / "no-skillmd").mkdir() # not a real skill, must be skipped
|
|
82
|
+
(root / "rag-route.md").write_text("---\nname: rag-route\n---")
|
|
83
|
+
out = SR.catalog_for_home(tmp)
|
|
84
|
+
self.assertIn("pursue", out)
|
|
85
|
+
self.assertIn("codeaudit", out)
|
|
86
|
+
self.assertIn("rag-route", out)
|
|
87
|
+
self.assertNotIn("no-skillmd", out)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class TestSkillBlock(unittest.TestCase):
|
|
91
|
+
def test_empty_returns_empty(self):
|
|
92
|
+
self.assertEqual(SR.format_skill_block([]), "")
|
|
93
|
+
|
|
94
|
+
def test_block_lists_skill_ids_and_header(self):
|
|
95
|
+
block = SR.format_skill_block(["pursue", "codeaudit"])
|
|
96
|
+
self.assertIn("## Skills available", block)
|
|
97
|
+
self.assertIn("/pursue", block)
|
|
98
|
+
self.assertIn("/codeaudit", block)
|
|
99
|
+
self.assertIn("invoke them as slash", block)
|
|
100
|
+
|
|
101
|
+
def test_block_includes_descriptions_when_skillmd_present(self):
|
|
102
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
103
|
+
root = Path(tmp) / "Agentik_SSOT" / "skills"
|
|
104
|
+
(root / "pursue").mkdir(parents=True)
|
|
105
|
+
(root / "pursue" / "SKILL.md").write_text(
|
|
106
|
+
"---\nname: pursue\n"
|
|
107
|
+
"description: Goal-driven loop until verify exits 0.\n"
|
|
108
|
+
"---\n# pursue\n"
|
|
109
|
+
)
|
|
110
|
+
block = SR.format_skill_block(["pursue"], home=tmp)
|
|
111
|
+
self.assertIn("Goal-driven loop", block)
|
|
112
|
+
|
|
113
|
+
def test_description_too_long_is_truncated(self):
|
|
114
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
115
|
+
root = Path(tmp) / "Agentik_SSOT" / "skills"
|
|
116
|
+
(root / "huge").mkdir(parents=True)
|
|
117
|
+
long_desc = "x" * 200
|
|
118
|
+
(root / "huge" / "SKILL.md").write_text(
|
|
119
|
+
f"---\nname: huge\ndescription: {long_desc}\n---"
|
|
120
|
+
)
|
|
121
|
+
block = SR.format_skill_block(["huge"], home=tmp)
|
|
122
|
+
self.assertIn("...", block)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class TestWorkerBriefSkills(unittest.TestCase):
|
|
126
|
+
def test_default_role_resolves_to_role_skills(self):
|
|
127
|
+
b = W.WorkerBrief(task_id="t1", role="worker", intent="x")
|
|
128
|
+
skills = b.resolved_skills()
|
|
129
|
+
self.assertIn("pursue", skills)
|
|
130
|
+
|
|
131
|
+
def test_explicit_skills_override(self):
|
|
132
|
+
b = W.WorkerBrief(task_id="t1", role="worker", intent="x",
|
|
133
|
+
skills=["only-this"])
|
|
134
|
+
self.assertEqual(b.resolved_skills(), ["only-this"])
|
|
135
|
+
|
|
136
|
+
def test_classifier_role_empty_by_default(self):
|
|
137
|
+
b = W.WorkerBrief(task_id="t1", role="classifier", intent="x")
|
|
138
|
+
self.assertEqual(b.resolved_skills(), [])
|
|
139
|
+
|
|
140
|
+
def test_json_round_trip_preserves_skills(self):
|
|
141
|
+
import json
|
|
142
|
+
b = W.WorkerBrief(task_id="t1", role="worker", intent="x",
|
|
143
|
+
skills=["pursue", "codeaudit"])
|
|
144
|
+
loaded = W.WorkerBrief.from_dict(json.loads(b.to_json()))
|
|
145
|
+
self.assertEqual(loaded.skills, ["pursue", "codeaudit"])
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class TestRunBriefEmbedsSkillBlock(unittest.TestCase):
|
|
149
|
+
"""When the brief carries skills, the system_prompt sent to claude
|
|
150
|
+
contains the skill block."""
|
|
151
|
+
|
|
152
|
+
def test_system_prompt_includes_skill_section(self):
|
|
153
|
+
import json as _json
|
|
154
|
+
from unittest import mock
|
|
155
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
156
|
+
home = Path(tmp)
|
|
157
|
+
brief = W.WorkerBrief(
|
|
158
|
+
task_id="t-sk", role="worker", intent="x",
|
|
159
|
+
skills=["pursue", "codeaudit"],
|
|
160
|
+
)
|
|
161
|
+
W.write_brief(home, brief)
|
|
162
|
+
captured = {}
|
|
163
|
+
|
|
164
|
+
def fake_run(cmd, **kw):
|
|
165
|
+
captured["cmd"] = cmd
|
|
166
|
+
import subprocess
|
|
167
|
+
return subprocess.CompletedProcess(
|
|
168
|
+
args=cmd, returncode=0,
|
|
169
|
+
stdout=_json.dumps({
|
|
170
|
+
"result": "ok", "session_id": "s",
|
|
171
|
+
"usage": {}, "total_cost_usd": 0.0,
|
|
172
|
+
}),
|
|
173
|
+
stderr="",
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
with mock.patch.object(W.subprocess, "run", side_effect=fake_run):
|
|
177
|
+
W.run_brief(home, "t-sk")
|
|
178
|
+
cmd = captured["cmd"]
|
|
179
|
+
# --append-system-prompt is present
|
|
180
|
+
self.assertIn("--append-system-prompt", cmd)
|
|
181
|
+
idx = cmd.index("--append-system-prompt")
|
|
182
|
+
block = cmd[idx + 1]
|
|
183
|
+
self.assertIn("## Skills available", block)
|
|
184
|
+
self.assertIn("/pursue", block)
|
|
185
|
+
self.assertIn("/codeaudit", block)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
if __name__ == "__main__":
|
|
189
|
+
unittest.main()
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"""Tests for the per-topic conversation-history layer.
|
|
2
|
+
|
|
3
|
+
The Telegram daemon used to forget everything between turns. This module
|
|
4
|
+
adds a SQLite-backed history. The tests verify the round-trip, the
|
|
5
|
+
chronological ordering, the context-prompt builder, and the DM refusal
|
|
6
|
+
path in the daemon router.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
import tempfile
|
|
12
|
+
import time
|
|
13
|
+
import unittest
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from unittest import mock
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
HERE = Path(__file__).resolve().parent
|
|
19
|
+
sys.path.insert(0, str(HERE.parent))
|
|
20
|
+
|
|
21
|
+
from omega_engine.telegram_history import ( # noqa: E402
|
|
22
|
+
Message,
|
|
23
|
+
build_context_prompt,
|
|
24
|
+
prune,
|
|
25
|
+
record_inbound,
|
|
26
|
+
record_outbound,
|
|
27
|
+
recent_messages,
|
|
28
|
+
topic_stats,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TestRecordAndRecent(unittest.TestCase):
|
|
33
|
+
def test_round_trip(self):
|
|
34
|
+
with tempfile.TemporaryDirectory() as td:
|
|
35
|
+
record_inbound(td, topic_id=42, text="hi", message_id=1)
|
|
36
|
+
record_outbound(td, topic_id=42, text="hello", message_id=2)
|
|
37
|
+
history = recent_messages(td, topic_id=42)
|
|
38
|
+
self.assertEqual(len(history), 2)
|
|
39
|
+
self.assertEqual(history[0].role, "user")
|
|
40
|
+
self.assertEqual(history[0].text, "hi")
|
|
41
|
+
self.assertEqual(history[1].role, "bot")
|
|
42
|
+
self.assertEqual(history[1].text, "hello")
|
|
43
|
+
|
|
44
|
+
def test_recent_is_chronological(self):
|
|
45
|
+
with tempfile.TemporaryDirectory() as td:
|
|
46
|
+
for i in range(5):
|
|
47
|
+
record_inbound(td, topic_id=7, text=f"msg{i}")
|
|
48
|
+
time.sleep(0.01)
|
|
49
|
+
history = recent_messages(td, topic_id=7)
|
|
50
|
+
self.assertEqual(
|
|
51
|
+
[m.text for m in history],
|
|
52
|
+
["msg0", "msg1", "msg2", "msg3", "msg4"],
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def test_recent_respects_limit(self):
|
|
56
|
+
with tempfile.TemporaryDirectory() as td:
|
|
57
|
+
for i in range(20):
|
|
58
|
+
record_inbound(td, topic_id=8, text=f"m{i}")
|
|
59
|
+
history = recent_messages(td, topic_id=8, limit=5)
|
|
60
|
+
self.assertEqual(len(history), 5)
|
|
61
|
+
# The 5 most recent, in chronological order.
|
|
62
|
+
self.assertEqual(
|
|
63
|
+
[m.text for m in history],
|
|
64
|
+
["m15", "m16", "m17", "m18", "m19"],
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def test_topics_are_isolated(self):
|
|
68
|
+
with tempfile.TemporaryDirectory() as td:
|
|
69
|
+
record_inbound(td, topic_id=1, text="topic1-a")
|
|
70
|
+
record_inbound(td, topic_id=2, text="topic2-a")
|
|
71
|
+
t1 = recent_messages(td, topic_id=1)
|
|
72
|
+
t2 = recent_messages(td, topic_id=2)
|
|
73
|
+
self.assertEqual([m.text for m in t1], ["topic1-a"])
|
|
74
|
+
self.assertEqual([m.text for m in t2], ["topic2-a"])
|
|
75
|
+
|
|
76
|
+
def test_record_rejects_unknown_role(self):
|
|
77
|
+
with tempfile.TemporaryDirectory() as td:
|
|
78
|
+
from omega_engine.telegram_history import _record
|
|
79
|
+
with self.assertRaises(ValueError):
|
|
80
|
+
_record(td, topic_id=1, role="alien", text="x", message_id=None)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class TestContextPrompt(unittest.TestCase):
|
|
84
|
+
def test_cold_topic_returns_intent_unchanged(self):
|
|
85
|
+
with tempfile.TemporaryDirectory() as td:
|
|
86
|
+
out = build_context_prompt(td, topic_id=99, new_intent="hello")
|
|
87
|
+
self.assertEqual(out, "hello")
|
|
88
|
+
|
|
89
|
+
def test_warm_topic_prepends_history(self):
|
|
90
|
+
with tempfile.TemporaryDirectory() as td:
|
|
91
|
+
record_inbound(td, topic_id=1, text="please fix the login bug")
|
|
92
|
+
record_outbound(td, topic_id=1, text="ok, I'm starting now")
|
|
93
|
+
out = build_context_prompt(td, topic_id=1,
|
|
94
|
+
new_intent="any progress?")
|
|
95
|
+
self.assertIn("Conversation history in topic 1", out)
|
|
96
|
+
self.assertIn("please fix the login bug", out)
|
|
97
|
+
self.assertIn("ok, I'm starting now", out)
|
|
98
|
+
self.assertIn("any progress?", out)
|
|
99
|
+
self.assertIn("user (just now)", out)
|
|
100
|
+
|
|
101
|
+
def test_context_format_carries_roles_and_age(self):
|
|
102
|
+
with tempfile.TemporaryDirectory() as td:
|
|
103
|
+
record_inbound(td, topic_id=2, text="how do I configure age?")
|
|
104
|
+
out = build_context_prompt(td, topic_id=2,
|
|
105
|
+
new_intent="also tell me about vault")
|
|
106
|
+
# role markers present
|
|
107
|
+
self.assertIn("user (", out)
|
|
108
|
+
# short human-time present (we just wrote it; should be "0s ago" or similar)
|
|
109
|
+
self.assertTrue("ago" in out)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class TestPrune(unittest.TestCase):
|
|
113
|
+
def test_prune_drops_old_rows(self):
|
|
114
|
+
with tempfile.TemporaryDirectory() as td:
|
|
115
|
+
from omega_engine.telegram_history import _connect
|
|
116
|
+
# Inject an artificially old row.
|
|
117
|
+
conn = _connect(td)
|
|
118
|
+
conn.execute(
|
|
119
|
+
"INSERT INTO messages (topic_id, role, text, message_id, timestamp) "
|
|
120
|
+
"VALUES (?, ?, ?, ?, ?)",
|
|
121
|
+
(1, "user", "ancient", None, 0), # epoch 0 — very old
|
|
122
|
+
)
|
|
123
|
+
conn.commit()
|
|
124
|
+
conn.close()
|
|
125
|
+
record_inbound(td, topic_id=1, text="recent")
|
|
126
|
+
removed = prune(td, older_than_days=30)
|
|
127
|
+
self.assertEqual(removed, 1)
|
|
128
|
+
history = recent_messages(td, topic_id=1)
|
|
129
|
+
self.assertEqual([m.text for m in history], ["recent"])
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class TestTopicStats(unittest.TestCase):
|
|
133
|
+
def test_stats_groups_per_topic(self):
|
|
134
|
+
with tempfile.TemporaryDirectory() as td:
|
|
135
|
+
record_inbound(td, topic_id=1, text="a")
|
|
136
|
+
record_inbound(td, topic_id=1, text="b")
|
|
137
|
+
record_outbound(td, topic_id=1, text="c")
|
|
138
|
+
record_inbound(td, topic_id=2, text="x")
|
|
139
|
+
stats = topic_stats(td)
|
|
140
|
+
by_topic = {s["topic_id"]: s for s in stats}
|
|
141
|
+
self.assertEqual(by_topic[1]["messages"], 3)
|
|
142
|
+
self.assertEqual(by_topic[2]["messages"], 1)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class TestDaemonDMRefusal(unittest.TestCase):
|
|
146
|
+
"""The daemon must refuse to start a mission from a DM."""
|
|
147
|
+
def test_dm_message_is_refused(self):
|
|
148
|
+
from omega_engine.daemons.telegram import _route_one
|
|
149
|
+
|
|
150
|
+
class _FakeBridge:
|
|
151
|
+
def __init__(self):
|
|
152
|
+
self.calls: list[dict] = []
|
|
153
|
+
def _call(self, method, fields, **_kw):
|
|
154
|
+
self.calls.append({"method": method, "fields": fields})
|
|
155
|
+
return {"message_id": 1}
|
|
156
|
+
|
|
157
|
+
class _FakeSupervisor:
|
|
158
|
+
def on_channel_message(self, topic_id, text):
|
|
159
|
+
return []
|
|
160
|
+
|
|
161
|
+
with tempfile.TemporaryDirectory() as td:
|
|
162
|
+
home = Path(td)
|
|
163
|
+
bridge = _FakeBridge()
|
|
164
|
+
tag = _route_one(
|
|
165
|
+
topic_id=None, text="hi from DM",
|
|
166
|
+
message_id=5, chat_id=12345,
|
|
167
|
+
supervisor=_FakeSupervisor(),
|
|
168
|
+
project_map={},
|
|
169
|
+
home=home,
|
|
170
|
+
telegram_bridge=bridge,
|
|
171
|
+
)
|
|
172
|
+
self.assertEqual(tag, "dm:refused")
|
|
173
|
+
# We replied to the user with the redirect message.
|
|
174
|
+
self.assertEqual(len(bridge.calls), 1)
|
|
175
|
+
self.assertEqual(bridge.calls[0]["method"], "sendMessage")
|
|
176
|
+
self.assertEqual(
|
|
177
|
+
str(bridge.calls[0]["fields"]["chat_id"]), "12345",
|
|
178
|
+
)
|
|
179
|
+
self.assertIn("project topic", bridge.calls[0]["fields"]["text"])
|
|
180
|
+
|
|
181
|
+
def test_topic_message_records_history(self):
|
|
182
|
+
from omega_engine.daemons.telegram import _route_one
|
|
183
|
+
|
|
184
|
+
class _FakeBridge: pass
|
|
185
|
+
class _FakeSupervisor:
|
|
186
|
+
def on_channel_message(self, topic_id, text):
|
|
187
|
+
return []
|
|
188
|
+
|
|
189
|
+
with tempfile.TemporaryDirectory() as td:
|
|
190
|
+
home = Path(td)
|
|
191
|
+
# No project mapped → topic:unknown path. But the inbound
|
|
192
|
+
# message should still be recorded.
|
|
193
|
+
tag = _route_one(
|
|
194
|
+
topic_id=99, text="curious question",
|
|
195
|
+
message_id=11, chat_id=12345,
|
|
196
|
+
supervisor=_FakeSupervisor(),
|
|
197
|
+
project_map={},
|
|
198
|
+
home=home,
|
|
199
|
+
telegram_bridge=_FakeBridge(),
|
|
200
|
+
)
|
|
201
|
+
self.assertEqual(tag, "topic:unknown")
|
|
202
|
+
history = recent_messages(home, topic_id=99)
|
|
203
|
+
self.assertEqual(len(history), 1)
|
|
204
|
+
self.assertEqual(history[0].text, "curious question")
|
|
205
|
+
self.assertEqual(history[0].role, "user")
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
if __name__ == "__main__":
|
|
209
|
+
unittest.main(verbosity=2)
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"""Tests for the tmux orchestrator + AISB chat-loop fallback."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import sys
|
|
5
|
+
import tempfile
|
|
6
|
+
import unittest
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from unittest import mock
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
HERE = Path(__file__).resolve().parent
|
|
12
|
+
sys.path.insert(0, str(HERE.parent))
|
|
13
|
+
|
|
14
|
+
from omega_engine import tmux # noqa: E402
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# ---------------------------------------------------------------------------
|
|
18
|
+
# Categorisation
|
|
19
|
+
# ---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TestCategorize(unittest.TestCase):
|
|
23
|
+
def test_aisb(self):
|
|
24
|
+
for n in ("AISB-master", "AISB-ORACLE", "aisb-chat"):
|
|
25
|
+
self.assertEqual(tmux.categorize(n), "aisb")
|
|
26
|
+
|
|
27
|
+
def test_oracle(self):
|
|
28
|
+
for n in ("Kommu-oracle", "DentistryGPT-oracle-2",
|
|
29
|
+
"AgentikOS-oracle"):
|
|
30
|
+
self.assertEqual(tmux.categorize(n), "oracle")
|
|
31
|
+
|
|
32
|
+
def test_worker(self):
|
|
33
|
+
for n in ("Kommu-worker-1-audit-codeaudit",
|
|
34
|
+
"DentistryGPT-worker-2-fix-login",
|
|
35
|
+
"Project-oracle-2-worker-1-task"):
|
|
36
|
+
self.assertEqual(tmux.categorize(n), "worker")
|
|
37
|
+
|
|
38
|
+
def test_dev(self):
|
|
39
|
+
for n in ("Causio-dev-feat", "Causio-fix-CAU-42", "K-work-x"):
|
|
40
|
+
self.assertEqual(tmux.categorize(n), "dev")
|
|
41
|
+
|
|
42
|
+
def test_linear(self):
|
|
43
|
+
self.assertEqual(tmux.categorize("Kommu-linear"), "linear")
|
|
44
|
+
|
|
45
|
+
def test_home(self):
|
|
46
|
+
for n in ("Home", "Home-2", "Home-3"):
|
|
47
|
+
self.assertEqual(tmux.categorize(n), "home")
|
|
48
|
+
|
|
49
|
+
def test_other(self):
|
|
50
|
+
for n in ("misc", "ssh-tunnel", "random-session-name"):
|
|
51
|
+
self.assertEqual(tmux.categorize(n), "other")
|
|
52
|
+
|
|
53
|
+
def test_project_extraction(self):
|
|
54
|
+
self.assertEqual(tmux.project_from("Kommu-oracle"), "Kommu")
|
|
55
|
+
self.assertEqual(tmux.project_from("DentistryGPT-worker-1-x"),
|
|
56
|
+
"DentistryGPT")
|
|
57
|
+
self.assertEqual(tmux.project_from("Causio-fix-CAU-42"), "Causio")
|
|
58
|
+
self.assertIsNone(tmux.project_from("Home"))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
# Subprocess wrapper (mocked)
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _fake_proc(stdout: str, returncode: int = 0):
|
|
67
|
+
import subprocess
|
|
68
|
+
return subprocess.CompletedProcess(args=[], returncode=returncode,
|
|
69
|
+
stdout=stdout, stderr="")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TestListSessions(unittest.TestCase):
|
|
73
|
+
def test_list_empty_when_tmux_missing(self):
|
|
74
|
+
with mock.patch("shutil.which", return_value=None):
|
|
75
|
+
sessions = tmux.list_sessions()
|
|
76
|
+
self.assertEqual(sessions, [])
|
|
77
|
+
|
|
78
|
+
def test_list_parses_format(self):
|
|
79
|
+
# Two sessions: Kommu-oracle (detached, 2 windows), Home (attached)
|
|
80
|
+
canned = (
|
|
81
|
+
"Kommu-oracle\t0\t2\t1700000000\n"
|
|
82
|
+
"Home\t1\t1\t1700000100\n"
|
|
83
|
+
)
|
|
84
|
+
with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
|
|
85
|
+
mock.patch("subprocess.run", return_value=_fake_proc(canned, 0)):
|
|
86
|
+
sessions = tmux.list_sessions()
|
|
87
|
+
self.assertEqual(len(sessions), 2)
|
|
88
|
+
self.assertEqual(sessions[0].name, "Kommu-oracle")
|
|
89
|
+
self.assertEqual(sessions[0].category, "oracle")
|
|
90
|
+
self.assertEqual(sessions[0].project, "Kommu")
|
|
91
|
+
self.assertFalse(sessions[0].attached)
|
|
92
|
+
self.assertEqual(sessions[0].windows, 2)
|
|
93
|
+
self.assertTrue(sessions[1].attached)
|
|
94
|
+
self.assertEqual(sessions[1].category, "home")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestSpawn(unittest.TestCase):
|
|
98
|
+
def test_refuses_existing_session(self):
|
|
99
|
+
with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
|
|
100
|
+
mock.patch("subprocess.run", return_value=_fake_proc("", 0)):
|
|
101
|
+
# is_alive returns True (rc=0) so spawn refuses.
|
|
102
|
+
self.assertFalse(tmux.spawn("Kommu-oracle"))
|
|
103
|
+
|
|
104
|
+
def test_spawn_oracle_naming(self):
|
|
105
|
+
captured: list = []
|
|
106
|
+
|
|
107
|
+
def fake_run(cmd, **kw):
|
|
108
|
+
captured.append(cmd)
|
|
109
|
+
# First call (has-session) returns 1 (not alive).
|
|
110
|
+
# Second call (new-session) returns 0.
|
|
111
|
+
rc = 1 if "has-session" in cmd else 0
|
|
112
|
+
return _fake_proc("", rc)
|
|
113
|
+
|
|
114
|
+
with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
|
|
115
|
+
mock.patch("subprocess.run", side_effect=fake_run):
|
|
116
|
+
name = tmux.spawn_oracle("Kommu")
|
|
117
|
+
self.assertEqual(name, "Kommu-oracle")
|
|
118
|
+
# The new-session command carries the right session name
|
|
119
|
+
new_session_cmd = next(c for c in captured if "new-session" in c)
|
|
120
|
+
self.assertIn("Kommu-oracle", new_session_cmd)
|
|
121
|
+
|
|
122
|
+
def test_spawn_worker_with_oracle_id(self):
|
|
123
|
+
with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
|
|
124
|
+
mock.patch("subprocess.run", return_value=_fake_proc("", 1)):
|
|
125
|
+
n1 = tmux.spawn_worker("Kommu", "audit-codeaudit",
|
|
126
|
+
worker_id=1, oracle_id=1)
|
|
127
|
+
n2 = tmux.spawn_worker("Kommu", "audit-secaudit",
|
|
128
|
+
worker_id=1, oracle_id=2)
|
|
129
|
+
self.assertEqual(n1, "Kommu-worker-1-audit-codeaudit")
|
|
130
|
+
self.assertEqual(n2, "Kommu-oracle-2-worker-1-audit-secaudit")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class TestHealth(unittest.TestCase):
|
|
134
|
+
def test_health_without_tmux(self):
|
|
135
|
+
with mock.patch("shutil.which", return_value=None):
|
|
136
|
+
r = tmux.health_report()
|
|
137
|
+
self.assertFalse(r["tmux_installed"])
|
|
138
|
+
|
|
139
|
+
def test_health_groups_categories(self):
|
|
140
|
+
canned = (
|
|
141
|
+
"AISB-master\t0\t1\t1700000000\n"
|
|
142
|
+
"Kommu-oracle\t0\t1\t1700000000\n"
|
|
143
|
+
"Kommu-worker-1-codeaudit\t0\t1\t1700000000\n"
|
|
144
|
+
)
|
|
145
|
+
with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
|
|
146
|
+
mock.patch("subprocess.run", return_value=_fake_proc(canned, 0)):
|
|
147
|
+
r = tmux.health_report()
|
|
148
|
+
self.assertEqual(r["sessions"], 3)
|
|
149
|
+
self.assertIn("oracle", r["by_category"])
|
|
150
|
+
self.assertIn("worker", r["by_category"])
|
|
151
|
+
self.assertIn("aisb", r["by_category"])
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class TestCleanupStale(unittest.TestCase):
|
|
155
|
+
def test_dry_run_lists_but_no_kill(self):
|
|
156
|
+
# Worker created at epoch 0 → very old.
|
|
157
|
+
canned = "Kommu-worker-1-stuck\t0\t1\t0\n"
|
|
158
|
+
with mock.patch("shutil.which", return_value="/usr/bin/tmux"), \
|
|
159
|
+
mock.patch("subprocess.run", return_value=_fake_proc(canned, 0)):
|
|
160
|
+
r = tmux.cleanup_stale(older_than_hours=1, dry_run=True)
|
|
161
|
+
self.assertEqual(r["candidates"], ["Kommu-worker-1-stuck"])
|
|
162
|
+
self.assertEqual(r["killed"], [])
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# ---------------------------------------------------------------------------
|
|
166
|
+
# Default config writes a file with the prefix+Z popup
|
|
167
|
+
# ---------------------------------------------------------------------------
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class TestDefaultConfig(unittest.TestCase):
|
|
171
|
+
def test_writes_file_with_prefix_z_binding(self):
|
|
172
|
+
with tempfile.TemporaryDirectory() as td:
|
|
173
|
+
path = tmux.write_default_config(Path(td) / "tmux.conf")
|
|
174
|
+
self.assertTrue(path.exists())
|
|
175
|
+
text = path.read_text()
|
|
176
|
+
self.assertIn("bind-key Z", text)
|
|
177
|
+
self.assertIn("omega tmux menu", text)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# ---------------------------------------------------------------------------
|
|
181
|
+
# AISB chat-loop wiring
|
|
182
|
+
# ---------------------------------------------------------------------------
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class TestAisbChat(unittest.TestCase):
|
|
186
|
+
def test_chat_records_inbound_and_outbound(self):
|
|
187
|
+
from omega_engine import aisb_chat
|
|
188
|
+
from omega_engine.telegram_history import recent_messages
|
|
189
|
+
|
|
190
|
+
# Mock input(): one user line then /quit.
|
|
191
|
+
responses = iter(["fix the login bug", "/quit"])
|
|
192
|
+
|
|
193
|
+
def fake_input(prompt=""):
|
|
194
|
+
return next(responses)
|
|
195
|
+
|
|
196
|
+
# Mock the provider so we don't actually call Claude.
|
|
197
|
+
class _FakeResult:
|
|
198
|
+
text = "ok, will look into it"
|
|
199
|
+
class _FakeProvider:
|
|
200
|
+
id = "fake"
|
|
201
|
+
def run(self, req): return _FakeResult()
|
|
202
|
+
class _FakeRouter:
|
|
203
|
+
def resolve(self, role): return _FakeProvider()
|
|
204
|
+
|
|
205
|
+
with tempfile.TemporaryDirectory() as td, \
|
|
206
|
+
mock.patch("builtins.input", side_effect=fake_input), \
|
|
207
|
+
mock.patch("omega_engine.router.ModelRouter.auto",
|
|
208
|
+
return_value=_FakeRouter()), \
|
|
209
|
+
mock.patch.dict("os.environ", {"OMEGA_HOME": td}):
|
|
210
|
+
rc = aisb_chat.run_chat_loop()
|
|
211
|
+
self.assertEqual(rc, 0)
|
|
212
|
+
# Assertions MUST be inside the with block — temp dir is
|
|
213
|
+
# deleted on context exit.
|
|
214
|
+
history = recent_messages(td, topic_id=aisb_chat.CHAT_TOPIC)
|
|
215
|
+
self.assertEqual(len(history), 2)
|
|
216
|
+
self.assertEqual(history[0].role, "user")
|
|
217
|
+
self.assertEqual(history[0].text, "fix the login bug")
|
|
218
|
+
self.assertEqual(history[1].role, "bot")
|
|
219
|
+
self.assertEqual(history[1].text, "ok, will look into it")
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
if __name__ == "__main__":
|
|
223
|
+
unittest.main(verbosity=2)
|