aethergraph 0.1.0a1__py3-none-any.whl → 0.1.0a2__py3-none-any.whl

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 (267) hide show
  1. aethergraph/__init__.py +4 -10
  2. aethergraph/__main__.py +293 -0
  3. aethergraph/api/v1/__init__.py +0 -0
  4. aethergraph/api/v1/agents.py +46 -0
  5. aethergraph/api/v1/apps.py +70 -0
  6. aethergraph/api/v1/artifacts.py +415 -0
  7. aethergraph/api/v1/channels.py +89 -0
  8. aethergraph/api/v1/deps.py +168 -0
  9. aethergraph/api/v1/graphs.py +259 -0
  10. aethergraph/api/v1/identity.py +25 -0
  11. aethergraph/api/v1/memory.py +353 -0
  12. aethergraph/api/v1/misc.py +47 -0
  13. aethergraph/api/v1/pagination.py +29 -0
  14. aethergraph/api/v1/runs.py +568 -0
  15. aethergraph/api/v1/schemas.py +535 -0
  16. aethergraph/api/v1/session.py +323 -0
  17. aethergraph/api/v1/stats.py +201 -0
  18. aethergraph/api/v1/viz.py +152 -0
  19. aethergraph/config/config.py +22 -0
  20. aethergraph/config/loader.py +3 -2
  21. aethergraph/config/storage.py +209 -0
  22. aethergraph/contracts/__init__.py +0 -0
  23. aethergraph/contracts/services/__init__.py +0 -0
  24. aethergraph/contracts/services/artifacts.py +27 -14
  25. aethergraph/contracts/services/memory.py +45 -17
  26. aethergraph/contracts/services/metering.py +129 -0
  27. aethergraph/contracts/services/runs.py +50 -0
  28. aethergraph/contracts/services/sessions.py +87 -0
  29. aethergraph/contracts/services/state_stores.py +3 -0
  30. aethergraph/contracts/services/viz.py +44 -0
  31. aethergraph/contracts/storage/artifact_index.py +88 -0
  32. aethergraph/contracts/storage/artifact_store.py +99 -0
  33. aethergraph/contracts/storage/async_kv.py +34 -0
  34. aethergraph/contracts/storage/blob_store.py +50 -0
  35. aethergraph/contracts/storage/doc_store.py +35 -0
  36. aethergraph/contracts/storage/event_log.py +31 -0
  37. aethergraph/contracts/storage/vector_index.py +48 -0
  38. aethergraph/core/__init__.py +0 -0
  39. aethergraph/core/execution/forward_scheduler.py +13 -2
  40. aethergraph/core/execution/global_scheduler.py +21 -15
  41. aethergraph/core/execution/step_forward.py +10 -1
  42. aethergraph/core/graph/__init__.py +0 -0
  43. aethergraph/core/graph/graph_builder.py +8 -4
  44. aethergraph/core/graph/graph_fn.py +156 -15
  45. aethergraph/core/graph/graph_spec.py +8 -0
  46. aethergraph/core/graph/graphify.py +146 -27
  47. aethergraph/core/graph/node_spec.py +0 -2
  48. aethergraph/core/graph/node_state.py +3 -0
  49. aethergraph/core/graph/task_graph.py +39 -1
  50. aethergraph/core/runtime/__init__.py +0 -0
  51. aethergraph/core/runtime/ad_hoc_context.py +64 -4
  52. aethergraph/core/runtime/base_service.py +28 -4
  53. aethergraph/core/runtime/execution_context.py +13 -15
  54. aethergraph/core/runtime/graph_runner.py +222 -37
  55. aethergraph/core/runtime/node_context.py +510 -6
  56. aethergraph/core/runtime/node_services.py +12 -5
  57. aethergraph/core/runtime/recovery.py +15 -1
  58. aethergraph/core/runtime/run_manager.py +783 -0
  59. aethergraph/core/runtime/run_manager_local.py +204 -0
  60. aethergraph/core/runtime/run_registration.py +2 -2
  61. aethergraph/core/runtime/run_types.py +89 -0
  62. aethergraph/core/runtime/runtime_env.py +136 -7
  63. aethergraph/core/runtime/runtime_metering.py +71 -0
  64. aethergraph/core/runtime/runtime_registry.py +36 -13
  65. aethergraph/core/runtime/runtime_services.py +194 -6
  66. aethergraph/core/tools/builtins/toolset.py +1 -1
  67. aethergraph/core/tools/toolkit.py +5 -0
  68. aethergraph/plugins/agents/default_chat_agent copy.py +90 -0
  69. aethergraph/plugins/agents/default_chat_agent.py +171 -0
  70. aethergraph/plugins/agents/shared.py +81 -0
  71. aethergraph/plugins/channel/adapters/webui.py +112 -112
  72. aethergraph/plugins/channel/routes/webui_routes.py +367 -102
  73. aethergraph/plugins/channel/utils/slack_utils.py +115 -59
  74. aethergraph/plugins/channel/utils/telegram_utils.py +88 -47
  75. aethergraph/plugins/channel/websockets/weibui_ws.py +172 -0
  76. aethergraph/runtime/__init__.py +15 -0
  77. aethergraph/server/app_factory.py +190 -34
  78. aethergraph/server/clients/channel_client.py +202 -0
  79. aethergraph/server/http/channel_http_routes.py +116 -0
  80. aethergraph/server/http/channel_ws_routers.py +45 -0
  81. aethergraph/server/loading.py +117 -0
  82. aethergraph/server/server.py +131 -0
  83. aethergraph/server/server_state.py +240 -0
  84. aethergraph/server/start.py +227 -66
  85. aethergraph/server/ui_static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  86. aethergraph/server/ui_static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  87. aethergraph/server/ui_static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  88. aethergraph/server/ui_static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  89. aethergraph/server/ui_static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  90. aethergraph/server/ui_static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  91. aethergraph/server/ui_static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  92. aethergraph/server/ui_static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  93. aethergraph/server/ui_static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  94. aethergraph/server/ui_static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  95. aethergraph/server/ui_static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  96. aethergraph/server/ui_static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  97. aethergraph/server/ui_static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  98. aethergraph/server/ui_static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  99. aethergraph/server/ui_static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  100. aethergraph/server/ui_static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  101. aethergraph/server/ui_static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  102. aethergraph/server/ui_static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  103. aethergraph/server/ui_static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  104. aethergraph/server/ui_static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  105. aethergraph/server/ui_static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  106. aethergraph/server/ui_static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  107. aethergraph/server/ui_static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  108. aethergraph/server/ui_static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  109. aethergraph/server/ui_static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  110. aethergraph/server/ui_static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  111. aethergraph/server/ui_static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  112. aethergraph/server/ui_static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  113. aethergraph/server/ui_static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  114. aethergraph/server/ui_static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  115. aethergraph/server/ui_static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  116. aethergraph/server/ui_static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  117. aethergraph/server/ui_static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  118. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  119. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  120. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  121. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  122. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  123. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  124. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  125. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  126. aethergraph/server/ui_static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  127. aethergraph/server/ui_static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  128. aethergraph/server/ui_static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  129. aethergraph/server/ui_static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  130. aethergraph/server/ui_static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  131. aethergraph/server/ui_static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  132. aethergraph/server/ui_static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  133. aethergraph/server/ui_static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  134. aethergraph/server/ui_static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  135. aethergraph/server/ui_static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  136. aethergraph/server/ui_static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  137. aethergraph/server/ui_static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  138. aethergraph/server/ui_static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  139. aethergraph/server/ui_static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  140. aethergraph/server/ui_static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  141. aethergraph/server/ui_static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  142. aethergraph/server/ui_static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  143. aethergraph/server/ui_static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  144. aethergraph/server/ui_static/assets/index-BR5GtXcZ.css +1 -0
  145. aethergraph/server/ui_static/assets/index-CQ0HZZ83.js +400 -0
  146. aethergraph/server/ui_static/index.html +15 -0
  147. aethergraph/server/ui_static/logo.png +0 -0
  148. aethergraph/services/artifacts/__init__.py +0 -0
  149. aethergraph/services/artifacts/facade.py +1239 -132
  150. aethergraph/services/auth/{dev.py → authn.py} +0 -8
  151. aethergraph/services/auth/authz.py +100 -0
  152. aethergraph/services/channel/__init__.py +0 -0
  153. aethergraph/services/channel/channel_bus.py +19 -1
  154. aethergraph/services/channel/factory.py +13 -1
  155. aethergraph/services/channel/ingress.py +311 -0
  156. aethergraph/services/channel/queue_adapter.py +75 -0
  157. aethergraph/services/channel/session.py +502 -19
  158. aethergraph/services/container/default_container.py +122 -43
  159. aethergraph/services/continuations/continuation.py +6 -0
  160. aethergraph/services/continuations/stores/fs_store.py +19 -0
  161. aethergraph/services/eventhub/event_hub.py +76 -0
  162. aethergraph/services/kv/__init__.py +0 -0
  163. aethergraph/services/kv/ephemeral.py +244 -0
  164. aethergraph/services/llm/__init__.py +0 -0
  165. aethergraph/services/llm/generic_client copy.py +691 -0
  166. aethergraph/services/llm/generic_client.py +1288 -187
  167. aethergraph/services/llm/providers.py +3 -1
  168. aethergraph/services/llm/types.py +47 -0
  169. aethergraph/services/llm/utils.py +284 -0
  170. aethergraph/services/logger/std.py +3 -0
  171. aethergraph/services/mcp/__init__.py +9 -0
  172. aethergraph/services/mcp/http_client.py +38 -0
  173. aethergraph/services/mcp/service.py +225 -1
  174. aethergraph/services/mcp/stdio_client.py +41 -6
  175. aethergraph/services/mcp/ws_client.py +44 -2
  176. aethergraph/services/memory/__init__.py +0 -0
  177. aethergraph/services/memory/distillers/llm_long_term.py +234 -0
  178. aethergraph/services/memory/distillers/llm_meta_summary.py +398 -0
  179. aethergraph/services/memory/distillers/long_term.py +225 -0
  180. aethergraph/services/memory/facade/__init__.py +3 -0
  181. aethergraph/services/memory/facade/chat.py +440 -0
  182. aethergraph/services/memory/facade/core.py +447 -0
  183. aethergraph/services/memory/facade/distillation.py +424 -0
  184. aethergraph/services/memory/facade/rag.py +410 -0
  185. aethergraph/services/memory/facade/results.py +315 -0
  186. aethergraph/services/memory/facade/retrieval.py +139 -0
  187. aethergraph/services/memory/facade/types.py +77 -0
  188. aethergraph/services/memory/facade/utils.py +43 -0
  189. aethergraph/services/memory/facade_dep.py +1539 -0
  190. aethergraph/services/memory/factory.py +9 -3
  191. aethergraph/services/memory/utils.py +10 -0
  192. aethergraph/services/metering/eventlog_metering.py +470 -0
  193. aethergraph/services/metering/noop.py +25 -4
  194. aethergraph/services/rag/__init__.py +0 -0
  195. aethergraph/services/rag/facade.py +279 -23
  196. aethergraph/services/rag/index_factory.py +2 -2
  197. aethergraph/services/rag/node_rag.py +317 -0
  198. aethergraph/services/rate_limit/inmem_rate_limit.py +24 -0
  199. aethergraph/services/registry/__init__.py +0 -0
  200. aethergraph/services/registry/agent_app_meta.py +419 -0
  201. aethergraph/services/registry/registry_key.py +1 -1
  202. aethergraph/services/registry/unified_registry.py +74 -6
  203. aethergraph/services/scope/scope.py +159 -0
  204. aethergraph/services/scope/scope_factory.py +164 -0
  205. aethergraph/services/state_stores/serialize.py +5 -0
  206. aethergraph/services/state_stores/utils.py +2 -1
  207. aethergraph/services/viz/__init__.py +0 -0
  208. aethergraph/services/viz/facade.py +413 -0
  209. aethergraph/services/viz/viz_service.py +69 -0
  210. aethergraph/storage/artifacts/artifact_index_jsonl.py +180 -0
  211. aethergraph/storage/artifacts/artifact_index_sqlite.py +426 -0
  212. aethergraph/storage/artifacts/cas_store.py +422 -0
  213. aethergraph/storage/artifacts/fs_cas.py +18 -0
  214. aethergraph/storage/artifacts/s3_cas.py +14 -0
  215. aethergraph/storage/artifacts/utils.py +124 -0
  216. aethergraph/storage/blob/fs_blob.py +86 -0
  217. aethergraph/storage/blob/s3_blob.py +115 -0
  218. aethergraph/storage/continuation_store/fs_cont.py +283 -0
  219. aethergraph/storage/continuation_store/inmem_cont.py +146 -0
  220. aethergraph/storage/continuation_store/kvdoc_cont.py +261 -0
  221. aethergraph/storage/docstore/fs_doc.py +63 -0
  222. aethergraph/storage/docstore/sqlite_doc.py +31 -0
  223. aethergraph/storage/docstore/sqlite_doc_sync.py +90 -0
  224. aethergraph/storage/eventlog/fs_event.py +136 -0
  225. aethergraph/storage/eventlog/sqlite_event.py +47 -0
  226. aethergraph/storage/eventlog/sqlite_event_sync.py +178 -0
  227. aethergraph/storage/factory.py +432 -0
  228. aethergraph/storage/fs_utils.py +28 -0
  229. aethergraph/storage/graph_state_store/state_store.py +64 -0
  230. aethergraph/storage/kv/inmem_kv.py +103 -0
  231. aethergraph/storage/kv/layered_kv.py +52 -0
  232. aethergraph/storage/kv/sqlite_kv.py +39 -0
  233. aethergraph/storage/kv/sqlite_kv_sync.py +98 -0
  234. aethergraph/storage/memory/event_persist.py +68 -0
  235. aethergraph/storage/memory/fs_persist.py +118 -0
  236. aethergraph/{services/memory/hotlog_kv.py → storage/memory/hotlog.py} +8 -2
  237. aethergraph/{services → storage}/memory/indices.py +31 -7
  238. aethergraph/storage/metering/meter_event.py +55 -0
  239. aethergraph/storage/runs/doc_store.py +280 -0
  240. aethergraph/storage/runs/inmen_store.py +82 -0
  241. aethergraph/storage/runs/sqlite_run_store.py +403 -0
  242. aethergraph/storage/sessions/doc_store.py +183 -0
  243. aethergraph/storage/sessions/inmem_store.py +110 -0
  244. aethergraph/storage/sessions/sqlite_session_store.py +399 -0
  245. aethergraph/storage/vector_index/chroma_index.py +138 -0
  246. aethergraph/storage/vector_index/faiss_index.py +179 -0
  247. aethergraph/storage/vector_index/sqlite_index.py +187 -0
  248. {aethergraph-0.1.0a1.dist-info → aethergraph-0.1.0a2.dist-info}/METADATA +138 -31
  249. aethergraph-0.1.0a2.dist-info/RECORD +356 -0
  250. aethergraph-0.1.0a2.dist-info/entry_points.txt +3 -0
  251. aethergraph/services/artifacts/factory.py +0 -35
  252. aethergraph/services/artifacts/fs_store.py +0 -656
  253. aethergraph/services/artifacts/jsonl_index.py +0 -123
  254. aethergraph/services/artifacts/sqlite_index.py +0 -209
  255. aethergraph/services/memory/distillers/episode.py +0 -116
  256. aethergraph/services/memory/distillers/rolling.py +0 -74
  257. aethergraph/services/memory/facade.py +0 -633
  258. aethergraph/services/memory/persist_fs.py +0 -40
  259. aethergraph/services/rag/index/base.py +0 -27
  260. aethergraph/services/rag/index/faiss_index.py +0 -121
  261. aethergraph/services/rag/index/sqlite_index.py +0 -134
  262. aethergraph-0.1.0a1.dist-info/RECORD +0 -182
  263. aethergraph-0.1.0a1.dist-info/entry_points.txt +0 -2
  264. {aethergraph-0.1.0a1.dist-info → aethergraph-0.1.0a2.dist-info}/WHEEL +0 -0
  265. {aethergraph-0.1.0a1.dist-info → aethergraph-0.1.0a2.dist-info}/licenses/LICENSE +0 -0
  266. {aethergraph-0.1.0a1.dist-info → aethergraph-0.1.0a2.dist-info}/licenses/NOTICE +0 -0
  267. {aethergraph-0.1.0a1.dist-info → aethergraph-0.1.0a2.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
- import os
5
4
  from pathlib import Path
6
5
  from typing import Any
7
6
 
@@ -12,17 +11,25 @@ from aethergraph.config.config import AppSettings
12
11
  from aethergraph.contracts.services.llm import LLMClientProtocol
13
12
 
14
13
  # ---- scheduler ---- TODO: move to a separate server to handle scheduling across threads/processes
14
+ from aethergraph.contracts.services.metering import MeteringService
15
+ from aethergraph.contracts.services.runs import RunStore
16
+ from aethergraph.contracts.services.sessions import SessionStore
15
17
  from aethergraph.contracts.services.state_stores import GraphStateStore
18
+ from aethergraph.contracts.storage.artifact_index import AsyncArtifactIndex
19
+ from aethergraph.contracts.storage.artifact_store import AsyncArtifactStore
20
+ from aethergraph.contracts.storage.event_log import EventLog
16
21
  from aethergraph.core.execution.global_scheduler import GlobalForwardScheduler
17
22
 
18
23
  # ---- artifact services ----
19
- from aethergraph.services.artifacts.fs_store import FSArtifactStore # AsyncArtifactStore
20
- from aethergraph.services.artifacts.jsonl_index import JsonlArtifactIndex # AsyncArtifactIndex
21
- from aethergraph.services.auth.dev import AllowAllAuthz, DevTokenAuthn
24
+ from aethergraph.core.runtime.run_manager import RunManager
25
+ from aethergraph.core.runtime.runtime_registry import current_registry, set_current_registry
26
+ from aethergraph.services.auth.authn import DevTokenAuthn
27
+ from aethergraph.services.auth.authz import AllowAllAuthz
22
28
  from aethergraph.services.channel.channel_bus import ChannelBus
23
29
 
24
30
  # ---- channel services ----
25
31
  from aethergraph.services.channel.factory import build_bus, make_channel_adapters_from_env
32
+ from aethergraph.services.channel.ingress import ChannelIngress
26
33
  from aethergraph.services.clock.clock import SystemClock
27
34
  from aethergraph.services.continuations.stores.fs_store import (
28
35
  FSContinuationStore, # AsyncContinuationStore
@@ -30,8 +37,6 @@ from aethergraph.services.continuations.stores.fs_store import (
30
37
  from aethergraph.services.eventbus.inmem import InMemoryEventBus
31
38
 
32
39
  # ---- kv services ----
33
- from aethergraph.services.kv.ephemeral import EphemeralKV
34
- from aethergraph.services.kv.sqlite_kv import SQLiteKV
35
40
  from aethergraph.services.llm.factory import build_llm_clients
36
41
  from aethergraph.services.llm.service import LLMService
37
42
  from aethergraph.services.logger.std import LoggingConfig, StdLoggerService
@@ -39,26 +44,40 @@ from aethergraph.services.mcp.service import MCPService
39
44
 
40
45
  # ---- memory services ----
41
46
  from aethergraph.services.memory.factory import MemoryFactory
42
- from aethergraph.services.memory.hotlog_kv import KVHotLog
43
- from aethergraph.services.memory.indices import KVIndices
44
- from aethergraph.services.memory.persist_fs import FSPersistence
45
- from aethergraph.services.metering.noop import NoopMetering
47
+ from aethergraph.services.metering.eventlog_metering import EventLogMeteringService
46
48
  from aethergraph.services.prompts.file_store import FilePromptStore
47
49
  from aethergraph.services.rag.chunker import TextSplitter
48
50
  from aethergraph.services.rag.facade import RAGFacade
49
51
 
50
52
  # ---- RAG components ----
51
- from aethergraph.services.rag.index_factory import create_vector_index
53
+ from aethergraph.services.rate_limit.inmem_rate_limit import SimpleRateLimiter
52
54
  from aethergraph.services.redactor.simple import RegexRedactor # Simple PII redactor
53
55
  from aethergraph.services.registry.unified_registry import UnifiedRegistry
54
56
  from aethergraph.services.resume.multi_scheduler_resume_bus import MultiSchedulerResumeBus
55
57
  from aethergraph.services.resume.router import ResumeRouter
56
58
  from aethergraph.services.schedulers.registry import SchedulerRegistry
59
+ from aethergraph.services.scope.scope_factory import ScopeFactory
57
60
  from aethergraph.services.secrets.env import EnvSecrets
58
- from aethergraph.services.state_stores.json_store import JsonGraphStateStore
59
61
  from aethergraph.services.tracing.noop import NoopTracer
62
+ from aethergraph.services.viz.viz_service import VizService
60
63
  from aethergraph.services.waits.wait_registry import WaitRegistry
61
64
  from aethergraph.services.wakeup.memory_queue import ThreadSafeWakeupQueue
65
+ from aethergraph.storage.factory import (
66
+ build_artifact_index,
67
+ build_artifact_store,
68
+ build_continuation_store,
69
+ build_doc_store,
70
+ build_event_log,
71
+ build_graph_state_store,
72
+ build_memory_hotlog,
73
+ build_memory_indices,
74
+ build_memory_persistence,
75
+ build_run_store,
76
+ build_session_store,
77
+ build_vector_index,
78
+ )
79
+ from aethergraph.storage.kv.inmem_kv import InMemoryKV as EphemeralKV
80
+ from aethergraph.storage.metering.meter_event import EventLogMeteringStore
62
81
 
63
82
  SERVICE_KEYS = [
64
83
  # core
@@ -75,7 +94,6 @@ SERVICE_KEYS = [
75
94
  "wakeup_queue",
76
95
  # storage and artifacts
77
96
  "kv_hot",
78
- "kv_durable",
79
97
  "artifacts",
80
98
  "artifact_index",
81
99
  # memory
@@ -98,6 +116,9 @@ class DefaultContainer:
98
116
  # root
99
117
  root: str
100
118
 
119
+ # scope
120
+ scope_factory: ScopeFactory
121
+
101
122
  # schedulers
102
123
  schedulers: dict[str, Any]
103
124
 
@@ -120,25 +141,35 @@ class DefaultContainer:
120
141
 
121
142
  # storage and artifacts
122
143
  kv_hot: EphemeralKV
123
- kv_durable: SQLiteKV
124
- artifacts: FSArtifactStore
125
- artifact_index: JsonlArtifactIndex
144
+ artifacts: AsyncArtifactStore
145
+ artifact_index: AsyncArtifactIndex
146
+ eventlog: EventLog
126
147
 
127
148
  # memory
128
149
  memory_factory: MemoryFactory
129
150
 
151
+ # viz - only useful with frontend; otherwise this is a pure storage service for metrics and images
152
+ viz_service: VizService | None = None
153
+
130
154
  # optional llm service
131
155
  llm: LLMClientProtocol | None = None
132
156
  rag: RAGFacade | None = None
133
157
  mcp: MCPService | None = None
134
158
 
159
+ # run controls -- for http endpoints and run manager
160
+ run_store: RunStore | None = None
161
+ run_manager: RunManager | None = None # RunManager
162
+ session_store: SessionStore | None = None # SessionStore
163
+
135
164
  # optional services (not used by default)
136
165
  event_bus: InMemoryEventBus | None = None
137
166
  prompts: FilePromptStore | None = None
138
167
  authn: DevTokenAuthn | None = None
139
168
  authz: AllowAllAuthz | None = None
140
169
  redactor: RegexRedactor | None = None
141
- metering: NoopMetering | None = None
170
+
171
+ metering: MeteringService | None = None
172
+ rate_limiter: SimpleRateLimiter | None = None
142
173
  tracer: NoopTracer | None = None
143
174
  secrets: EnvSecrets | None = None
144
175
 
@@ -148,6 +179,9 @@ class DefaultContainer:
148
179
  # settings -- not a service, but useful to have around
149
180
  settings: AppSettings | None = None
150
181
 
182
+ # channel ingress (set after init to avoid circular dependency)
183
+ channel_ingress: ChannelIngress | None = None # set after init to avoid circular dependency
184
+
151
185
 
152
186
  def build_default_container(
153
187
  *,
@@ -172,20 +206,28 @@ def build_default_container(
172
206
  # we use user specified root if provided, else from config/env
173
207
  root_p = Path(root).resolve() if root else Path(cfg.root).resolve()
174
208
  (root_p / "kv").mkdir(parents=True, exist_ok=True)
175
- (root_p / "continuations").mkdir(parents=True, exist_ok=True)
176
209
  (root_p / "index").mkdir(parents=True, exist_ok=True)
177
210
  (root_p / "memory").mkdir(parents=True, exist_ok=True)
178
- (root_p / "graph_states").mkdir(parents=True, exist_ok=True)
211
+
212
+ # Scope factory
213
+ scope_factory = ScopeFactory()
214
+
215
+ # event log for metering and channel events --
216
+ # TODO: make configurable from cfg
217
+ eventlog = build_event_log(cfg)
179
218
 
180
219
  # core services
181
220
  logger_factory = StdLoggerService.build(
182
221
  LoggingConfig.from_cfg(cfg, log_dir=str(root_p / "logs"))
183
222
  )
184
223
  clock = SystemClock()
185
- registry = UnifiedRegistry()
224
+ # registry = UnifiedRegistry()
225
+ registry: UnifiedRegistry = current_registry()
226
+ set_current_registry(registry) # set global registry, ensure singleton (optional)
186
227
 
187
228
  # continuations and resume
188
- cont_store = FSContinuationStore(root=str(root_p / "continuations"), secret=os.urandom(32))
229
+ cont_store = build_continuation_store(cfg)
230
+
189
231
  sched_registry = SchedulerRegistry()
190
232
  wait_registry = WaitRegistry()
191
233
  resume_bus = MultiSchedulerResumeBus(
@@ -198,7 +240,8 @@ def build_default_container(
198
240
  wait_registry=wait_registry,
199
241
  )
200
242
  wakeup_queue = ThreadSafeWakeupQueue() # TODO: this is a placeholder, not fully implemented
201
- state_store = JsonGraphStateStore(root=str(root_p / "graph_states"))
243
+ # state_store = JsonGraphStateStore(root=str(root_p / "graph_states"))
244
+ state_store = build_graph_state_store(cfg)
202
245
 
203
246
  # global scheduler
204
247
  global_sched = GlobalForwardScheduler(
@@ -212,7 +255,7 @@ def build_default_container(
212
255
  }
213
256
 
214
257
  # channels
215
- channel_adapters = make_channel_adapters_from_env(cfg)
258
+ channel_adapters = make_channel_adapters_from_env(cfg, event_log=eventlog)
216
259
  channels = build_bus(
217
260
  channel_adapters,
218
261
  default="console:stdin",
@@ -221,18 +264,13 @@ def build_default_container(
221
264
  cont_store=cont_store,
222
265
  )
223
266
 
224
- # storage and artifacts
267
+ # storage and artifacts -- kv_hot has special methods for hot data, do not use other persistent kv here
225
268
  kv_hot = EphemeralKV()
226
- kv_durable = SQLiteKV(str(root_p / "kv" / "kv.sqlite"))
227
- artifacts = FSArtifactStore(
228
- str(root_p / "artifacts")
229
- ) # async wrapper over FileArtifactStoreSync
230
- artifact_index = JsonlArtifactIndex(str(root_p / "index" / "artifacts.jsonl"))
231
269
 
232
- # memory
233
- hotlog = KVHotLog(kv=kv_hot)
234
- persistence = FSPersistence(base_dir=str(root_p / "memory"))
235
- indices = KVIndices(kv=kv_durable, hot_ttl_s=7 * 24 * 3600)
270
+ artifacts = build_artifact_store(cfg)
271
+ artifact_index = build_artifact_index(cfg)
272
+
273
+ viz_service = VizService(event_log=eventlog)
236
274
 
237
275
  # optional services
238
276
  secrets = (
@@ -241,11 +279,8 @@ def build_default_container(
241
279
  llm_clients = build_llm_clients(cfg.llm, secrets) # return {profile: GenericLLMClient}
242
280
  llm_service = LLMService(clients=llm_clients) if llm_clients else None
243
281
 
244
- rag_cfg = cfg.rag
245
- vec_index = create_vector_index(
246
- backend=rag_cfg.backend, index_path=str(root_p / "rag" / "rag_index"), dim=rag_cfg.dim
247
- )
248
-
282
+ # RAG facade
283
+ vec_index = build_vector_index(cfg)
249
284
  rag_facade = RAGFacade(
250
285
  corpus_root=str(root_p / "rag" / "rag_corpora"),
251
286
  artifacts=artifacts,
@@ -257,11 +292,17 @@ def build_default_container(
257
292
  )
258
293
  mcp = MCPService() # empty MCP service; users can register clients as needed
259
294
 
295
+ # memory factory
296
+ persistence = build_memory_persistence(cfg)
297
+ hotlog = build_memory_hotlog(cfg)
298
+ indices = build_memory_indices(cfg)
299
+ docs = build_doc_store(cfg)
260
300
  memory_factory = MemoryFactory(
261
301
  hotlog=hotlog,
262
302
  persistence=persistence,
263
303
  indices=indices,
264
304
  artifacts=artifacts,
305
+ docs=docs,
265
306
  hot_limit=int(cfg.memory.hot_limit),
266
307
  hot_ttl_s=int(cfg.memory.hot_ttl_s),
267
308
  default_signal_threshold=float(cfg.memory.signal_threshold),
@@ -270,8 +311,35 @@ def build_default_container(
270
311
  rag_facade=rag_facade,
271
312
  )
272
313
 
273
- return DefaultContainer(
314
+ # run store and manager
315
+ run_store = build_run_store(cfg)
316
+ run_manager = RunManager(
317
+ run_store=run_store,
318
+ registry=registry,
319
+ sched_registry=sched_registry,
320
+ max_concurrent_runs=cfg.rate_limit.max_concurrent_runs,
321
+ )
322
+ session_store = build_session_store(cfg)
323
+
324
+ # Metering service
325
+ # TODO: make metering service configurable
326
+ metering_store = EventLogMeteringStore(event_log=eventlog)
327
+ metering = EventLogMeteringService(store=metering_store)
328
+
329
+ # rate limiter
330
+ rl_settings = cfg.rate_limit
331
+ rate_limiter = SimpleRateLimiter(
332
+ max_events=rl_settings.burst_max_runs,
333
+ window_seconds=rl_settings.burst_window_seconds,
334
+ )
335
+
336
+ # auth services
337
+ authn = DevTokenAuthn()
338
+ authz = AllowAllAuthz()
339
+
340
+ container = DefaultContainer(
274
341
  root=str(root_p),
342
+ scope_factory=scope_factory,
275
343
  schedulers=schedulers,
276
344
  registry=registry,
277
345
  logger=logger_factory,
@@ -284,25 +352,36 @@ def build_default_container(
284
352
  resume_router=resume_router,
285
353
  wakeup_queue=wakeup_queue,
286
354
  kv_hot=kv_hot,
287
- kv_durable=kv_durable,
288
355
  state_store=state_store,
289
356
  artifacts=artifacts,
290
357
  artifact_index=artifact_index,
358
+ viz_service=viz_service,
359
+ eventlog=eventlog,
291
360
  memory_factory=memory_factory,
292
361
  llm=llm_service,
293
362
  rag=rag_facade,
294
363
  mcp=mcp,
364
+ run_store=run_store,
365
+ run_manager=run_manager,
366
+ session_store=session_store,
295
367
  secrets=secrets,
296
368
  event_bus=None,
297
369
  prompts=None,
298
- authn=None,
299
- authz=None,
370
+ authn=authn,
371
+ authz=authz,
300
372
  redactor=None,
301
- metering=None,
373
+ metering=metering,
374
+ rate_limiter=rate_limiter,
302
375
  tracer=None,
303
376
  settings=cfg,
304
377
  )
305
378
 
379
+ # channel ingress (after container is built to avoid circular dependency)
380
+ container.channel_ingress = ChannelIngress(
381
+ container=container, logger=logger_factory.for_channel()
382
+ )
383
+ return container
384
+
306
385
 
307
386
  # Singleton (used unless the host sets their own)
308
387
  DEFAULT_CONTAINER: DefaultContainer | None = None
@@ -37,6 +37,12 @@ class Continuation:
37
37
  closed: bool = False # ← NEW
38
38
  payload: dict[str, Any] | None = None # set at creation time
39
39
 
40
+ # new session, etc.
41
+ session_id: str | None = None
42
+ agent_id: str | None = None
43
+ app_id: str | None = None
44
+ graph_id: str | None = None
45
+
40
46
  def to_dict(self) -> dict[str, Any]:
41
47
  return {
42
48
  "run_id": self.run_id,
@@ -95,6 +95,25 @@ class FSContinuationStore: # implements AsyncContinuationStore
95
95
 
96
96
  return await asyncio.to_thread(_read)
97
97
 
98
+ async def list_cont_by_run(self, run_id: str) -> list[Continuation]:
99
+ def _list():
100
+ out = []
101
+ run_path = self.root / "runs" / run_id / "nodes"
102
+ if not run_path.exists():
103
+ return out
104
+ for node_dir in run_path.iterdir():
105
+ cont_path = node_dir / "continuation.json"
106
+ if cont_path.exists():
107
+ raw = json.loads(cont_path.read_text(encoding="utf-8"))
108
+ for k in ("deadline", "next_wakeup_at", "created_at"):
109
+ if raw.get(k):
110
+ raw[k] = datetime.fromisoformat(raw[k])
111
+ raw["closed"] = bool(raw.get("closed", False))
112
+ out.append(Continuation(**raw))
113
+ return out
114
+
115
+ return await asyncio.to_thread(_list)
116
+
98
117
  async def delete(self, run_id: str, node_id: str) -> None:
99
118
  def _del():
100
119
  p = self._cont_path(run_id, node_id)
@@ -0,0 +1,76 @@
1
+ from __future__ import annotations
2
+
3
+ from collections import defaultdict
4
+ from collections.abc import Awaitable, Callable
5
+
6
+ Subscriber = Callable[[dict], Awaitable[None]]
7
+
8
+ """
9
+ Lightweight in-memory pub/sub hub for UI events.
10
+
11
+ This sits *alongside* EventLog:
12
+
13
+ - EventLog = durable storage (what HTTP polling uses)
14
+ - EventHub = transient fan-out for live WebSocket subscribers
15
+
16
+ Later:
17
+ - You can swap this for Redis/Kafka/etc without changing the adapters.
18
+ """
19
+
20
+
21
+ class EventHub:
22
+ """
23
+ Pub/sub keyed by (scope_id, kind).
24
+
25
+ For example:
26
+ scope_id="session:abc123", kind="session_chat"
27
+ scope_id="run:xyz456", kind="run_channel"
28
+ """
29
+
30
+ def __init__(self) -> None:
31
+ # (scope_id, kind) -> set of async callbacks
32
+ self._subs: dict[tuple[str, str], set[Subscriber]] = defaultdict(set)
33
+
34
+ def subscribe(self, scope_id: str, kind: str, cb: Subscriber) -> None:
35
+ """Register a callback that should receive new rows for this (scope, kind)."""
36
+ self._subs[(scope_id, kind)].add(cb)
37
+
38
+ def unsubscribe(self, scope_id: str, kind: str, cb: Subscriber) -> None:
39
+ """Remove a previously registered callback."""
40
+ key = (scope_id, kind)
41
+ subs = self._subs.get(key)
42
+ if not subs:
43
+ return
44
+ subs.discard(cb)
45
+ if not subs:
46
+ # Optional: cleanup empty sets
47
+ self._subs.pop(key, None)
48
+
49
+ async def broadcast(self, row: dict) -> None:
50
+ """
51
+ Push a new EventLog row to all subscribers.
52
+
53
+ Expected row schema:
54
+ {
55
+ "id": str,
56
+ "ts": float,
57
+ "scope_id": str,
58
+ "kind": str,
59
+ "payload": {...},
60
+ }
61
+ """
62
+ scope_id = row.get("scope_id")
63
+ kind = row.get("kind")
64
+ if not scope_id or not kind:
65
+ return
66
+
67
+ # Snapshot to avoid mutation during iteration
68
+ subs = list(self._subs.get((scope_id, kind), []))
69
+
70
+ for cb in subs:
71
+ try:
72
+ await cb(row)
73
+ except Exception:
74
+ # TODO: log error; maybe drop the subscriber if repeatedly failing
75
+ # For now, we ignore to avoid breaking others.
76
+ continue
File without changes