@agentikos/omega-os 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +25 -13
  2. package/bootstrap/lib/steps.sh +214 -9
  3. package/bootstrap/manifest.example.yaml +6 -1
  4. package/docs/COMPLETION-PLAN.md +48 -0
  5. package/omega/Agentik_Engine/README.md +25 -10
  6. package/omega/Agentik_Engine/omega_engine/__init__.py +66 -2
  7. package/omega/Agentik_Engine/omega_engine/account.py +505 -0
  8. package/omega/Agentik_Engine/omega_engine/autonomous.py +538 -0
  9. package/omega/Agentik_Engine/omega_engine/cli.py +467 -29
  10. package/omega/Agentik_Engine/omega_engine/daemons/__init__.py +14 -0
  11. package/omega/Agentik_Engine/omega_engine/daemons/autonomous.py +56 -0
  12. package/omega/Agentik_Engine/omega_engine/daemons/engine.py +187 -0
  13. package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +231 -0
  14. package/omega/Agentik_Engine/omega_engine/educators/__init__.py +51 -0
  15. package/omega/Agentik_Engine/omega_engine/educators/artifact.py +65 -0
  16. package/omega/Agentik_Engine/omega_engine/educators/automation.py +76 -0
  17. package/omega/Agentik_Engine/omega_engine/educators/base.py +327 -0
  18. package/omega/Agentik_Engine/omega_engine/educators/claudecode.py +71 -0
  19. package/omega/Agentik_Engine/omega_engine/educators/connection.py +75 -0
  20. package/omega/Agentik_Engine/omega_engine/educators/coworker.py +68 -0
  21. package/omega/Agentik_Engine/omega_engine/educators/loop.py +82 -0
  22. package/omega/Agentik_Engine/omega_engine/educators/prompt.py +68 -0
  23. package/omega/Agentik_Engine/omega_engine/educators/skill.py +69 -0
  24. package/omega/Agentik_Engine/omega_engine/executor.py +46 -6
  25. package/omega/Agentik_Engine/omega_engine/mission.py +13 -1
  26. package/omega/Agentik_Engine/omega_engine/provider.py +247 -1
  27. package/omega/Agentik_Engine/omega_engine/rag/__init__.py +21 -0
  28. package/omega/Agentik_Engine/omega_engine/rag/agentic.py +83 -0
  29. package/omega/Agentik_Engine/omega_engine/rag/base.py +42 -0
  30. package/omega/Agentik_Engine/omega_engine/rag/corrective.py +119 -0
  31. package/omega/Agentik_Engine/omega_engine/rag/graph.py +169 -0
  32. package/omega/Agentik_Engine/omega_engine/rag/hybrid.py +205 -0
  33. package/omega/Agentik_Engine/omega_engine/rag/multimodal.py +136 -0
  34. package/omega/Agentik_Engine/omega_engine/rag/router.py +110 -0
  35. package/omega/Agentik_Engine/omega_engine/reducer.py +21 -3
  36. package/omega/Agentik_Engine/omega_engine/store.py +65 -5
  37. package/omega/Agentik_Engine/omega_engine/sync.py +304 -0
  38. package/omega/Agentik_Engine/omega_engine/tools.py +272 -0
  39. package/omega/Agentik_Engine/pyproject.toml +1 -1
  40. package/omega/Agentik_Engine/tests/test_account.py +333 -0
  41. package/omega/Agentik_Engine/tests/test_autonomous.py +361 -0
  42. package/omega/Agentik_Engine/tests/test_educators.py +233 -0
  43. package/omega/Agentik_Engine/tests/test_rag.py +287 -0
  44. package/omega/Agentik_Engine/tests/test_snapshot_partial.py +172 -0
  45. package/omega/Agentik_Engine/tests/test_tools_and_sync.py +312 -0
  46. package/omega/Agentik_SSOT/skills/rag-route.md +73 -0
  47. package/package.json +1 -1
  48. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  49. package/omega/Agentik_Engine/omega_engine/__pycache__/audit.cpython-313.pyc +0 -0
  50. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_arsenal.cpython-313.pyc +0 -0
  51. package/omega/Agentik_Engine/omega_engine/__pycache__/barrier.cpython-313.pyc +0 -0
  52. package/omega/Agentik_Engine/omega_engine/__pycache__/bus.cpython-313.pyc +0 -0
  53. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  54. package/omega/Agentik_Engine/omega_engine/__pycache__/events.cpython-313.pyc +0 -0
  55. package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
  56. package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
  57. package/omega/Agentik_Engine/omega_engine/__pycache__/progress.cpython-313.pyc +0 -0
  58. package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
  59. package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
  60. package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
  61. package/omega/Agentik_Engine/omega_engine/__pycache__/report.cpython-313.pyc +0 -0
  62. package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
  63. package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
  64. package/omega/Agentik_Engine/omega_engine/__pycache__/supervisor.cpython-313.pyc +0 -0
  65. package/omega/Agentik_Engine/omega_engine/__pycache__/task.cpython-313.pyc +0 -0
  66. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram.cpython-313.pyc +0 -0
  67. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313.pyc +0 -0
  68. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313.pyc +0 -0
  69. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313.pyc +0 -0
  70. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313.pyc +0 -0
  71. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313.pyc +0 -0
  72. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313.pyc +0 -0
  73. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313.pyc +0 -0
@@ -0,0 +1,312 @@
1
+ """ToolRegistry + SyncEngine / ClaudeCodeAdapter end-to-end test.
2
+
3
+ Seeds a tempdir OMEGA_HOME with one skill, one command, one MCP-config entry,
4
+ one catalog entry, one tool, and one hook. Asserts the projection produces the
5
+ expected Claude Code native layout (skills/<id>/SKILL.md, commands/<id>.md,
6
+ .mcp.json with mcpServers, settings.json with hooks).
7
+
8
+ Standalone: python3 tests/test_tools_and_sync.py
9
+ """
10
+ import json
11
+ import shutil
12
+ import sys
13
+ import tempfile
14
+ from pathlib import Path
15
+
16
+ sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
17
+
18
+ from omega_engine import cli # noqa: E402
19
+ from omega_engine.sync import ClaudeCodeAdapter, SyncEngine # noqa: E402
20
+ from omega_engine.tools import ( # noqa: E402
21
+ Tool,
22
+ ToolRegistry,
23
+ load_catalog,
24
+ merge_mcp_config,
25
+ )
26
+
27
+
28
+ # --------------------------------------------------------------------------
29
+ # Tempdir helpers
30
+ # --------------------------------------------------------------------------
31
+
32
+
33
+ def _seed_home() -> Path:
34
+ home = Path(tempfile.mkdtemp(prefix="omega-tools-sync-test-"))
35
+ # 8-block scaffolding (only what the test touches)
36
+ for b in ("Agentik_SSOT", "Agentik_Tools", "Agentik_Providers"):
37
+ (home / b).mkdir(parents=True, exist_ok=True)
38
+ # SSOT subdirs
39
+ ssot = home / "Agentik_SSOT"
40
+ (ssot / "skills").mkdir(parents=True, exist_ok=True)
41
+ (ssot / "commands").mkdir(parents=True, exist_ok=True)
42
+ (ssot / "agents").mkdir(parents=True, exist_ok=True)
43
+ (ssot / "hooks").mkdir(parents=True, exist_ok=True)
44
+ (ssot / "mcp").mkdir(parents=True, exist_ok=True)
45
+ return home
46
+
47
+
48
+ def _seed_skill(home: Path, sid: str, body: str) -> None:
49
+ (home / "Agentik_SSOT" / "skills" / f"{sid}.md").write_text(body)
50
+
51
+
52
+ def _seed_command(home: Path, cid: str, body: str) -> None:
53
+ (home / "Agentik_SSOT" / "commands" / f"{cid}.md").write_text(body)
54
+
55
+
56
+ def _seed_agent(home: Path, aid: str, body: str) -> None:
57
+ (home / "Agentik_SSOT" / "agents" / f"{aid}.md").write_text(body)
58
+
59
+
60
+ def _seed_hook(home: Path, fname: str, payload: dict) -> None:
61
+ (home / "Agentik_SSOT" / "hooks" / fname).write_text(json.dumps(payload))
62
+
63
+
64
+ def _seed_catalog(home: Path) -> None:
65
+ import yaml
66
+ cat = {
67
+ "version": 1,
68
+ "catalog": [
69
+ {"id": "filesystem", "name": "Filesystem",
70
+ "description": "sandboxed file access",
71
+ "category": "core",
72
+ "install": {"method": "npx",
73
+ "package": "@modelcontextprotocol/server-filesystem"},
74
+ "recommended": True},
75
+ {"id": "github", "name": "GitHub",
76
+ "description": "issues + PRs",
77
+ "category": "dev",
78
+ "install": {"method": "npx",
79
+ "package": "@modelcontextprotocol/server-github"},
80
+ "secrets": ["GITHUB_TOKEN"],
81
+ "recommended": True},
82
+ ],
83
+ }
84
+ (home / "Agentik_SSOT" / "mcp" / "mcp-catalog.yaml").write_text(
85
+ yaml.safe_dump(cat, sort_keys=False))
86
+
87
+
88
+ def _seed_mcp_config(home: Path) -> None:
89
+ merge_mcp_config(home, {"id": "filesystem", "secret_refs": [], "enabled": True})
90
+ merge_mcp_config(home, {"id": "github", "secret_refs": ["GITHUB_TOKEN"],
91
+ "enabled": True})
92
+
93
+
94
+ def _seed_providers(home: Path) -> None:
95
+ import yaml
96
+ reg = {
97
+ "version": 1,
98
+ "providers": [{"id": "claude", "adapter": "claude"}],
99
+ }
100
+ (home / "Agentik_Providers" / "registry.yaml").write_text(
101
+ yaml.safe_dump(reg, sort_keys=False))
102
+
103
+
104
+ # --------------------------------------------------------------------------
105
+ # 1. ToolRegistry — install / list / remove + idempotent save/load
106
+ # --------------------------------------------------------------------------
107
+
108
+
109
+ def test_registry_install_list_remove():
110
+ home = _seed_home()
111
+ try:
112
+ reg = ToolRegistry.load(home)
113
+ assert reg.list() == []
114
+
115
+ t = Tool(name="filesystem", version="1.2.3",
116
+ path="Agentik_Tools/filesystem/",
117
+ invoke="Agentik_Tools/filesystem/bin/server-filesystem",
118
+ source="mcp:filesystem")
119
+ reg.install(t)
120
+ reg.save(home)
121
+ assert reg.installed_path("filesystem") == home / "Agentik_Tools" / "filesystem"
122
+
123
+ # round-trip
124
+ reg2 = ToolRegistry.load(home)
125
+ assert len(reg2.list()) == 1
126
+ assert reg2.get("filesystem").version == "1.2.3"
127
+
128
+ # remove
129
+ assert reg2.remove("filesystem") is True
130
+ reg2.save(home)
131
+ assert ToolRegistry.load(home).list() == []
132
+ finally:
133
+ shutil.rmtree(home, ignore_errors=True)
134
+
135
+
136
+ # --------------------------------------------------------------------------
137
+ # 2. catalog round-trip
138
+ # --------------------------------------------------------------------------
139
+
140
+
141
+ def test_catalog_loads():
142
+ home = _seed_home()
143
+ try:
144
+ _seed_catalog(home)
145
+ cat = load_catalog(home)
146
+ ids = {e["id"] for e in cat["catalog"]}
147
+ assert ids == {"filesystem", "github"}
148
+ finally:
149
+ shutil.rmtree(home, ignore_errors=True)
150
+
151
+
152
+ # --------------------------------------------------------------------------
153
+ # 3. ClaudeCodeAdapter.project() — full projection
154
+ # --------------------------------------------------------------------------
155
+
156
+
157
+ def test_claude_code_projection():
158
+ home = _seed_home()
159
+ try:
160
+ # seed an SSOT
161
+ _seed_skill(home, "frontend-design",
162
+ "# Frontend design\n\nProduction-grade UI.\n")
163
+ _seed_command(home, "uiuxaudit",
164
+ "# /uiuxaudit\n\nUI/UX forensic audit.\n")
165
+ _seed_agent(home, "oracle",
166
+ "# Oracle\n\nClassify and route.\n")
167
+ _seed_hook(home, "stop.json",
168
+ {"Stop": [{"matcher": "*", "hooks": [{"type": "command",
169
+ "command": "echo stop"}]}]})
170
+ _seed_catalog(home)
171
+ _seed_mcp_config(home)
172
+ _seed_providers(home)
173
+
174
+ # pre-register one tool so .mcp.json gets a real command path
175
+ reg = ToolRegistry.load(home)
176
+ reg.install(Tool(
177
+ name="filesystem",
178
+ path="Agentik_Tools/filesystem/",
179
+ invoke="Agentik_Tools/filesystem/bin/server-filesystem",
180
+ source="mcp:filesystem",
181
+ ))
182
+ reg.save(home)
183
+
184
+ adapter = ClaudeCodeAdapter()
185
+ out = adapter.project(home)
186
+ assert out["projected"]
187
+ target = Path(out["target"])
188
+ assert target.is_dir()
189
+ assert (target / "skills" / "frontend-design" / "SKILL.md").exists()
190
+ assert "Production-grade UI" in (
191
+ target / "skills" / "frontend-design" / "SKILL.md").read_text()
192
+ assert (target / "commands" / "uiuxaudit.md").exists()
193
+ assert (target / "agents" / "oracle.md").exists()
194
+
195
+ # .mcp.json — both servers projected; filesystem has a local command,
196
+ # github falls back to npx.
197
+ mcp = json.loads((target / ".mcp.json").read_text())
198
+ servers = mcp["mcpServers"]
199
+ assert "filesystem" in servers and "github" in servers
200
+ assert servers["filesystem"]["command"].endswith(
201
+ "Agentik_Tools/filesystem/bin/server-filesystem")
202
+ assert servers["github"]["command"] == "npx"
203
+ assert "@modelcontextprotocol/server-github" in servers["github"]["args"]
204
+ # secret refs projected as env placeholders
205
+ assert servers["github"]["env"] == {"GITHUB_TOKEN": "${GITHUB_TOKEN}"}
206
+
207
+ # settings.json — hooks block merged
208
+ settings = json.loads((target / "settings.json").read_text())
209
+ assert "Stop" in settings["hooks"]
210
+
211
+ # idempotency: re-running produces the same outcome
212
+ out2 = adapter.project(home)
213
+ assert out2["skills_written"] == out["skills_written"]
214
+ assert out2["mcp_servers"] == out["mcp_servers"]
215
+ # the .mcp.json content stays the same
216
+ mcp2 = json.loads((target / ".mcp.json").read_text())
217
+ assert mcp == mcp2
218
+ finally:
219
+ shutil.rmtree(home, ignore_errors=True)
220
+
221
+
222
+ # --------------------------------------------------------------------------
223
+ # 4. SyncEngine.sync_all() over the providers registry
224
+ # --------------------------------------------------------------------------
225
+
226
+
227
+ def test_sync_engine_iterates_providers():
228
+ home = _seed_home()
229
+ try:
230
+ _seed_skill(home, "frontend-design", "# Skill\n")
231
+ _seed_catalog(home)
232
+ _seed_mcp_config(home)
233
+ # both claude (real adapter) and glm (stub adapter)
234
+ import yaml
235
+ (home / "Agentik_Providers" / "registry.yaml").write_text(yaml.safe_dump({
236
+ "version": 1,
237
+ "providers": [{"id": "claude"}, {"id": "glm"}],
238
+ }))
239
+ outcomes = SyncEngine().sync_all(home)
240
+ by_id = {o["provider"]: o for o in outcomes}
241
+ assert by_id["claude-code"]["projected"] is True
242
+ assert by_id["glm"]["projected"] is False
243
+ assert "no native projection" in by_id["glm"]["reason"]
244
+ finally:
245
+ shutil.rmtree(home, ignore_errors=True)
246
+
247
+
248
+ # --------------------------------------------------------------------------
249
+ # 5. CLI: `omega sync` returns 0
250
+ # --------------------------------------------------------------------------
251
+
252
+
253
+ def test_cli_sync_returns_zero(monkeypatch=None):
254
+ home = _seed_home()
255
+ try:
256
+ _seed_skill(home, "frontend-design", "# Skill\n")
257
+ _seed_catalog(home)
258
+ _seed_mcp_config(home)
259
+ _seed_providers(home)
260
+
261
+ import os
262
+ old = os.environ.get("OMEGA_HOME")
263
+ os.environ["OMEGA_HOME"] = str(home)
264
+ try:
265
+ rc = cli.main(["sync"])
266
+ finally:
267
+ if old is None:
268
+ os.environ.pop("OMEGA_HOME", None)
269
+ else:
270
+ os.environ["OMEGA_HOME"] = old
271
+ assert rc == 0
272
+ finally:
273
+ shutil.rmtree(home, ignore_errors=True)
274
+
275
+
276
+ # --------------------------------------------------------------------------
277
+ # 6. CLI: `omega tool list` returns 0 on empty registry
278
+ # --------------------------------------------------------------------------
279
+
280
+
281
+ def test_cli_tool_list_empty():
282
+ home = _seed_home()
283
+ try:
284
+ import os
285
+ old = os.environ.get("OMEGA_HOME")
286
+ os.environ["OMEGA_HOME"] = str(home)
287
+ try:
288
+ rc = cli.main(["tool", "list"])
289
+ finally:
290
+ if old is None:
291
+ os.environ.pop("OMEGA_HOME", None)
292
+ else:
293
+ os.environ["OMEGA_HOME"] = old
294
+ assert rc == 0
295
+ finally:
296
+ shutil.rmtree(home, ignore_errors=True)
297
+
298
+
299
+ def _run_all() -> bool:
300
+ tests = [v for k, v in sorted(globals().items())
301
+ if k.startswith("test_") and callable(v)]
302
+ passed = 0
303
+ for t in tests:
304
+ t()
305
+ print(f" PASS {t.__name__}")
306
+ passed += 1
307
+ print(f"\n{passed}/{len(tests)} tools+sync tests passed")
308
+ return passed == len(tests)
309
+
310
+
311
+ if __name__ == "__main__":
312
+ sys.exit(0 if _run_all() else 1)
@@ -0,0 +1,73 @@
1
+ # /rag-route — Classify a query, pick a retrieval strategy
2
+
3
+ > An agentic skill. Wraps `omega_engine.rag.RAGRouter`. Classifies the
4
+ > incoming query and dispatches to the right inner retriever, always behind
5
+ > the Corrective RAG envelope.
6
+
7
+ ---
8
+
9
+ ## What it does
10
+
11
+ Given a natural-language query, `/rag-route`:
12
+
13
+ 1. Applies a cheap heuristic to detect query shape:
14
+ - Relational ("depends", "between", "who owns") → **graph**
15
+ - Modal ("diagram", "screenshot", "pdf") → **multimodal**
16
+ - Investigative ("why", "how", "explain") → **agentic**
17
+ - Otherwise → **hybrid** (the default — dense + BM25)
18
+ 2. Asks the provider (role `rag-route`) to confirm or override.
19
+ 3. Runs the chosen retriever, wrapped in `CorrectiveRetriever` so the
20
+ result is graded and re-retrieved if quality is low.
21
+ 4. Returns a `RetrievalResult` with `strategy = "router(<inner>)->corrective+<inner>"`.
22
+
23
+ ## Why route at all?
24
+
25
+ A single retriever wins for a single shape of query. Real workloads mix
26
+ shapes — code search (hybrid), dependency questions (graph), screenshot
27
+ recall (multimodal), causal explanations (agentic). Routing keeps each
28
+ strategy honest at what it's best at, and the Corrective envelope keeps
29
+ the overall quality floor explicit.
30
+
31
+ ## How to call it (Python)
32
+
33
+ ```python
34
+ from omega_engine import (
35
+ RAGRouter, HybridRetriever, GraphRetriever, MockProvider,
36
+ )
37
+
38
+ provider = MockProvider()
39
+ router = RAGRouter(
40
+ strategies={
41
+ "hybrid": HybridRetriever("/path/to/rag.db"),
42
+ "graph": GraphRetriever("/path/to/graph.json"),
43
+ },
44
+ provider=provider,
45
+ default="hybrid",
46
+ threshold=70.0,
47
+ max_retries=2,
48
+ )
49
+ result = router.retrieve("what does the auth service depend on?", k=5)
50
+ # result.strategy → "router(graph)->corrective+graph"
51
+ # result.documents → ranked Documents
52
+ ```
53
+
54
+ ## Where its pieces live
55
+
56
+ Following the OmegaOS placement rule (engine ≠ config ≠ runtime):
57
+
58
+ - **Engine** — `omega/Agentik_Engine/omega_engine/rag/` (the retrievers + router).
59
+ - **Runtime** — `<omega_home>/Agentik_Runtime/memory/rag.db` (hybrid corpus)
60
+ and `<omega_home>/Agentik_Runtime/memory/graph.json` (graph).
61
+ - **Config (this skill)** — `omega/Agentik_SSOT/skills/rag-route.md`.
62
+
63
+ ## Provider contract
64
+
65
+ Mock-friendly. The provider receives `AgentRequest(role="rag-route", ...)`
66
+ and is expected to return an `AgentResult` whose `artifacts["strategy"]` is
67
+ one of the names registered with the router. Anything else is ignored —
68
+ the router falls back to the heuristic.
69
+
70
+ ## Tests
71
+
72
+ `omega/Agentik_Engine/tests/test_rag.py` exercises classification, the
73
+ inner strategies, and the Corrective wrap end to end with `MockProvider`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentikos/omega-os",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Omega OS — installable agentic operating system with verified-completion orchestration. Event-sourced engine, 8-block rack, autonomous agents, MCP.",
5
5
  "bin": {
6
6
  "omega-os": "bin/omega-os.js"