@alneas/eaos-server 0.0.0-stage → 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 (360) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.ja.md +49 -0
  4. package/README.md +46 -2
  5. package/dist/agentic/agent-jobs.d.ts +333 -0
  6. package/dist/agentic/agent-jobs.js +15 -0
  7. package/dist/agentic/agent-jobs.js.map +1 -0
  8. package/dist/agentic/agent-node.d.ts +40 -0
  9. package/dist/agentic/agent-node.js +7 -0
  10. package/dist/agentic/agent-node.js.map +1 -0
  11. package/dist/agentic/agent-runner.d.ts +33 -0
  12. package/dist/agentic/agent-runner.js +7 -0
  13. package/dist/agentic/agent-runner.js.map +1 -0
  14. package/dist/agentic/ai-broker.d.ts +169 -0
  15. package/dist/agentic/ai-broker.js +8 -0
  16. package/dist/agentic/ai-broker.js.map +1 -0
  17. package/dist/agentic/atomic-checkpointer.d.ts +137 -0
  18. package/dist/agentic/atomic-checkpointer.js +9 -0
  19. package/dist/agentic/atomic-checkpointer.js.map +1 -0
  20. package/dist/agentic/autonomous-worker.d.ts +122 -0
  21. package/dist/agentic/autonomous-worker.js +10 -0
  22. package/dist/agentic/autonomous-worker.js.map +1 -0
  23. package/dist/agentic/event-bridge.d.ts +350 -0
  24. package/dist/agentic/event-bridge.js +9 -0
  25. package/dist/agentic/event-bridge.js.map +1 -0
  26. package/dist/agentic/executor.d.ts +91 -0
  27. package/dist/agentic/executor.js +12 -0
  28. package/dist/agentic/executor.js.map +1 -0
  29. package/dist/agentic/graph-projection.d.ts +119 -0
  30. package/dist/agentic/graph-projection.js +7 -0
  31. package/dist/agentic/graph-projection.js.map +1 -0
  32. package/dist/agentic/graph.d.ts +524 -0
  33. package/dist/agentic/graph.js +7 -0
  34. package/dist/agentic/graph.js.map +1 -0
  35. package/dist/agentic/index.d.ts +28 -0
  36. package/dist/agentic/index.js +87 -0
  37. package/dist/agentic/index.js.map +1 -0
  38. package/dist/agentic/local-runner.d.ts +106 -0
  39. package/dist/agentic/local-runner.js +7 -0
  40. package/dist/agentic/local-runner.js.map +1 -0
  41. package/dist/agentic/remote-executor.d.ts +67 -0
  42. package/dist/agentic/remote-executor.js +8 -0
  43. package/dist/agentic/remote-executor.js.map +1 -0
  44. package/dist/agentic/types.d.ts +157 -0
  45. package/dist/agentic/types.js +7 -0
  46. package/dist/agentic/types.js.map +1 -0
  47. package/dist/agentic/workflow-catalog.d.ts +152 -0
  48. package/dist/agentic/workflow-catalog.js +7 -0
  49. package/dist/agentic/workflow-catalog.js.map +1 -0
  50. package/dist/agentic/workflow-compiler.d.ts +44 -0
  51. package/dist/agentic/workflow-compiler.js +8 -0
  52. package/dist/agentic/workflow-compiler.js.map +1 -0
  53. package/dist/agentic/workflow-coordinator.d.ts +170 -0
  54. package/dist/agentic/workflow-coordinator.js +8 -0
  55. package/dist/agentic/workflow-coordinator.js.map +1 -0
  56. package/dist/agentic/workflow-manager.d.ts +91 -0
  57. package/dist/agentic/workflow-manager.js +7 -0
  58. package/dist/agentic/workflow-manager.js.map +1 -0
  59. package/dist/agentic/workflow-registry.d.ts +334 -0
  60. package/dist/agentic/workflow-registry.js +7 -0
  61. package/dist/agentic/workflow-registry.js.map +1 -0
  62. package/dist/artifacts-CteHmCMI.d.ts +614 -0
  63. package/dist/auth-hooks/api-key.d.ts +75 -0
  64. package/dist/auth-hooks/api-key.js +7 -0
  65. package/dist/auth-hooks/api-key.js.map +1 -0
  66. package/dist/auth-hooks/index.d.ts +80 -0
  67. package/dist/auth-hooks/index.js +28 -0
  68. package/dist/auth-hooks/index.js.map +1 -0
  69. package/dist/browser-auth/account-memberships.d.ts +213 -0
  70. package/dist/browser-auth/account-memberships.js +13 -0
  71. package/dist/browser-auth/account-memberships.js.map +1 -0
  72. package/dist/browser-auth/index.d.ts +8 -0
  73. package/dist/browser-auth/index.js +59 -0
  74. package/dist/browser-auth/index.js.map +1 -0
  75. package/dist/browser-auth/kratos-session.d.ts +37 -0
  76. package/dist/browser-auth/kratos-session.js +7 -0
  77. package/dist/browser-auth/kratos-session.js.map +1 -0
  78. package/dist/browser-auth/platform-session.d.ts +120 -0
  79. package/dist/browser-auth/platform-session.js +7 -0
  80. package/dist/browser-auth/platform-session.js.map +1 -0
  81. package/dist/browser-auth/public-memberships.d.ts +22 -0
  82. package/dist/browser-auth/public-memberships.js +7 -0
  83. package/dist/browser-auth/public-memberships.js.map +1 -0
  84. package/dist/cache/index.d.ts +181 -0
  85. package/dist/cache/index.js +197 -0
  86. package/dist/cache/index.js.map +1 -0
  87. package/dist/chunk-32746UQZ.js +131 -0
  88. package/dist/chunk-32746UQZ.js.map +1 -0
  89. package/dist/chunk-3NLSWP2Y.js +223 -0
  90. package/dist/chunk-3NLSWP2Y.js.map +1 -0
  91. package/dist/chunk-3P4XTTQH.js +346 -0
  92. package/dist/chunk-3P4XTTQH.js.map +1 -0
  93. package/dist/chunk-3VITSHN3.js +15 -0
  94. package/dist/chunk-3VITSHN3.js.map +1 -0
  95. package/dist/chunk-46UWPEW2.js +226 -0
  96. package/dist/chunk-46UWPEW2.js.map +1 -0
  97. package/dist/chunk-4BARRLJR.js +180 -0
  98. package/dist/chunk-4BARRLJR.js.map +1 -0
  99. package/dist/chunk-4VORUFKR.js +45 -0
  100. package/dist/chunk-4VORUFKR.js.map +1 -0
  101. package/dist/chunk-55D4ERWO.js +1 -0
  102. package/dist/chunk-55D4ERWO.js.map +1 -0
  103. package/dist/chunk-5TBBZIND.js +18 -0
  104. package/dist/chunk-5TBBZIND.js.map +1 -0
  105. package/dist/chunk-5WOZWPZA.js +211 -0
  106. package/dist/chunk-5WOZWPZA.js.map +1 -0
  107. package/dist/chunk-6CBVZ6CT.js +168 -0
  108. package/dist/chunk-6CBVZ6CT.js.map +1 -0
  109. package/dist/chunk-6XZXYNJR.js +74 -0
  110. package/dist/chunk-6XZXYNJR.js.map +1 -0
  111. package/dist/chunk-753HWDSC.js +222 -0
  112. package/dist/chunk-753HWDSC.js.map +1 -0
  113. package/dist/chunk-7AHSS7SO.js +81 -0
  114. package/dist/chunk-7AHSS7SO.js.map +1 -0
  115. package/dist/chunk-7FTJN4SA.js +1 -0
  116. package/dist/chunk-7FTJN4SA.js.map +1 -0
  117. package/dist/chunk-AVDMLTPF.js +24 -0
  118. package/dist/chunk-AVDMLTPF.js.map +1 -0
  119. package/dist/chunk-BKAHUEIT.js +95 -0
  120. package/dist/chunk-BKAHUEIT.js.map +1 -0
  121. package/dist/chunk-CJ7OFEF7.js +134 -0
  122. package/dist/chunk-CJ7OFEF7.js.map +1 -0
  123. package/dist/chunk-EJKWDZIU.js +111 -0
  124. package/dist/chunk-EJKWDZIU.js.map +1 -0
  125. package/dist/chunk-F2J6IQ6I.js +247 -0
  126. package/dist/chunk-F2J6IQ6I.js.map +1 -0
  127. package/dist/chunk-F3O7CELI.js +23 -0
  128. package/dist/chunk-F3O7CELI.js.map +1 -0
  129. package/dist/chunk-F4IITPGX.js +221 -0
  130. package/dist/chunk-F4IITPGX.js.map +1 -0
  131. package/dist/chunk-FD6VC2NA.js +66 -0
  132. package/dist/chunk-FD6VC2NA.js.map +1 -0
  133. package/dist/chunk-FRRRWAHO.js +14 -0
  134. package/dist/chunk-FRRRWAHO.js.map +1 -0
  135. package/dist/chunk-HCKAGLLB.js +17 -0
  136. package/dist/chunk-HCKAGLLB.js.map +1 -0
  137. package/dist/chunk-HVC7FG6B.js +191 -0
  138. package/dist/chunk-HVC7FG6B.js.map +1 -0
  139. package/dist/chunk-HXFVOR7Z.js +496 -0
  140. package/dist/chunk-HXFVOR7Z.js.map +1 -0
  141. package/dist/chunk-IJWYS2PF.js +122 -0
  142. package/dist/chunk-IJWYS2PF.js.map +1 -0
  143. package/dist/chunk-INCHXAFK.js +1395 -0
  144. package/dist/chunk-INCHXAFK.js.map +1 -0
  145. package/dist/chunk-JT6BRGQM.js +1 -0
  146. package/dist/chunk-JT6BRGQM.js.map +1 -0
  147. package/dist/chunk-L6PMAEMB.js +115 -0
  148. package/dist/chunk-L6PMAEMB.js.map +1 -0
  149. package/dist/chunk-LOUGW6MU.js +126 -0
  150. package/dist/chunk-LOUGW6MU.js.map +1 -0
  151. package/dist/chunk-LYPZPE53.js +129 -0
  152. package/dist/chunk-LYPZPE53.js.map +1 -0
  153. package/dist/chunk-NNCCN7JP.js +186 -0
  154. package/dist/chunk-NNCCN7JP.js.map +1 -0
  155. package/dist/chunk-PBC3MZUL.js +212 -0
  156. package/dist/chunk-PBC3MZUL.js.map +1 -0
  157. package/dist/chunk-R4ADP2DC.js +20 -0
  158. package/dist/chunk-R4ADP2DC.js.map +1 -0
  159. package/dist/chunk-RHN4Y6VS.js +44 -0
  160. package/dist/chunk-RHN4Y6VS.js.map +1 -0
  161. package/dist/chunk-SDJNYPYK.js +770 -0
  162. package/dist/chunk-SDJNYPYK.js.map +1 -0
  163. package/dist/chunk-UGNTCOVR.js +28 -0
  164. package/dist/chunk-UGNTCOVR.js.map +1 -0
  165. package/dist/chunk-VC2PCK2S.js +31 -0
  166. package/dist/chunk-VC2PCK2S.js.map +1 -0
  167. package/dist/chunk-VF5YDZJC.js +305 -0
  168. package/dist/chunk-VF5YDZJC.js.map +1 -0
  169. package/dist/chunk-VISRDVTK.js +675 -0
  170. package/dist/chunk-VISRDVTK.js.map +1 -0
  171. package/dist/chunk-W6O3LVBY.js +102 -0
  172. package/dist/chunk-W6O3LVBY.js.map +1 -0
  173. package/dist/chunk-WFEAKJLR.js +47 -0
  174. package/dist/chunk-WFEAKJLR.js.map +1 -0
  175. package/dist/chunk-XIEY2OF4.js +67 -0
  176. package/dist/chunk-XIEY2OF4.js.map +1 -0
  177. package/dist/chunk-XITLHDG3.js +37 -0
  178. package/dist/chunk-XITLHDG3.js.map +1 -0
  179. package/dist/chunk-XMWPYZWZ.js +61 -0
  180. package/dist/chunk-XMWPYZWZ.js.map +1 -0
  181. package/dist/chunk-XUP6CNOM.js +34 -0
  182. package/dist/chunk-XUP6CNOM.js.map +1 -0
  183. package/dist/chunk-YABTQZDJ.js +25 -0
  184. package/dist/chunk-YABTQZDJ.js.map +1 -0
  185. package/dist/chunk-YMHVRBUU.js +199 -0
  186. package/dist/chunk-YMHVRBUU.js.map +1 -0
  187. package/dist/chunk-YMJ7BRKU.js +510 -0
  188. package/dist/chunk-YMJ7BRKU.js.map +1 -0
  189. package/dist/chunk-ZC3XWU7B.js +28 -0
  190. package/dist/chunk-ZC3XWU7B.js.map +1 -0
  191. package/dist/chunk-ZHMTD5KV.js +90 -0
  192. package/dist/chunk-ZHMTD5KV.js.map +1 -0
  193. package/dist/chunk-ZWZDLOE7.js +160 -0
  194. package/dist/chunk-ZWZDLOE7.js.map +1 -0
  195. package/dist/db-package/db/local-first-sqlite-adapter.d.ts +432 -0
  196. package/dist/db-package/db/local-first-sqlite-adapter.js +7 -0
  197. package/dist/db-package/db/local-first-sqlite-adapter.js.map +1 -0
  198. package/dist/db-package/index.d.ts +7 -0
  199. package/dist/db-package/index.js +16 -0
  200. package/dist/db-package/index.js.map +1 -0
  201. package/dist/db-package/migration/aggregator.d.ts +86 -0
  202. package/dist/db-package/migration/aggregator.js +7 -0
  203. package/dist/db-package/migration/aggregator.js.map +1 -0
  204. package/dist/db-package/migration/index.d.ts +3 -0
  205. package/dist/db-package/migration/index.js +8 -0
  206. package/dist/db-package/migration/index.js.map +1 -0
  207. package/dist/engine.d.ts +205 -0
  208. package/dist/engine.js +20 -0
  209. package/dist/engine.js.map +1 -0
  210. package/dist/entitlements/index.d.ts +313 -0
  211. package/dist/entitlements/index.js +23 -0
  212. package/dist/entitlements/index.js.map +1 -0
  213. package/dist/execution/chat.d.ts +7 -0
  214. package/dist/execution/chat.js +7 -0
  215. package/dist/execution/chat.js.map +1 -0
  216. package/dist/execution/index.d.ts +342 -0
  217. package/dist/execution/index.js +66 -0
  218. package/dist/execution/index.js.map +1 -0
  219. package/dist/execution/tool-agent.d.ts +7 -0
  220. package/dist/execution/tool-agent.js +8 -0
  221. package/dist/execution/tool-agent.js.map +1 -0
  222. package/dist/extensions/index.d.ts +172 -0
  223. package/dist/extensions/index.js +95 -0
  224. package/dist/extensions/index.js.map +1 -0
  225. package/dist/health/index.d.ts +35 -0
  226. package/dist/health/index.js +7 -0
  227. package/dist/health/index.js.map +1 -0
  228. package/dist/index.d.ts +43 -0
  229. package/dist/index.js +161 -0
  230. package/dist/index.js.map +1 -0
  231. package/dist/lifecycle/index.d.ts +133 -0
  232. package/dist/lifecycle/index.js +13 -0
  233. package/dist/lifecycle/index.js.map +1 -0
  234. package/dist/lifecycle-engine/backend-migration.d.ts +2 -0
  235. package/dist/lifecycle-engine/backend-migration.js +11 -0
  236. package/dist/lifecycle-engine/backend-migration.js.map +1 -0
  237. package/dist/lifecycle-engine/baseline.d.ts +2 -0
  238. package/dist/lifecycle-engine/baseline.js +9 -0
  239. package/dist/lifecycle-engine/baseline.js.map +1 -0
  240. package/dist/lifecycle-engine/index.d.ts +1497 -0
  241. package/dist/lifecycle-engine/index.js +41 -0
  242. package/dist/lifecycle-engine/index.js.map +1 -0
  243. package/dist/lifecycle-engine/platform/artifacts.d.ts +4 -0
  244. package/dist/lifecycle-engine/platform/artifacts.js +7 -0
  245. package/dist/lifecycle-engine/platform/artifacts.js.map +1 -0
  246. package/dist/lifecycle-engine/platform/control-plane.d.ts +12 -0
  247. package/dist/lifecycle-engine/platform/control-plane.js +2 -0
  248. package/dist/lifecycle-engine/platform/control-plane.js.map +1 -0
  249. package/dist/lifecycle-engine/platform/database-router.d.ts +118 -0
  250. package/dist/lifecycle-engine/platform/database-router.js +7 -0
  251. package/dist/lifecycle-engine/platform/database-router.js.map +1 -0
  252. package/dist/lifecycle-engine/platform/deployment-placements.d.ts +464 -0
  253. package/dist/lifecycle-engine/platform/deployment-placements.js +16 -0
  254. package/dist/lifecycle-engine/platform/deployment-placements.js.map +1 -0
  255. package/dist/lifecycle-engine/platform/deployment.d.ts +4 -0
  256. package/dist/lifecycle-engine/platform/deployment.js +17 -0
  257. package/dist/lifecycle-engine/platform/deployment.js.map +1 -0
  258. package/dist/lifecycle-engine/platform/index.d.ts +737 -0
  259. package/dist/lifecycle-engine/platform/index.js +60 -0
  260. package/dist/lifecycle-engine/platform/index.js.map +1 -0
  261. package/dist/lifecycle-engine/platform/runtime.d.ts +80 -0
  262. package/dist/lifecycle-engine/platform/runtime.js +11 -0
  263. package/dist/lifecycle-engine/platform/runtime.js.map +1 -0
  264. package/dist/lifecycle-engine/platform/site-publication.d.ts +102 -0
  265. package/dist/lifecycle-engine/platform/site-publication.js +7 -0
  266. package/dist/lifecycle-engine/platform/site-publication.js.map +1 -0
  267. package/dist/lifecycle-engine/platform/user-directory.d.ts +139 -0
  268. package/dist/lifecycle-engine/platform/user-directory.js +13 -0
  269. package/dist/lifecycle-engine/platform/user-directory.js.map +1 -0
  270. package/dist/mcp.d.ts +92 -0
  271. package/dist/mcp.js +10 -0
  272. package/dist/mcp.js.map +1 -0
  273. package/dist/middleware/auth.d.ts +118 -0
  274. package/dist/middleware/auth.js +7 -0
  275. package/dist/middleware/auth.js.map +1 -0
  276. package/dist/middleware/error-handler.d.ts +35 -0
  277. package/dist/middleware/error-handler.js +7 -0
  278. package/dist/middleware/error-handler.js.map +1 -0
  279. package/dist/middleware/module-guard.d.ts +33 -0
  280. package/dist/middleware/module-guard.js +7 -0
  281. package/dist/middleware/module-guard.js.map +1 -0
  282. package/dist/platform-admin/index.d.ts +37 -0
  283. package/dist/platform-admin/index.js +11 -0
  284. package/dist/platform-admin/index.js.map +1 -0
  285. package/dist/platform-admin/store.d.ts +346 -0
  286. package/dist/platform-admin/store.js +7 -0
  287. package/dist/platform-admin/store.js.map +1 -0
  288. package/dist/plugin-data/annotations.d.ts +6 -0
  289. package/dist/plugin-data/annotations.js +12 -0
  290. package/dist/plugin-data/annotations.js.map +1 -0
  291. package/dist/plugin-data/atomic-context.d.ts +41 -0
  292. package/dist/plugin-data/atomic-context.js +9 -0
  293. package/dist/plugin-data/atomic-context.js.map +1 -0
  294. package/dist/plugin-data/atomic.d.ts +6 -0
  295. package/dist/plugin-data/atomic.js +26 -0
  296. package/dist/plugin-data/atomic.js.map +1 -0
  297. package/dist/plugin-data/audit.d.ts +6 -0
  298. package/dist/plugin-data/audit.js +12 -0
  299. package/dist/plugin-data/audit.js.map +1 -0
  300. package/dist/plugin-data/commands.d.ts +6 -0
  301. package/dist/plugin-data/commands.js +8 -0
  302. package/dist/plugin-data/commands.js.map +1 -0
  303. package/dist/plugin-data/composite.d.ts +6 -0
  304. package/dist/plugin-data/composite.js +8 -0
  305. package/dist/plugin-data/composite.js.map +1 -0
  306. package/dist/plugin-data/delivery.d.ts +6 -0
  307. package/dist/plugin-data/delivery.js +16 -0
  308. package/dist/plugin-data/delivery.js.map +1 -0
  309. package/dist/plugin-data/index.d.ts +2798 -0
  310. package/dist/plugin-data/index.js +102 -0
  311. package/dist/plugin-data/index.js.map +1 -0
  312. package/dist/plugin-data/json-documents.d.ts +6 -0
  313. package/dist/plugin-data/json-documents.js +16 -0
  314. package/dist/plugin-data/json-documents.js.map +1 -0
  315. package/dist/plugin-data/outbox.d.ts +6 -0
  316. package/dist/plugin-data/outbox.js +16 -0
  317. package/dist/plugin-data/outbox.js.map +1 -0
  318. package/dist/plugin-data/scoped-records.d.ts +6 -0
  319. package/dist/plugin-data/scoped-records.js +10 -0
  320. package/dist/plugin-data/scoped-records.js.map +1 -0
  321. package/dist/plugin-sdk.d.ts +41 -0
  322. package/dist/plugin-sdk.js +10 -0
  323. package/dist/plugin-sdk.js.map +1 -0
  324. package/dist/sql-lifecycle/index.d.ts +138 -0
  325. package/dist/sql-lifecycle/index.js +167 -0
  326. package/dist/sql-lifecycle/index.js.map +1 -0
  327. package/dist/storage/index.d.ts +2 -0
  328. package/dist/storage/index.js +13 -0
  329. package/dist/storage/index.js.map +1 -0
  330. package/dist/storage/s3-compatible.d.ts +139 -0
  331. package/dist/storage/s3-compatible.js +11 -0
  332. package/dist/storage/s3-compatible.js.map +1 -0
  333. package/dist/tenant.d.ts +108 -0
  334. package/dist/tenant.js +9 -0
  335. package/dist/tenant.js.map +1 -0
  336. package/dist/workspace-context.d.ts +119 -0
  337. package/dist/workspace-context.js +9 -0
  338. package/dist/workspace-context.js.map +1 -0
  339. package/docs/api.md +30560 -0
  340. package/docs/db/README.md +49 -0
  341. package/docs/db/docs/api.md +1613 -0
  342. package/docs/db/docs/guide.md +47 -0
  343. package/docs/entitlements.md +60 -0
  344. package/docs/guide.md +92 -0
  345. package/docs/index.md +57 -0
  346. package/docs/ja/db/README.md +46 -0
  347. package/docs/ja/db/docs/guide.md +53 -0
  348. package/docs/ja/guide.md +46 -0
  349. package/docs/ja/lifecycle/README.md +46 -0
  350. package/docs/ja/lifecycle/docs/guide.md +45 -0
  351. package/docs/ja/storage/README.md +46 -0
  352. package/docs/ja/storage/docs/guide.md +43 -0
  353. package/docs/lifecycle/README.md +49 -0
  354. package/docs/lifecycle/docs/api.md +3770 -0
  355. package/docs/lifecycle/docs/baseline.md +50 -0
  356. package/docs/lifecycle/docs/guide.md +47 -0
  357. package/docs/storage/README.md +49 -0
  358. package/docs/storage/docs/api.md +470 -0
  359. package/docs/storage/docs/guide.md +47 -0
  360. package/package.json +354 -4
@@ -0,0 +1,95 @@
1
+ // src/tenant.ts
2
+ var TenantResolver = class {
3
+ defaultTenantId;
4
+ domainTenantMap;
5
+ hostTenantMap;
6
+ /**
7
+ * Copies routing mappings, normalizing their keys to lower case.
8
+ * @param options - Routing mappings and fallback; omitted options use empty mappings and "default".
9
+ */
10
+ constructor(options = {}) {
11
+ this.defaultTenantId = options.defaultTenantId ?? "default";
12
+ this.domainTenantMap = new Map(
13
+ Object.entries(options.domainTenantMap ?? {}).map(([k, v]) => [k.toLowerCase(), v])
14
+ );
15
+ this.hostTenantMap = new Map(
16
+ Object.entries(options.hostTenantMap ?? {}).map(([k, v]) => [k.toLowerCase(), v])
17
+ );
18
+ }
19
+ /**
20
+ * Looks up the lower-case domain following the first @ in an email routing hint.
21
+ * @param email - Email hint; missing, empty, or missing @ returns null. No address validation is performed.
22
+ * @returns The configured routing ID, or null when no domain matches.
23
+ * @example
24
+ * ```typescript
25
+ * import { TenantResolver } from "@alneas/eaos-server/tenant";
26
+ * const resolver = new TenantResolver({ domainTenantMap: { "example.com": "workspace" } });
27
+ * console.log(resolver.resolveFromEmail("person@example.com"));
28
+ * ```
29
+ */
30
+ resolveFromEmail(email) {
31
+ if (!email) return null;
32
+ const parts = email.split("@");
33
+ if (parts.length < 2) return null;
34
+ const domain = parts[1].toLowerCase();
35
+ return this.domainTenantMap.get(domain) ?? null;
36
+ }
37
+ /**
38
+ * Looks up a configured hostname after removing text following the first colon and lower-casing.
39
+ * @param host - Host routing hint, optionally including a port; missing or empty values return null. IPv6 host parsing is not provided.
40
+ * @returns The exact configured host mapping, or null.
41
+ * @example
42
+ * ```typescript
43
+ * import { TenantResolver } from "@alneas/eaos-server/tenant";
44
+ * const resolver = new TenantResolver({ hostTenantMap: { "workspace.example.com": "workspace" } });
45
+ * console.log(resolver.resolveFromHost("workspace.example.com:443"));
46
+ * ```
47
+ */
48
+ resolveFromHost(host) {
49
+ if (!host) return null;
50
+ const cleanHost = host.split(":")[0].toLowerCase();
51
+ if (this.hostTenantMap.has(cleanHost)) {
52
+ return this.hostTenantMap.get(cleanHost);
53
+ }
54
+ return null;
55
+ }
56
+ /**
57
+ * Selects a truthy explicit ID, then a host mapping, then the configured fallback.
58
+ * @param input - Routing hints: explicitTenantId takes precedence over host; email is intentionally ignored. The host must establish whether an explicit ID is trusted.
59
+ * @returns The selected routing ID, without validating tenant existence or membership.
60
+ * @see TenantResolver for a complete usage example.
61
+ * @example
62
+ * ```typescript
63
+ * import { TenantResolver } from "@alneas/eaos-server/tenant";
64
+ * const resolver = new TenantResolver();
65
+ * console.log(resolver.resolve({ explicitTenantId: "workspace" }));
66
+ * ```
67
+ */
68
+ resolve(input) {
69
+ if (input.explicitTenantId) return input.explicitTenantId;
70
+ const fromHost = this.resolveFromHost(input.host);
71
+ if (fromHost) return fromHost;
72
+ return this.defaultTenantId;
73
+ }
74
+ /**
75
+ * Reads the fallback ID captured at construction.
76
+ * @returns The configured fallback, or "default" when none was supplied.
77
+ * @example
78
+ * ```typescript
79
+ * import { TenantResolver } from "@alneas/eaos-server/tenant";
80
+ * console.log(new TenantResolver().getDefaultTenantId());
81
+ * ```
82
+ */
83
+ getDefaultTenantId() {
84
+ return this.defaultTenantId;
85
+ }
86
+ };
87
+ function createTenantResolver(options) {
88
+ return new TenantResolver(options);
89
+ }
90
+
91
+ export {
92
+ TenantResolver,
93
+ createTenantResolver
94
+ };
95
+ //# sourceMappingURL=chunk-BKAHUEIT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tenant.ts"],"sourcesContent":["/**\n * Routing hints used by {@link TenantResolver}; they do not authenticate a tenant.\n * @see TenantResolver for a complete usage example.\n */\nexport interface TenantResolverOptions {\n /** Fallback when no explicit ID or host mapping matches. @defaultValue \"default\" */\n defaultTenantId?: string\n /** Routing-only email domain mappings. Never use email-derived results as an authenticated tenant claim. */\n domainTenantMap?: Record<string, string>\n /** Trusted, exact hostname mappings (e.g. { \"demo.example.com\": \"tenant-demo\" }). */\n hostTenantMap?: Record<string, string>\n}\n\n/**\n * Selects a tenant routing ID from an explicit trusted ID, configured host, or fallback.\n * @remarks This resolver performs no authentication or membership check. Host headers and explicit IDs must be validated by the host before being used for authorization. Email mappings are exposed only by resolveFromEmail.\n * @example\n * ```typescript\n * import { TenantResolver } from \"@alneas/eaos-server/tenant\";\n * const resolver = new TenantResolver({ hostTenantMap: { \"workspace.example.com\": \"workspace\" } });\n * const tenantId = resolver.resolve({ host: \"workspace.example.com:443\" });\n * console.log(tenantId); // \"workspace\"\n * ```\n */\nexport class TenantResolver {\n private defaultTenantId: string\n private domainTenantMap: Map<string, string>\n private hostTenantMap: Map<string, string>\n\n /**\n * Copies routing mappings, normalizing their keys to lower case.\n * @param options - Routing mappings and fallback; omitted options use empty mappings and \"default\".\n */\n constructor(options: TenantResolverOptions = {}) {\n this.defaultTenantId = options.defaultTenantId ?? 'default'\n this.domainTenantMap = new Map(\n Object.entries(options.domainTenantMap ?? {}).map(([k, v]) => [k.toLowerCase(), v])\n )\n this.hostTenantMap = new Map(\n Object.entries(options.hostTenantMap ?? {}).map(([k, v]) => [k.toLowerCase(), v])\n )\n }\n\n /**\n * Looks up the lower-case domain following the first @ in an email routing hint.\n * @param email - Email hint; missing, empty, or missing @ returns null. No address validation is performed.\n * @returns The configured routing ID, or null when no domain matches.\n * @example\n * ```typescript\n * import { TenantResolver } from \"@alneas/eaos-server/tenant\";\n * const resolver = new TenantResolver({ domainTenantMap: { \"example.com\": \"workspace\" } });\n * console.log(resolver.resolveFromEmail(\"person@example.com\"));\n * ```\n */\n resolveFromEmail(email: string | null | undefined): string | null {\n if (!email) return null\n const parts = email.split('@')\n if (parts.length < 2) return null\n const domain = parts[1].toLowerCase()\n return this.domainTenantMap.get(domain) ?? null\n }\n\n /**\n * Looks up a configured hostname after removing text following the first colon and lower-casing.\n * @param host - Host routing hint, optionally including a port; missing or empty values return null. IPv6 host parsing is not provided.\n * @returns The exact configured host mapping, or null.\n * @example\n * ```typescript\n * import { TenantResolver } from \"@alneas/eaos-server/tenant\";\n * const resolver = new TenantResolver({ hostTenantMap: { \"workspace.example.com\": \"workspace\" } });\n * console.log(resolver.resolveFromHost(\"workspace.example.com:443\"));\n * ```\n */\n resolveFromHost(host: string | null | undefined): string | null {\n if (!host) return null\n const cleanHost = host.split(':')[0].toLowerCase()\n if (this.hostTenantMap.has(cleanHost)) {\n return this.hostTenantMap.get(cleanHost)!\n }\n return null\n }\n\n /**\n * Selects a truthy explicit ID, then a host mapping, then the configured fallback.\n * @param input - Routing hints: explicitTenantId takes precedence over host; email is intentionally ignored. The host must establish whether an explicit ID is trusted.\n * @returns The selected routing ID, without validating tenant existence or membership.\n * @see TenantResolver for a complete usage example.\n * @example\n * ```typescript\n * import { TenantResolver } from \"@alneas/eaos-server/tenant\";\n * const resolver = new TenantResolver();\n * console.log(resolver.resolve({ explicitTenantId: \"workspace\" }));\n * ```\n */\n resolve(input: { \n /**\n * Optional host routing hint, including a possible port; checked only after a falsy/absent explicitTenantId against configured exact host mappings.\n */\n host?: string | null; \n /**\n * Optional compatibility routing hint intentionally ignored by resolve; an email domain is not an authenticated tenant claim.\n */\n email?: string | null; \n /**\n * Optional trusted tenant routing selection; any truthy value takes precedence without tenant-existence or membership validation.\n */\n explicitTenantId?: string | null }): string {\n if (input.explicitTenantId) return input.explicitTenantId\n // Email domains are routing hints only; they are deliberately not accepted\n // as an authenticated tenant selector.\n const fromHost = this.resolveFromHost(input.host)\n if (fromHost) return fromHost\n return this.defaultTenantId\n }\n\n /**\n * Reads the fallback ID captured at construction.\n * @returns The configured fallback, or \"default\" when none was supplied.\n * @example\n * ```typescript\n * import { TenantResolver } from \"@alneas/eaos-server/tenant\";\n * console.log(new TenantResolver().getDefaultTenantId());\n * ```\n */\n getDefaultTenantId(): string {\n return this.defaultTenantId\n }\n}\n\n/**\n * Creates a resolver for host-owned tenant routing hints.\n * @param options - Routing mappings and fallback; see {@link TenantResolverOptions}.\n * @returns A new independent resolver with copied mappings.\n * @example\n * ```typescript\n * import { createTenantResolver } from \"@alneas/eaos-server/tenant\";\n * const resolver = createTenantResolver({ defaultTenantId: \"workspace\" });\n * console.log(resolver.resolve({}));\n * ```\n */\nexport function createTenantResolver(options?: TenantResolverOptions): TenantResolver {\n return new TenantResolver(options)\n}\n"],"mappings":";AAwBO,IAAM,iBAAN,MAAqB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMR,YAAY,UAAiC,CAAC,GAAG;AAC/C,SAAK,kBAAkB,QAAQ,mBAAmB;AAClD,SAAK,kBAAkB,IAAI;AAAA,MACzB,OAAO,QAAQ,QAAQ,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC;AAAA,IACpF;AACA,SAAK,gBAAgB,IAAI;AAAA,MACvB,OAAO,QAAQ,QAAQ,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC;AAAA,IAClF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,iBAAiB,OAAiD;AAChE,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,UAAM,SAAS,MAAM,CAAC,EAAE,YAAY;AACpC,WAAO,KAAK,gBAAgB,IAAI,MAAM,KAAK;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,gBAAgB,MAAgD;AAC9D,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,YAAY,KAAK,MAAM,GAAG,EAAE,CAAC,EAAE,YAAY;AACjD,QAAI,KAAK,cAAc,IAAI,SAAS,GAAG;AACrC,aAAO,KAAK,cAAc,IAAI,SAAS;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,QAAQ,OAYoC;AAC1C,QAAI,MAAM,iBAAkB,QAAO,MAAM;AAGzC,UAAM,WAAW,KAAK,gBAAgB,MAAM,IAAI;AAChD,QAAI,SAAU,QAAO;AACrB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,qBAA6B;AAC3B,WAAO,KAAK;AAAA,EACd;AACF;AAaO,SAAS,qBAAqB,SAAiD;AACpF,SAAO,IAAI,eAAe,OAAO;AACnC;","names":[]}
@@ -0,0 +1,134 @@
1
+ import {
2
+ AgentGraphEngine
3
+ } from "./chunk-HXFVOR7Z.js";
4
+
5
+ // src/agentic/workflow-compiler.ts
6
+ import { evaluateWorkflowCondition, validateWorkflowDefinition } from "@alneas/eaos-core";
7
+ async function compileWorkflowDefinition(input, options) {
8
+ const definition = validateWorkflowDefinition(input);
9
+ if (!options?.catalog) throw new Error("Workflow node catalog is required");
10
+ const graph = new AgentGraphEngine({
11
+ checkpointer: options.checkpointer,
12
+ authorizeResume: options.authorizeResume,
13
+ workflowId: definition.workflowId,
14
+ workflowVersion: definition.version
15
+ });
16
+ for (const node of definition.nodes) {
17
+ const registration = options.catalog.require(node.type);
18
+ const visual = visualNode(node, registration.descriptor);
19
+ if (node.subflow) {
20
+ if (!registration.resolveSubgraph) throw new Error(`Workflow node '${node.id}' declares a subflow but '${node.type}' has no subgraph resolver`);
21
+ const subgraph = await registration.resolveSubgraph({ definition, node });
22
+ if (!subgraph || typeof subgraph.invoke !== "function") throw new Error(`Workflow subflow '${node.id}' did not resolve to a compiled graph`);
23
+ graph.addSubgraph(node.id, subgraph, {
24
+ visual,
25
+ mapInput: (state) => node.subflow?.inputPath ? valueAtPath(state, node.subflow.inputPath).value : state,
26
+ mapOutput: (output, state) => ({ context: { ...state.context ?? {}, [node.subflow?.outputKey ?? `${node.id}.output`]: structuredClone(output) } })
27
+ });
28
+ continue;
29
+ }
30
+ const handler = await registration.resolve({ definition, node });
31
+ if (typeof handler !== "function") throw new Error(`Workflow node '${node.id}' did not resolve to a handler`);
32
+ graph.addNode(node.id, wrapNode(node, handler), { retryPolicy: retryPolicy(node), visual });
33
+ }
34
+ graph.setEntryPoint(definition.entryNode);
35
+ for (const node of definition.nodes) {
36
+ const outgoing = definition.edges.filter((edge) => edge.from === node.id);
37
+ if (!outgoing.length) continue;
38
+ for (const edge of outgoing) graph.addEdge(edge.from, edge.to, { visual: edgeVisual(edge) });
39
+ if (outgoing.some((edge) => edge.condition !== void 0)) {
40
+ const destinations = [...new Set(outgoing.map((edge) => edge.to))];
41
+ graph.addConditionalEdges(node.id, (state) => routeDefinitionEdges(outgoing, state), destinations, {
42
+ labels: Object.fromEntries(outgoing.map((edge) => [edge.to, edge.label ?? (edge.condition ? "\u6761\u4EF6\u5206\u5C90" : "\u65E2\u5B9A")])),
43
+ visual: { kind: "conditional" }
44
+ });
45
+ }
46
+ }
47
+ return { definition, graph };
48
+ }
49
+ function wrapNode(node, handler) {
50
+ return async (state) => {
51
+ const handlerState = node.toolScope ? { ...structuredClone(state), context: { ...state.context ?? {}, __eaosWorkflowToolScope: structuredClone(node.toolScope) } } : structuredClone(state);
52
+ const update = await withTimeout(handler(handlerState), node.timeoutMs, node.id);
53
+ if (!node.approval) return update;
54
+ const existing = update.pendingApproval;
55
+ const args = existing?.args ?? (node.approval.argsPath ? valueAtPath({ ...state, ...update }, node.approval.argsPath).value : {});
56
+ if (!isRecord(args)) throw new Error(`Workflow approval node '${node.id}' args must be an object`);
57
+ return {
58
+ ...update,
59
+ pendingApproval: {
60
+ ...existing ?? {},
61
+ toolName: existing?.toolName ?? node.approval.toolName,
62
+ approvalLevel: existing?.approvalLevel ?? node.approval.approvalLevel,
63
+ riskLevel: existing?.riskLevel ?? node.approval.riskLevel,
64
+ reason: existing?.reason ?? node.approval.reason,
65
+ args: structuredClone(args),
66
+ ...node.approval.permission === void 0 ? {} : { permission: existing?.permission ?? node.approval.permission },
67
+ ...node.approval.contractVersion === void 0 ? {} : { contractVersion: existing?.contractVersion ?? node.approval.contractVersion }
68
+ }
69
+ };
70
+ };
71
+ }
72
+ function retryPolicy(node) {
73
+ if (!node.retry) return void 0;
74
+ return { maxAttempts: node.retry.maxAttempts, initialInterval: node.retry.backoffMs, maxInterval: node.retry.maxBackoffMs, jitter: node.retry.jitter };
75
+ }
76
+ function visualNode(node, descriptor) {
77
+ return {
78
+ kind: node.kind ?? descriptor.kind ?? "task",
79
+ label: node.label ?? descriptor.label,
80
+ ...node.description ?? descriptor.description ? { description: node.description ?? descriptor.description } : {},
81
+ ...node.pluginId ?? descriptor.pluginId ? { pluginId: node.pluginId ?? descriptor.pluginId } : {},
82
+ ...node.approval ? { approvalLevel: node.approval.approvalLevel, riskLevel: node.approval.riskLevel, toolName: node.approval.toolName, canRequestApproval: true } : { canRequestApproval: descriptor.canRequestApproval ?? true },
83
+ ...node.retry ? { retryable: node.retry.maxAttempts > 1 } : {},
84
+ ...node.subflow ? { subgraphId: node.subflow.workflowId, subgraphVersion: node.subflow.version } : {}
85
+ };
86
+ }
87
+ function edgeVisual(edge) {
88
+ return {
89
+ kind: edge.condition ? "conditional" : edge.default ? "system" : "normal",
90
+ ...edge.label === void 0 ? {} : { label: edge.label },
91
+ ...edge.condition === void 0 ? {} : { condition: conditionLabel(edge.condition) }
92
+ };
93
+ }
94
+ function conditionLabel(condition) {
95
+ if ("all" in condition) return condition.all.map(conditionLabel).join(" AND ");
96
+ if ("any" in condition) return condition.any.map(conditionLabel).join(" OR ");
97
+ if ("not" in condition) return `NOT (${conditionLabel(condition.not)})`;
98
+ return `${condition.path} ${condition.operator}${"value" in condition ? ` ${JSON.stringify(condition.value)}` : ""}`;
99
+ }
100
+ function routeDefinitionEdges(edges, state) {
101
+ const fallback = edges.find((edge) => edge.default === true || edge.condition === void 0);
102
+ const match = edges.find((edge) => edge.condition !== void 0 && evaluateWorkflowCondition(edge.condition, state));
103
+ return (match ?? fallback)?.to ?? (() => {
104
+ throw new Error(`No workflow edge condition matched from '${state.currentStep}'`);
105
+ })();
106
+ }
107
+ function valueAtPath(input, path) {
108
+ let current = input;
109
+ for (const part of path.split(".")) {
110
+ if (!isRecord(current) || !Object.prototype.hasOwnProperty.call(current, part)) return { exists: false, value: void 0 };
111
+ current = current[part];
112
+ }
113
+ return { exists: true, value: current };
114
+ }
115
+ function isRecord(value) {
116
+ return typeof value === "object" && value !== null && !Array.isArray(value);
117
+ }
118
+ async function withTimeout(promise, timeoutMs, nodeId) {
119
+ if (timeoutMs === void 0) return promise;
120
+ let timer;
121
+ const timeout = new Promise((_, reject) => {
122
+ timer = setTimeout(() => reject(new Error(`Workflow node '${nodeId}' timed out after ${timeoutMs}ms`)), timeoutMs);
123
+ });
124
+ try {
125
+ return await Promise.race([promise, timeout]);
126
+ } finally {
127
+ if (timer !== void 0) clearTimeout(timer);
128
+ }
129
+ }
130
+
131
+ export {
132
+ compileWorkflowDefinition
133
+ };
134
+ //# sourceMappingURL=chunk-CJ7OFEF7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/agentic/workflow-compiler.ts"],"sourcesContent":["import type { WorkflowCondition, WorkflowDefinition, WorkflowDefinitionEdge, WorkflowDefinitionNode, WorkflowGraphNodeInput } from '@alneas/eaos-core'\nimport { evaluateWorkflowCondition, validateWorkflowDefinition } from '@alneas/eaos-core'\nimport type { BaseCheckpointSaver, RetryPolicy } from '@langchain/langgraph'\nimport { AgentGraphEngine, type AgentGraphEngineOptions, type AgentGraphState, type GraphNodeHandler } from './graph'\nimport { WorkflowNodeCatalog } from './workflow-catalog'\n\n/**\n * Trusted node catalog, checkpoint persistence, and live approval authority for {@link compileWorkflowDefinition}.\n */\nexport interface WorkflowCompilerOptions {\n /** Required host/plugin node resolver catalog. */\n catalog: WorkflowNodeCatalog\n /** Optional LangGraph saver; absent uses the graph engine default, which is not durable host storage. */\n checkpointer?: BaseCheckpointSaver\n /** Optional live host approval authorization forwarded to the graph engine. */\n authorizeResume?: AgentGraphEngineOptions['authorizeResume']\n}\n\n/**\n * Validated definition and configured graph produced by {@link compileWorkflowDefinition}.\n */\nexport interface CompiledWorkflow {\n /** Validated serializable workflow definition returned by core validation. */\n definition: WorkflowDefinition\n /** Newly assembled graph; compilation performs no workflow execution. */\n graph: AgentGraphEngine\n}\n\n/**\n * Validates a serializable workflow and resolves its catalog nodes into a LangGraph-backed runtime.\n * @param input - Unknown serialized definition accepted by core validateWorkflowDefinition.\n * @param options - Required catalog, optional saver, and live resume authorizer.\n * @returns Validated definition and newly configured graph with node retries, conditional routes, approval metadata, and subgraph mappings.\n * @throws Rejects definition validation, missing catalog/types/subgraph resolvers, invalid resolved handlers/graphs, or propagated resolver/graph construction errors.\n * @remarks Host resolvers may have setup side effects before a later node fails; no rollback/disposal protocol is provided. Node timeouts race the handler but do not cancel underlying work. Tool scopes are passed in workflow context; handlers must enforce them. Runtime conditional routing picks the first matching condition or first default/unconditional edge and throws if none match. Durable persistence, live authorization, and safe side-effect retry contracts remain host-owned.\n * @example\n * ```typescript\n * import { compileWorkflowDefinition, type WorkflowCompilerOptions } from \"@alneas/eaos-server/agentic/workflow-compiler\";\n * export async function compile(input: unknown, options: WorkflowCompilerOptions) {\n * return compileWorkflowDefinition(input, options);\n * }\n * ```\n */\nexport async function compileWorkflowDefinition(input: unknown, options: WorkflowCompilerOptions): Promise<CompiledWorkflow> {\n const definition = validateWorkflowDefinition(input)\n if (!options?.catalog) throw new Error('Workflow node catalog is required')\n const graph = new AgentGraphEngine({\n checkpointer: options.checkpointer,\n authorizeResume: options.authorizeResume,\n workflowId: definition.workflowId,\n workflowVersion: definition.version,\n })\n\n for (const node of definition.nodes) {\n const registration = options.catalog.require(node.type)\n const visual = visualNode(node, registration.descriptor)\n if (node.subflow) {\n if (!registration.resolveSubgraph) throw new Error(`Workflow node '${node.id}' declares a subflow but '${node.type}' has no subgraph resolver`)\n const subgraph = await registration.resolveSubgraph({ definition, node })\n if (!subgraph || typeof subgraph.invoke !== 'function') throw new Error(`Workflow subflow '${node.id}' did not resolve to a compiled graph`)\n graph.addSubgraph(node.id, subgraph, {\n visual,\n mapInput: state => node.subflow?.inputPath ? valueAtPath(state, node.subflow.inputPath).value : state,\n mapOutput: (output, state) => ({ context: { ...(state.context ?? {}), [node.subflow?.outputKey ?? `${node.id}.output`]: structuredClone(output) } }),\n })\n continue\n }\n const handler = await registration.resolve({ definition, node })\n if (typeof handler !== 'function') throw new Error(`Workflow node '${node.id}' did not resolve to a handler`)\n graph.addNode(node.id, wrapNode(node, handler), { retryPolicy: retryPolicy(node), visual })\n }\n\n graph.setEntryPoint(definition.entryNode)\n for (const node of definition.nodes) {\n const outgoing = definition.edges.filter(edge => edge.from === node.id)\n if (!outgoing.length) continue\n for (const edge of outgoing) graph.addEdge(edge.from, edge.to, { visual: edgeVisual(edge) })\n if (outgoing.some(edge => edge.condition !== undefined)) {\n const destinations = [...new Set(outgoing.map(edge => edge.to))]\n graph.addConditionalEdges(node.id, state => routeDefinitionEdges(outgoing, state), destinations, {\n labels: Object.fromEntries(outgoing.map(edge => [edge.to, edge.label ?? (edge.condition ? '条件分岐' : '既定')])),\n visual: { kind: 'conditional' },\n })\n }\n }\n return { definition, graph }\n}\n\nfunction wrapNode(node: WorkflowDefinitionNode, handler: GraphNodeHandler): GraphNodeHandler {\n return async state => {\n const handlerState = node.toolScope\n ? { ...structuredClone(state), context: { ...(state.context ?? {}), __eaosWorkflowToolScope: structuredClone(node.toolScope) } }\n : structuredClone(state)\n const update = await withTimeout(handler(handlerState), node.timeoutMs, node.id)\n if (!node.approval) return update\n const existing = update.pendingApproval\n const args = existing?.args ?? (node.approval.argsPath ? valueAtPath({ ...state, ...update }, node.approval.argsPath).value : {})\n if (!isRecord(args)) throw new Error(`Workflow approval node '${node.id}' args must be an object`)\n return {\n ...update,\n pendingApproval: {\n ...(existing ?? {}),\n toolName: existing?.toolName ?? node.approval.toolName,\n approvalLevel: existing?.approvalLevel ?? node.approval.approvalLevel,\n riskLevel: existing?.riskLevel ?? node.approval.riskLevel,\n reason: existing?.reason ?? node.approval.reason,\n args: structuredClone(args),\n ...(node.approval.permission === undefined ? {} : { permission: existing?.permission ?? node.approval.permission }),\n ...(node.approval.contractVersion === undefined ? {} : { contractVersion: existing?.contractVersion ?? node.approval.contractVersion }),\n },\n }\n }\n}\n\nfunction retryPolicy(node: WorkflowDefinitionNode): RetryPolicy | undefined {\n if (!node.retry) return undefined\n return { maxAttempts: node.retry.maxAttempts, initialInterval: node.retry.backoffMs, maxInterval: node.retry.maxBackoffMs, jitter: node.retry.jitter }\n}\n\nfunction visualNode(node: WorkflowDefinitionNode, descriptor: { label: string; description?: string; pluginId?: string; kind: WorkflowDefinitionNode['kind']; canRequestApproval?: boolean }): WorkflowGraphNodeInput {\n return {\n kind: node.kind ?? descriptor.kind ?? 'task',\n label: node.label ?? descriptor.label,\n ...(node.description ?? descriptor.description ? { description: node.description ?? descriptor.description } : {}),\n ...(node.pluginId ?? descriptor.pluginId ? { pluginId: node.pluginId ?? descriptor.pluginId } : {}),\n ...(node.approval ? { approvalLevel: node.approval.approvalLevel, riskLevel: node.approval.riskLevel, toolName: node.approval.toolName, canRequestApproval: true } : { canRequestApproval: descriptor.canRequestApproval ?? true }),\n ...(node.retry ? { retryable: node.retry.maxAttempts > 1 } : {}),\n ...(node.subflow ? { subgraphId: node.subflow.workflowId, subgraphVersion: node.subflow.version } : {}),\n }\n}\n\nfunction edgeVisual(edge: WorkflowDefinitionEdge) {\n return {\n kind: edge.condition ? 'conditional' as const : edge.default ? 'system' as const : 'normal' as const,\n ...(edge.label === undefined ? {} : { label: edge.label }),\n ...(edge.condition === undefined ? {} : { condition: conditionLabel(edge.condition) }),\n }\n}\n\nfunction conditionLabel(condition: WorkflowCondition): string {\n if ('all' in condition) return condition.all.map(conditionLabel).join(' AND ')\n if ('any' in condition) return condition.any.map(conditionLabel).join(' OR ')\n if ('not' in condition) return `NOT (${conditionLabel(condition.not)})`\n return `${condition.path} ${condition.operator}${'value' in condition ? ` ${JSON.stringify(condition.value)}` : ''}`\n}\n\nfunction routeDefinitionEdges(edges: readonly WorkflowDefinitionEdge[], state: AgentGraphState): string {\n const fallback = edges.find(edge => edge.default === true || edge.condition === undefined)\n const match = edges.find(edge => edge.condition !== undefined && evaluateWorkflowCondition(edge.condition, state))\n return (match ?? fallback)?.to ?? (() => { throw new Error(`No workflow edge condition matched from '${state.currentStep}'`) })()\n}\n\nfunction valueAtPath(input: unknown, path: string): { exists: boolean; value: unknown } {\n let current: unknown = input\n for (const part of path.split('.')) {\n if (!isRecord(current) || !Object.prototype.hasOwnProperty.call(current, part)) return { exists: false, value: undefined }\n current = current[part]\n }\n return { exists: true, value: current }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nasync function withTimeout<T>(promise: Promise<T>, timeoutMs: number | undefined, nodeId: string): Promise<T> {\n if (timeoutMs === undefined) return promise\n let timer: ReturnType<typeof setTimeout> | undefined\n const timeout = new Promise<never>((_, reject) => { timer = setTimeout(() => reject(new Error(`Workflow node '${nodeId}' timed out after ${timeoutMs}ms`)), timeoutMs) })\n try { return await Promise.race([promise, timeout]) } finally { if (timer !== undefined) clearTimeout(timer) }\n}\n"],"mappings":";;;;;AACA,SAAS,2BAA2B,kCAAkC;AA0CtE,eAAsB,0BAA0B,OAAgB,SAA6D;AAC3H,QAAM,aAAa,2BAA2B,KAAK;AACnD,MAAI,CAAC,SAAS,QAAS,OAAM,IAAI,MAAM,mCAAmC;AAC1E,QAAM,QAAQ,IAAI,iBAAiB;AAAA,IACjC,cAAc,QAAQ;AAAA,IACtB,iBAAiB,QAAQ;AAAA,IACzB,YAAY,WAAW;AAAA,IACvB,iBAAiB,WAAW;AAAA,EAC9B,CAAC;AAED,aAAW,QAAQ,WAAW,OAAO;AACnC,UAAM,eAAe,QAAQ,QAAQ,QAAQ,KAAK,IAAI;AACtD,UAAM,SAAS,WAAW,MAAM,aAAa,UAAU;AACvD,QAAI,KAAK,SAAS;AAChB,UAAI,CAAC,aAAa,gBAAiB,OAAM,IAAI,MAAM,kBAAkB,KAAK,EAAE,6BAA6B,KAAK,IAAI,4BAA4B;AAC9I,YAAM,WAAW,MAAM,aAAa,gBAAgB,EAAE,YAAY,KAAK,CAAC;AACxE,UAAI,CAAC,YAAY,OAAO,SAAS,WAAW,WAAY,OAAM,IAAI,MAAM,qBAAqB,KAAK,EAAE,uCAAuC;AAC3I,YAAM,YAAY,KAAK,IAAI,UAAU;AAAA,QACnC;AAAA,QACA,UAAU,WAAS,KAAK,SAAS,YAAY,YAAY,OAAO,KAAK,QAAQ,SAAS,EAAE,QAAQ;AAAA,QAChG,WAAW,CAAC,QAAQ,WAAW,EAAE,SAAS,EAAE,GAAI,MAAM,WAAW,CAAC,GAAI,CAAC,KAAK,SAAS,aAAa,GAAG,KAAK,EAAE,SAAS,GAAG,gBAAgB,MAAM,EAAE,EAAE;AAAA,MACpJ,CAAC;AACD;AAAA,IACF;AACA,UAAM,UAAU,MAAM,aAAa,QAAQ,EAAE,YAAY,KAAK,CAAC;AAC/D,QAAI,OAAO,YAAY,WAAY,OAAM,IAAI,MAAM,kBAAkB,KAAK,EAAE,gCAAgC;AAC5G,UAAM,QAAQ,KAAK,IAAI,SAAS,MAAM,OAAO,GAAG,EAAE,aAAa,YAAY,IAAI,GAAG,OAAO,CAAC;AAAA,EAC5F;AAEA,QAAM,cAAc,WAAW,SAAS;AACxC,aAAW,QAAQ,WAAW,OAAO;AACnC,UAAM,WAAW,WAAW,MAAM,OAAO,UAAQ,KAAK,SAAS,KAAK,EAAE;AACtE,QAAI,CAAC,SAAS,OAAQ;AACtB,eAAW,QAAQ,SAAU,OAAM,QAAQ,KAAK,MAAM,KAAK,IAAI,EAAE,QAAQ,WAAW,IAAI,EAAE,CAAC;AAC3F,QAAI,SAAS,KAAK,UAAQ,KAAK,cAAc,MAAS,GAAG;AACvD,YAAM,eAAe,CAAC,GAAG,IAAI,IAAI,SAAS,IAAI,UAAQ,KAAK,EAAE,CAAC,CAAC;AAC/D,YAAM,oBAAoB,KAAK,IAAI,WAAS,qBAAqB,UAAU,KAAK,GAAG,cAAc;AAAA,QAC/F,QAAQ,OAAO,YAAY,SAAS,IAAI,UAAQ,CAAC,KAAK,IAAI,KAAK,UAAU,KAAK,YAAY,6BAAS,eAAK,CAAC,CAAC;AAAA,QAC1G,QAAQ,EAAE,MAAM,cAAc;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,EAAE,YAAY,MAAM;AAC7B;AAEA,SAAS,SAAS,MAA8B,SAA6C;AAC3F,SAAO,OAAM,UAAS;AACpB,UAAM,eAAe,KAAK,YACtB,EAAE,GAAG,gBAAgB,KAAK,GAAG,SAAS,EAAE,GAAI,MAAM,WAAW,CAAC,GAAI,yBAAyB,gBAAgB,KAAK,SAAS,EAAE,EAAE,IAC7H,gBAAgB,KAAK;AACzB,UAAM,SAAS,MAAM,YAAY,QAAQ,YAAY,GAAG,KAAK,WAAW,KAAK,EAAE;AAC/E,QAAI,CAAC,KAAK,SAAU,QAAO;AAC3B,UAAM,WAAW,OAAO;AACxB,UAAM,OAAO,UAAU,SAAS,KAAK,SAAS,WAAW,YAAY,EAAE,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,SAAS,QAAQ,EAAE,QAAQ,CAAC;AAC/H,QAAI,CAAC,SAAS,IAAI,EAAG,OAAM,IAAI,MAAM,2BAA2B,KAAK,EAAE,0BAA0B;AACjG,WAAO;AAAA,MACL,GAAG;AAAA,MACH,iBAAiB;AAAA,QACf,GAAI,YAAY,CAAC;AAAA,QACjB,UAAU,UAAU,YAAY,KAAK,SAAS;AAAA,QAC9C,eAAe,UAAU,iBAAiB,KAAK,SAAS;AAAA,QACxD,WAAW,UAAU,aAAa,KAAK,SAAS;AAAA,QAChD,QAAQ,UAAU,UAAU,KAAK,SAAS;AAAA,QAC1C,MAAM,gBAAgB,IAAI;AAAA,QAC1B,GAAI,KAAK,SAAS,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,UAAU,cAAc,KAAK,SAAS,WAAW;AAAA,QACjH,GAAI,KAAK,SAAS,oBAAoB,SAAY,CAAC,IAAI,EAAE,iBAAiB,UAAU,mBAAmB,KAAK,SAAS,gBAAgB;AAAA,MACvI;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,YAAY,MAAuD;AAC1E,MAAI,CAAC,KAAK,MAAO,QAAO;AACxB,SAAO,EAAE,aAAa,KAAK,MAAM,aAAa,iBAAiB,KAAK,MAAM,WAAW,aAAa,KAAK,MAAM,cAAc,QAAQ,KAAK,MAAM,OAAO;AACvJ;AAEA,SAAS,WAAW,MAA8B,YAAoK;AACpN,SAAO;AAAA,IACL,MAAM,KAAK,QAAQ,WAAW,QAAQ;AAAA,IACtC,OAAO,KAAK,SAAS,WAAW;AAAA,IAChC,GAAI,KAAK,eAAe,WAAW,cAAc,EAAE,aAAa,KAAK,eAAe,WAAW,YAAY,IAAI,CAAC;AAAA,IAChH,GAAI,KAAK,YAAY,WAAW,WAAW,EAAE,UAAU,KAAK,YAAY,WAAW,SAAS,IAAI,CAAC;AAAA,IACjG,GAAI,KAAK,WAAW,EAAE,eAAe,KAAK,SAAS,eAAe,WAAW,KAAK,SAAS,WAAW,UAAU,KAAK,SAAS,UAAU,oBAAoB,KAAK,IAAI,EAAE,oBAAoB,WAAW,sBAAsB,KAAK;AAAA,IACjO,GAAI,KAAK,QAAQ,EAAE,WAAW,KAAK,MAAM,cAAc,EAAE,IAAI,CAAC;AAAA,IAC9D,GAAI,KAAK,UAAU,EAAE,YAAY,KAAK,QAAQ,YAAY,iBAAiB,KAAK,QAAQ,QAAQ,IAAI,CAAC;AAAA,EACvG;AACF;AAEA,SAAS,WAAW,MAA8B;AAChD,SAAO;AAAA,IACL,MAAM,KAAK,YAAY,gBAAyB,KAAK,UAAU,WAAoB;AAAA,IACnF,GAAI,KAAK,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;AAAA,IACxD,GAAI,KAAK,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,eAAe,KAAK,SAAS,EAAE;AAAA,EACtF;AACF;AAEA,SAAS,eAAe,WAAsC;AAC5D,MAAI,SAAS,UAAW,QAAO,UAAU,IAAI,IAAI,cAAc,EAAE,KAAK,OAAO;AAC7E,MAAI,SAAS,UAAW,QAAO,UAAU,IAAI,IAAI,cAAc,EAAE,KAAK,MAAM;AAC5E,MAAI,SAAS,UAAW,QAAO,QAAQ,eAAe,UAAU,GAAG,CAAC;AACpE,SAAO,GAAG,UAAU,IAAI,IAAI,UAAU,QAAQ,GAAG,WAAW,YAAY,IAAI,KAAK,UAAU,UAAU,KAAK,CAAC,KAAK,EAAE;AACpH;AAEA,SAAS,qBAAqB,OAA0C,OAAgC;AACtG,QAAM,WAAW,MAAM,KAAK,UAAQ,KAAK,YAAY,QAAQ,KAAK,cAAc,MAAS;AACzF,QAAM,QAAQ,MAAM,KAAK,UAAQ,KAAK,cAAc,UAAa,0BAA0B,KAAK,WAAW,KAAK,CAAC;AACjH,UAAQ,SAAS,WAAW,OAAO,MAAM;AAAE,UAAM,IAAI,MAAM,4CAA4C,MAAM,WAAW,GAAG;AAAA,EAAE,GAAG;AAClI;AAEA,SAAS,YAAY,OAAgB,MAAmD;AACtF,MAAI,UAAmB;AACvB,aAAW,QAAQ,KAAK,MAAM,GAAG,GAAG;AAClC,QAAI,CAAC,SAAS,OAAO,KAAK,CAAC,OAAO,UAAU,eAAe,KAAK,SAAS,IAAI,EAAG,QAAO,EAAE,QAAQ,OAAO,OAAO,OAAU;AACzH,cAAU,QAAQ,IAAI;AAAA,EACxB;AACA,SAAO,EAAE,QAAQ,MAAM,OAAO,QAAQ;AACxC;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,eAAe,YAAe,SAAqB,WAA+B,QAA4B;AAC5G,MAAI,cAAc,OAAW,QAAO;AACpC,MAAI;AACJ,QAAM,UAAU,IAAI,QAAe,CAAC,GAAG,WAAW;AAAE,YAAQ,WAAW,MAAM,OAAO,IAAI,MAAM,kBAAkB,MAAM,qBAAqB,SAAS,IAAI,CAAC,GAAG,SAAS;AAAA,EAAE,CAAC;AACxK,MAAI;AAAE,WAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,OAAO,CAAC;AAAA,EAAE,UAAE;AAAU,QAAI,UAAU,OAAW,cAAa,KAAK;AAAA,EAAE;AAC/G;","names":[]}
@@ -0,0 +1,111 @@
1
+ import {
2
+ ServerWorkflowManager
3
+ } from "./chunk-FD6VC2NA.js";
4
+
5
+ // src/agentic/workflow-coordinator.ts
6
+ var DurableWorkflowCoordinator = class extends ServerWorkflowManager {
7
+ store;
8
+ /**
9
+ * Captures workflow callbacks and required durable instance store.
10
+ * @param options - Host store, approval notification, and live resume authorization.
11
+ * @throws If store is missing.
12
+ */
13
+ constructor(options) {
14
+ super(options);
15
+ if (!options?.store) throw new Error("Workflow instance store is required");
16
+ this.store = options.store;
17
+ }
18
+ /**
19
+ * Creates a queued companion instance then runs and persists its graph outcome.
20
+ * @param graph - Configured graph with appropriate checkpoint persistence.
21
+ * @param record - Host-admitted instance metadata; instanceId and tenantId must match initialState.
22
+ * @param initialState - Verified workflow identity and starting state.
23
+ * @returns Graph state after execution and companion CAS persistence.
24
+ * @throws Rejects alignment mismatch, existing instance, graph/callback/clone/store failures, or companion revision conflict.
25
+ * @remarks The queued record can exist even if graph execution later fails; no cross-store rollback occurs. Atomic duplicate prevention belongs to store.create.
26
+ * @example
27
+ * ```typescript
28
+ * import { DurableWorkflowCoordinator } from "@alneas/eaos-server/agentic/workflow-coordinator";
29
+ * import type { AgentGraphEngine, AgentGraphState } from "@alneas/eaos-server/agentic/graph";
30
+ * import type { WorkflowInstanceRecord } from "@alneas/eaos-core";
31
+ * export async function start(coordinator: DurableWorkflowCoordinator, graph: AgentGraphEngine, record: WorkflowInstanceRecord, state: AgentGraphState) { return coordinator.start(graph, record, state); }
32
+ * ```
33
+ */
34
+ async start(graph, record, initialState) {
35
+ if (record.instanceId !== initialState.sessionId || record.tenantId !== initialState.tenantId) throw new Error("Workflow instance and graph state are not aligned");
36
+ const existing = await this.store.read(record.tenantId, record.instanceId);
37
+ if (existing) throw new Error("Workflow instance already exists");
38
+ await this.store.create(record.tenantId, { id: record.instanceId, revision: 1, value: { ...structuredClone(record), status: "queued" } });
39
+ return this.runAndPersist(graph, initialState);
40
+ }
41
+ /**
42
+ * Runs an existing graph instance and CAS-updates its companion status.
43
+ * @param graph - Graph whose session already has a companion record.
44
+ * @param initialState - Verified state aligned with that record.
45
+ * @returns Graph result after companion persistence; status prioritizes pending approval, error, completion, then running.
46
+ * @throws Graph/store/clock failures, missing companion, or changed revision; graph checkpoints may already have advanced.
47
+ * @example
48
+ * ```typescript
49
+ * import { DurableWorkflowCoordinator } from "@alneas/eaos-server/agentic/workflow-coordinator";
50
+ * import type { AgentGraphEngine, AgentGraphState } from "@alneas/eaos-server/agentic/graph";
51
+ * export async function run(coordinator: DurableWorkflowCoordinator, graph: AgentGraphEngine, state: AgentGraphState) { return coordinator.runWorkflow(graph, state); }
52
+ * ```
53
+ */
54
+ async runWorkflow(graph, initialState) {
55
+ return this.runAndPersist(graph, initialState);
56
+ }
57
+ /**
58
+ * Resumes a verified graph approval then persists its resulting companion state.
59
+ * @param graph - Graph owning the pending checkpoint.
60
+ * @param payload - Host-authenticated approver decision and optional binding checks.
61
+ * @returns Resume outcome; companion persistence failure becomes resumed:false error data even when graph resume already succeeded.
62
+ * @throws Underlying graph/store failures outside normalized resume/persistence handling may reject.
63
+ * @remarks A false result does not prove no side effects occurred; reconcile graph and companion state before retrying.
64
+ * @example
65
+ * ```typescript
66
+ * import { DurableWorkflowCoordinator } from "@alneas/eaos-server/agentic/workflow-coordinator";
67
+ * import type { AgentGraphEngine } from "@alneas/eaos-server/agentic/graph";
68
+ * import type { ServerApprovalCallbackPayload } from "@alneas/eaos-server/agentic/types";
69
+ * export async function approve(coordinator: DurableWorkflowCoordinator, graph: AgentGraphEngine, payload: ServerApprovalCallbackPayload) { return coordinator.handleApproval(graph, payload); }
70
+ * ```
71
+ */
72
+ async handleApproval(graph, payload) {
73
+ const result = await super.handleApproval(graph, payload);
74
+ if (result.resumed && result.state) {
75
+ try {
76
+ await this.persist(result.state);
77
+ } catch (error) {
78
+ return { resumed: false, error: error instanceof Error ? error.message : "Workflow instance persistence failed" };
79
+ }
80
+ }
81
+ return result;
82
+ }
83
+ async runAndPersist(graph, state) {
84
+ const result = await super.runWorkflow(graph, state);
85
+ await this.persist(result);
86
+ return result;
87
+ }
88
+ async persist(state) {
89
+ const current = await this.store.read(state.tenantId, state.sessionId);
90
+ if (!current) throw new Error(`Workflow instance '${state.sessionId}' not found`);
91
+ const value = {
92
+ ...current.value,
93
+ status: statusForState(state),
94
+ checkpointRevision: state.checkpointRevision,
95
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
96
+ ...state.error ? { error: state.error } : { error: void 0 }
97
+ };
98
+ if (!await this.store.replace(state.tenantId, { ...current, revision: current.revision + 1, value }, current.revision)) throw new Error("Workflow instance revision changed");
99
+ }
100
+ };
101
+ function statusForState(state) {
102
+ if (state.pendingApproval) return "waiting_approval";
103
+ if (state.error) return "failed";
104
+ if (state.isComplete) return "completed";
105
+ return "running";
106
+ }
107
+
108
+ export {
109
+ DurableWorkflowCoordinator
110
+ };
111
+ //# sourceMappingURL=chunk-EJKWDZIU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/agentic/workflow-coordinator.ts"],"sourcesContent":["import type { WorkflowInstanceRecord, WorkflowInstanceStatus } from '@alneas/eaos-core'\nimport type { AgentGraphState, AgentGraphEngine } from './graph'\nimport { ServerWorkflowManager, type ServerWorkflowOptions } from './workflow-manager'\nimport type { ServerApprovalCallbackPayload } from './types'\n\n/**\n * Durable business-instance record with host compare-and-swap revision.\n * @see DurableWorkflowCoordinator.\n */\nexport interface StoredWorkflowInstance {\n /** Workflow instance ID, aligned with graph sessionId. */\n id: string\n /** Host CAS revision, starting at one for coordinator-created records. */\n revision: number\n /** Domain workflow instance metadata; graph payload remains in its checkpointer. */\n value: WorkflowInstanceRecord\n}\n\n/** Host-owned durable store for the companion workflow instance record.\n * @see DurableWorkflowCoordinator for usage.\n */\nexport interface WorkflowInstanceStore {\n /**\n * Reads an authorized tenant's companion instance.\n * @param tenantId - Verified owning tenant.\n * @param instanceId - Workflow session/instance ID.\n * @returns Stored record, or null if absent.\n * @throws Persistence failures propagate.\n \n * @example\n * ```typescript\n * import type { WorkflowInstanceStore } from \"@alneas/eaos-server\";\n * export async function readTenantInstance(\n * store: WorkflowInstanceStore, verifiedTenantId: string, instanceId: string,\n * ) {\n * const record = await store.read(verifiedTenantId, instanceId);\n * return record?.value.status; // A missing instance yields undefined here.\n * }\n * ```\n */\n read(tenantId: string, instanceId: string): Promise<StoredWorkflowInstance | null>\n /**\n * Atomically inserts a new companion instance, rejecting duplicates.\n * @param tenantId - Verified owning tenant.\n * @param record - Initial revision-one queued record.\n * @returns No value; resolves when durable creation completes.\n * @throws Duplicate/conflicting identity or persistence failure must reject.\n \n * @example\n * ```typescript\n * import type { WorkflowInstanceStore } from \"@alneas/eaos-server\";\n * export async function createQueuedInstance(\n * store: WorkflowInstanceStore, verifiedTenantId: string,\n * initialRecord: Parameters<WorkflowInstanceStore[\"create\"]>[1],\n * ) {\n * // Supply an aligned, admitted revision-one queued record.\n * await store.create(verifiedTenantId, initialRecord);\n * }\n * ```\n */\n create(tenantId: string, record: StoredWorkflowInstance): Promise<void>\n /**\n * Atomically replaces a companion record only if its revision matches.\n * @param tenantId - Verified owning tenant.\n * @param record - Replacement with incremented revision.\n * @param expectedRevision - Previously read revision required for CAS.\n * @returns True on replacement, false on stale revision.\n * @throws Persistence failures propagate.\n \n * @example\n * ```typescript\n * import type { WorkflowInstanceStore } from \"@alneas/eaos-server\";\n * export async function replaceTenantInstance(\n * store: WorkflowInstanceStore, verifiedTenantId: string,\n * nextRecord: Parameters<WorkflowInstanceStore[\"replace\"]>[1], previouslyReadRevision: number,\n * ) {\n * // nextRecord has the incremented revision; false means another writer won.\n * return await store.replace(verifiedTenantId, nextRecord, previouslyReadRevision);\n * }\n * ```\n */\n replace(tenantId: string, record: StoredWorkflowInstance, expectedRevision: number): Promise<boolean>\n}\n\n/**\n * Workflow notification/approval callbacks plus durable companion-instance storage.\n * @see DurableWorkflowCoordinator.\n */\nexport interface DurableWorkflowCoordinatorOptions extends ServerWorkflowOptions {\n /** Host-authorized tenant-scoped store with atomic create and revision checks. */\n store: WorkflowInstanceStore\n}\n\n/**\n * Keeps the business workflow instance synchronized with the LangGraph\n * checkpoint without making either one the other's database implementation.\n * @remarks Checkpoint and companion record updates are separate operations; failures can leave them temporarily divergent. The host owns writer serialization, tenant authorization, durable stores, and reconciliation rather than blind retry after partial outcomes.\n * @example\n * ```typescript\n * import { DurableWorkflowCoordinator } from \"@alneas/eaos-server/agentic/workflow-coordinator\";\n * import type { DurableWorkflowCoordinatorOptions } from \"@alneas/eaos-server/agentic/workflow-coordinator\";\n * export function coordinator(options: DurableWorkflowCoordinatorOptions) { return new DurableWorkflowCoordinator(options); }\n * ```\n */\nexport class DurableWorkflowCoordinator extends ServerWorkflowManager {\n private readonly store: WorkflowInstanceStore\n\n /**\n * Captures workflow callbacks and required durable instance store.\n * @param options - Host store, approval notification, and live resume authorization.\n * @throws If store is missing.\n */\n constructor(options: DurableWorkflowCoordinatorOptions) {\n super(options)\n if (!options?.store) throw new Error('Workflow instance store is required')\n this.store = options.store\n }\n\n /**\n * Creates a queued companion instance then runs and persists its graph outcome.\n * @param graph - Configured graph with appropriate checkpoint persistence.\n * @param record - Host-admitted instance metadata; instanceId and tenantId must match initialState.\n * @param initialState - Verified workflow identity and starting state.\n * @returns Graph state after execution and companion CAS persistence.\n * @throws Rejects alignment mismatch, existing instance, graph/callback/clone/store failures, or companion revision conflict.\n * @remarks The queued record can exist even if graph execution later fails; no cross-store rollback occurs. Atomic duplicate prevention belongs to store.create.\n * @example\n * ```typescript\n * import { DurableWorkflowCoordinator } from \"@alneas/eaos-server/agentic/workflow-coordinator\";\n * import type { AgentGraphEngine, AgentGraphState } from \"@alneas/eaos-server/agentic/graph\";\n * import type { WorkflowInstanceRecord } from \"@alneas/eaos-core\";\n * export async function start(coordinator: DurableWorkflowCoordinator, graph: AgentGraphEngine, record: WorkflowInstanceRecord, state: AgentGraphState) { return coordinator.start(graph, record, state); }\n * ```\n */\n async start(graph: AgentGraphEngine, record: WorkflowInstanceRecord, initialState: AgentGraphState): Promise<AgentGraphState> {\n if (record.instanceId !== initialState.sessionId || record.tenantId !== initialState.tenantId) throw new Error('Workflow instance and graph state are not aligned')\n const existing = await this.store.read(record.tenantId, record.instanceId)\n if (existing) throw new Error('Workflow instance already exists')\n await this.store.create(record.tenantId, { id: record.instanceId, revision: 1, value: { ...structuredClone(record), status: 'queued' } })\n return this.runAndPersist(graph, initialState)\n }\n\n /**\n * Runs an existing graph instance and CAS-updates its companion status.\n * @param graph - Graph whose session already has a companion record.\n * @param initialState - Verified state aligned with that record.\n * @returns Graph result after companion persistence; status prioritizes pending approval, error, completion, then running.\n * @throws Graph/store/clock failures, missing companion, or changed revision; graph checkpoints may already have advanced.\n * @example\n * ```typescript\n * import { DurableWorkflowCoordinator } from \"@alneas/eaos-server/agentic/workflow-coordinator\";\n * import type { AgentGraphEngine, AgentGraphState } from \"@alneas/eaos-server/agentic/graph\";\n * export async function run(coordinator: DurableWorkflowCoordinator, graph: AgentGraphEngine, state: AgentGraphState) { return coordinator.runWorkflow(graph, state); }\n * ```\n */\n override async runWorkflow(graph: AgentGraphEngine, initialState: AgentGraphState): Promise<AgentGraphState> {\n return this.runAndPersist(graph, initialState)\n }\n\n /**\n * Resumes a verified graph approval then persists its resulting companion state.\n * @param graph - Graph owning the pending checkpoint.\n * @param payload - Host-authenticated approver decision and optional binding checks.\n * @returns Resume outcome; companion persistence failure becomes resumed:false error data even when graph resume already succeeded.\n * @throws Underlying graph/store failures outside normalized resume/persistence handling may reject.\n * @remarks A false result does not prove no side effects occurred; reconcile graph and companion state before retrying.\n * @example\n * ```typescript\n * import { DurableWorkflowCoordinator } from \"@alneas/eaos-server/agentic/workflow-coordinator\";\n * import type { AgentGraphEngine } from \"@alneas/eaos-server/agentic/graph\";\n * import type { ServerApprovalCallbackPayload } from \"@alneas/eaos-server/agentic/types\";\n * export async function approve(coordinator: DurableWorkflowCoordinator, graph: AgentGraphEngine, payload: ServerApprovalCallbackPayload) { return coordinator.handleApproval(graph, payload); }\n * ```\n */\n override async handleApproval(graph: AgentGraphEngine, payload: ServerApprovalCallbackPayload): Promise<{ \n /** True only when graph resumption and companion-instance persistence complete; false may also mean companion persistence failed after the graph advanced. */\n resumed: boolean; \n /** Optional resumed graph state returned when companion persistence succeeds; omitted when companion persistence is normalized into failure data. */\n state?: AgentGraphState; \n /** Optional graph resume or companion persistence failure detail; reconcile both stores before retrying because graph effects may already have completed. */\n error?: string }> {\n const result = await super.handleApproval(graph, payload)\n if (result.resumed && result.state) {\n try { await this.persist(result.state) } catch (error) { return { resumed: false, error: error instanceof Error ? error.message : 'Workflow instance persistence failed' } }\n }\n return result\n }\n\n private async runAndPersist(graph: AgentGraphEngine, state: AgentGraphState): Promise<AgentGraphState> {\n const result = await super.runWorkflow(graph, state)\n await this.persist(result)\n return result\n }\n\n private async persist(state: AgentGraphState): Promise<void> {\n const current = await this.store.read(state.tenantId, state.sessionId)\n if (!current) throw new Error(`Workflow instance '${state.sessionId}' not found`)\n const value: WorkflowInstanceRecord = {\n ...current.value,\n status: statusForState(state),\n checkpointRevision: state.checkpointRevision,\n updatedAt: new Date().toISOString(),\n ...(state.error ? { error: state.error } : { error: undefined }),\n }\n if (!await this.store.replace(state.tenantId, { ...current, revision: current.revision + 1, value }, current.revision)) throw new Error('Workflow instance revision changed')\n }\n}\n\nfunction statusForState(state: AgentGraphState): WorkflowInstanceStatus {\n if (state.pendingApproval) return 'waiting_approval'\n if (state.error) return 'failed'\n if (state.isComplete) return 'completed'\n return 'running'\n}\n"],"mappings":";;;;;AAwGO,IAAM,6BAAN,cAAyC,sBAAsB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YAAY,SAA4C;AACtD,UAAM,OAAO;AACb,QAAI,CAAC,SAAS,MAAO,OAAM,IAAI,MAAM,qCAAqC;AAC1E,SAAK,QAAQ,QAAQ;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,MAAM,OAAyB,QAAgC,cAAyD;AAC5H,QAAI,OAAO,eAAe,aAAa,aAAa,OAAO,aAAa,aAAa,SAAU,OAAM,IAAI,MAAM,mDAAmD;AAClK,UAAM,WAAW,MAAM,KAAK,MAAM,KAAK,OAAO,UAAU,OAAO,UAAU;AACzE,QAAI,SAAU,OAAM,IAAI,MAAM,kCAAkC;AAChE,UAAM,KAAK,MAAM,OAAO,OAAO,UAAU,EAAE,IAAI,OAAO,YAAY,UAAU,GAAG,OAAO,EAAE,GAAG,gBAAgB,MAAM,GAAG,QAAQ,SAAS,EAAE,CAAC;AACxI,WAAO,KAAK,cAAc,OAAO,YAAY;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAe,YAAY,OAAyB,cAAyD;AAC3G,WAAO,KAAK,cAAc,OAAO,YAAY;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAe,eAAe,OAAyB,SAMrC;AAChB,UAAM,SAAS,MAAM,MAAM,eAAe,OAAO,OAAO;AACxD,QAAI,OAAO,WAAW,OAAO,OAAO;AAClC,UAAI;AAAE,cAAM,KAAK,QAAQ,OAAO,KAAK;AAAA,MAAE,SAAS,OAAO;AAAE,eAAO,EAAE,SAAS,OAAO,OAAO,iBAAiB,QAAQ,MAAM,UAAU,uCAAuC;AAAA,MAAE;AAAA,IAC7K;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,OAAyB,OAAkD;AACrG,UAAM,SAAS,MAAM,MAAM,YAAY,OAAO,KAAK;AACnD,UAAM,KAAK,QAAQ,MAAM;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,QAAQ,OAAuC;AAC3D,UAAM,UAAU,MAAM,KAAK,MAAM,KAAK,MAAM,UAAU,MAAM,SAAS;AACrE,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,sBAAsB,MAAM,SAAS,aAAa;AAChF,UAAM,QAAgC;AAAA,MACpC,GAAG,QAAQ;AAAA,MACX,QAAQ,eAAe,KAAK;AAAA,MAC5B,oBAAoB,MAAM;AAAA,MAC1B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,EAAE,OAAO,OAAU;AAAA,IAChE;AACA,QAAI,CAAC,MAAM,KAAK,MAAM,QAAQ,MAAM,UAAU,EAAE,GAAG,SAAS,UAAU,QAAQ,WAAW,GAAG,MAAM,GAAG,QAAQ,QAAQ,EAAG,OAAM,IAAI,MAAM,oCAAoC;AAAA,EAC9K;AACF;AAEA,SAAS,eAAe,OAAgD;AACtE,MAAI,MAAM,gBAAiB,QAAO;AAClC,MAAI,MAAM,MAAO,QAAO;AACxB,MAAI,MAAM,WAAY,QAAO;AAC7B,SAAO;AACT;","names":[]}