@leuduan/lagent 0.0.0-stage → 0.1.2

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 (327) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +144 -2
  3. package/dist/chunks/2O7ZGEIT.js +1 -0
  4. package/dist/chunks/2OSESBIL.js +1 -0
  5. package/dist/chunks/34KW6VNQ.js +1 -0
  6. package/dist/chunks/37YOGDGY.js +1 -0
  7. package/dist/chunks/3LQHQRIU.js +6 -0
  8. package/dist/chunks/3QCW4WDJ.js +1 -0
  9. package/dist/chunks/4XVRUSCQ.js +1 -0
  10. package/dist/chunks/6ECI2GGV.js +1 -0
  11. package/dist/chunks/74HKUGRR.js +1 -0
  12. package/dist/chunks/ADHERZLW.js +2 -0
  13. package/dist/chunks/AP6Q4EPT.js +36 -0
  14. package/dist/chunks/BM3S37EZ.js +1 -0
  15. package/dist/chunks/C5LYCXJG.js +1 -0
  16. package/dist/chunks/CDQG7RKA.js +1 -0
  17. package/dist/chunks/D7E6EWIE.js +3 -0
  18. package/dist/chunks/DDANMY45.js +3 -0
  19. package/dist/chunks/DRYAN665.js +1 -0
  20. package/dist/chunks/DXFXAYDN.js +17 -0
  21. package/dist/chunks/EGZI4XQX.js +24 -0
  22. package/dist/chunks/ENWFSU27.js +41 -0
  23. package/dist/chunks/G6RXC3AL.js +1 -0
  24. package/dist/chunks/G74AGRAJ.js +15 -0
  25. package/dist/chunks/GQGNVSKB.js +1 -0
  26. package/dist/chunks/IJ2WNMD5.js +7 -0
  27. package/dist/chunks/J5S4URAW.js +1 -0
  28. package/dist/chunks/JPZFKSWT.js +1 -0
  29. package/dist/chunks/KESCTXGO.js +5 -0
  30. package/dist/chunks/L3N4FIEN.js +1 -0
  31. package/dist/chunks/NAOUTU7A.js +4 -0
  32. package/dist/chunks/NDIM7MEW.js +1 -0
  33. package/dist/chunks/O4PPOM5Z.js +2 -0
  34. package/dist/chunks/OVZFGILJ.js +1 -0
  35. package/dist/chunks/P5ZHHOOM.js +6 -0
  36. package/dist/chunks/PUSUPTAT.js +1 -0
  37. package/dist/chunks/QMMLQJBS.js +1 -0
  38. package/dist/chunks/RK3VP2Q4.js +3 -0
  39. package/dist/chunks/SGGMBSBA.js +1 -0
  40. package/dist/chunks/SL2YLB2F.js +1 -0
  41. package/dist/chunks/TOOIB6J2.js +1 -0
  42. package/dist/chunks/TYTQRLTX.js +1 -0
  43. package/dist/chunks/UC3FVVJ2.js +5 -0
  44. package/dist/chunks/UCTEU62F.js +1 -0
  45. package/dist/chunks/UD3VJER6.js +1 -0
  46. package/dist/chunks/UKXMCHHT.js +1 -0
  47. package/dist/chunks/WUUKTSRT.js +7 -0
  48. package/dist/chunks/X65X4KP5.js +7 -0
  49. package/dist/chunks/YIR5MYGU.js +1 -0
  50. package/dist/chunks/YLNJXQ3Z.js +1 -0
  51. package/dist/context.d.ts +101 -0
  52. package/dist/index.d.ts +47 -0
  53. package/dist/index.js +77 -0
  54. package/dist/journal/catalog.d.ts +112 -0
  55. package/dist/journal/forkChain.d.ts +16 -0
  56. package/dist/journal/index.d.ts +15 -0
  57. package/dist/journal/journal.d.ts +475 -0
  58. package/dist/journal/projection.d.ts +87 -0
  59. package/dist/journal/store.d.ts +181 -0
  60. package/dist/kit/claim.d.ts +13 -0
  61. package/dist/kit/drain.d.ts +10 -0
  62. package/dist/kit/extension.d.ts +180 -0
  63. package/dist/kit/grants.d.ts +9 -0
  64. package/dist/kit/modes.d.ts +65 -0
  65. package/dist/kit/retries.d.ts +25 -0
  66. package/dist/kit/scope.d.ts +32 -0
  67. package/dist/kit/service.d.ts +7 -0
  68. package/dist/kit/strategy.d.ts +10 -0
  69. package/dist/kit/timers.d.ts +43 -0
  70. package/dist/kit/tool.d.ts +72 -0
  71. package/dist/llm/client.d.ts +135 -0
  72. package/dist/llm/content.d.ts +52 -0
  73. package/dist/llm/door.d.ts +21 -0
  74. package/dist/llm/door.js +1 -0
  75. package/dist/llm/failure.d.ts +82 -0
  76. package/dist/llm/index.d.ts +16 -0
  77. package/dist/llm/primitives.d.ts +286 -0
  78. package/dist/llm/prompt.d.ts +21 -0
  79. package/dist/llm/provider.d.ts +63 -0
  80. package/dist/llm/readLedger.d.ts +24 -0
  81. package/dist/llm/request.d.ts +58 -0
  82. package/dist/loop/agent.d.ts +134 -0
  83. package/dist/loop/auxiliary.d.ts +54 -0
  84. package/dist/loop/chain.d.ts +46 -0
  85. package/dist/loop/chunks.d.ts +27 -0
  86. package/dist/loop/continuation.d.ts +166 -0
  87. package/dist/loop/decide.d.ts +64 -0
  88. package/dist/loop/errors.d.ts +162 -0
  89. package/dist/loop/forks.d.ts +61 -0
  90. package/dist/loop/holds.d.ts +104 -0
  91. package/dist/loop/hooks.d.ts +241 -0
  92. package/dist/loop/inbox.d.ts +188 -0
  93. package/dist/loop/index.d.ts +37 -0
  94. package/dist/loop/limits.d.ts +14 -0
  95. package/dist/loop/opening.d.ts +42 -0
  96. package/dist/loop/prepare.d.ts +30 -0
  97. package/dist/loop/projections.d.ts +307 -0
  98. package/dist/loop/replace.d.ts +33 -0
  99. package/dist/loop/requests.d.ts +129 -0
  100. package/dist/loop/route.d.ts +53 -0
  101. package/dist/loop/runtime.d.ts +85 -0
  102. package/dist/loop/state.d.ts +70 -0
  103. package/dist/loop/strategy.d.ts +71 -0
  104. package/dist/loop/summary.d.ts +3 -0
  105. package/dist/loop/surface.d.ts +153 -0
  106. package/dist/loop/threadState.d.ts +72 -0
  107. package/dist/loop/tool.d.ts +101 -0
  108. package/dist/loop/toolCalls.d.ts +42 -0
  109. package/dist/loop/wake.d.ts +32 -0
  110. package/dist/models/config/agent.d.ts +18 -0
  111. package/dist/models/config/prompt.d.ts +18 -0
  112. package/dist/models/door.d.ts +12 -0
  113. package/dist/models/door.js +1 -0
  114. package/dist/models/index.d.ts +7 -0
  115. package/dist/models/jsonSchema.d.ts +7 -0
  116. package/dist/models/wire/journal.d.ts +2772 -0
  117. package/dist/models/wire/primitives.d.ts +65 -0
  118. package/dist/plugin.d.ts +53 -0
  119. package/dist/plugin.js +1 -0
  120. package/dist/plugins/agentsMd.d.ts +76 -0
  121. package/dist/plugins/agentsMd.js +1 -0
  122. package/dist/plugins/ask/askQuestion.d.ts +9 -0
  123. package/dist/plugins/ask/index.d.ts +26 -0
  124. package/dist/plugins/ask/index.js +1 -0
  125. package/dist/plugins/ask/service.d.ts +125 -0
  126. package/dist/plugins/commands/background.d.ts +8 -0
  127. package/dist/plugins/commands/foreground.d.ts +4 -0
  128. package/dist/plugins/commands/index.d.ts +40 -0
  129. package/dist/plugins/commands/index.js +1 -0
  130. package/dist/plugins/commands/output.d.ts +115 -0
  131. package/dist/plugins/commands/record.d.ts +549 -0
  132. package/dist/plugins/commands/service.d.ts +314 -0
  133. package/dist/plugins/commands/shell.d.ts +25 -0
  134. package/dist/plugins/compaction/checkpoint.d.ts +91 -0
  135. package/dist/plugins/compaction/config.d.ts +133 -0
  136. package/dist/plugins/compaction/estimate.d.ts +29 -0
  137. package/dist/plugins/compaction/index.d.ts +2 -0
  138. package/dist/plugins/compaction/index.js +7 -0
  139. package/dist/plugins/compaction/log.d.ts +61 -0
  140. package/dist/plugins/compaction/planner.d.ts +207 -0
  141. package/dist/plugins/compaction/preset.d.ts +86 -0
  142. package/dist/plugins/compaction/prune.d.ts +9 -0
  143. package/dist/plugins/compaction/records.d.ts +227 -0
  144. package/dist/plugins/compaction/segments.d.ts +23 -0
  145. package/dist/plugins/compaction/shared.d.ts +14 -0
  146. package/dist/plugins/compaction/summarize.d.ts +13 -0
  147. package/dist/plugins/dateAndBranch.d.ts +47 -0
  148. package/dist/plugins/dateAndBranch.js +1 -0
  149. package/dist/plugins/delegations/answers.d.ts +39 -0
  150. package/dist/plugins/delegations/assignmentKey.d.ts +22 -0
  151. package/dist/plugins/delegations/cleanup.d.ts +161 -0
  152. package/dist/plugins/delegations/constraint.d.ts +76 -0
  153. package/dist/plugins/delegations/index.d.ts +39 -0
  154. package/dist/plugins/delegations/index.js +1 -0
  155. package/dist/plugins/delegations/notices.d.ts +261 -0
  156. package/dist/plugins/delegations/obligations.d.ts +210 -0
  157. package/dist/plugins/delegations/record.d.ts +632 -0
  158. package/dist/plugins/delegations/request.d.ts +381 -0
  159. package/dist/plugins/delegations/role.d.ts +30 -0
  160. package/dist/plugins/delegations/service.d.ts +562 -0
  161. package/dist/plugins/delegations/standing.d.ts +19 -0
  162. package/dist/plugins/delegations/stopCheck.d.ts +21 -0
  163. package/dist/plugins/delegations/testing.d.ts +16 -0
  164. package/dist/plugins/delegations/tools.d.ts +71 -0
  165. package/dist/plugins/delegations/waitBook.d.ts +116 -0
  166. package/dist/plugins/delegations/waits.d.ts +118 -0
  167. package/dist/plugins/diagnostics/digest.d.ts +14 -0
  168. package/dist/plugins/diagnostics/index.d.ts +68 -0
  169. package/dist/plugins/diagnostics/index.js +1 -0
  170. package/dist/plugins/historyRecall/history.d.ts +9 -0
  171. package/dist/plugins/historyRecall/index.d.ts +31 -0
  172. package/dist/plugins/historyRecall/index.js +1 -0
  173. package/dist/plugins/historyRecall/render.d.ts +34 -0
  174. package/dist/plugins/historyRecall/tools.d.ts +4 -0
  175. package/dist/plugins/mcp/catalog.d.ts +36 -0
  176. package/dist/plugins/mcp/config.d.ts +63 -0
  177. package/dist/plugins/mcp/connection.d.ts +53 -0
  178. package/dist/plugins/mcp/errors.d.ts +32 -0
  179. package/dist/plugins/mcp/index.d.ts +33 -0
  180. package/dist/plugins/mcp/index.js +5 -0
  181. package/dist/plugins/mcp/mount.d.ts +98 -0
  182. package/dist/plugins/mcp/names.d.ts +25 -0
  183. package/dist/plugins/mcp/render.d.ts +29 -0
  184. package/dist/plugins/mcp/slots.d.ts +15 -0
  185. package/dist/plugins/mcp/stdio.d.ts +49 -0
  186. package/dist/plugins/mcp/tool.d.ts +41 -0
  187. package/dist/plugins/providers/anthropic.d.ts +175 -0
  188. package/dist/plugins/providers/anthropicMessages.d.ts +65 -0
  189. package/dist/plugins/providers/codex.d.ts +60 -0
  190. package/dist/plugins/providers/codexAuth.d.ts +116 -0
  191. package/dist/plugins/providers/deepseek.d.ts +55 -0
  192. package/dist/plugins/providers/door.d.ts +61 -0
  193. package/dist/plugins/providers/door.js +1 -0
  194. package/dist/plugins/providers/failure.d.ts +23 -0
  195. package/dist/plugins/providers/gateway.d.ts +23 -0
  196. package/dist/plugins/providers/index.d.ts +6 -0
  197. package/dist/plugins/providers/openaiChat.d.ts +62 -0
  198. package/dist/plugins/providers/openaiResponses.d.ts +100 -0
  199. package/dist/plugins/providers/opencodeCopilot.d.ts +23 -0
  200. package/dist/plugins/providers/opencodeGo.d.ts +98 -0
  201. package/dist/plugins/providers/shared.d.ts +104 -0
  202. package/dist/plugins/providers/stream.d.ts +154 -0
  203. package/dist/plugins/routeContext.d.ts +22 -0
  204. package/dist/plugins/routeContext.js +1 -0
  205. package/dist/plugins/schedules/index.d.ts +21 -0
  206. package/dist/plugins/schedules/index.js +5 -0
  207. package/dist/plugins/schedules/record.d.ts +396 -0
  208. package/dist/plugins/schedules/service.d.ts +120 -0
  209. package/dist/plugins/schedules/time.d.ts +26 -0
  210. package/dist/plugins/schedules/tools.d.ts +6 -0
  211. package/dist/plugins/skills/discovery.d.ts +54 -0
  212. package/dist/plugins/skills/index.d.ts +31 -0
  213. package/dist/plugins/skills/index.js +1 -0
  214. package/dist/plugins/skills/tool.d.ts +11 -0
  215. package/dist/plugins/store/durableObject.d.ts +23 -0
  216. package/dist/plugins/store/durableObject.js +1 -0
  217. package/dist/plugins/store/durableObjectConnection.d.ts +27 -0
  218. package/dist/plugins/store/memory.d.ts +29 -0
  219. package/dist/plugins/store/sql.d.ts +59 -0
  220. package/dist/plugins/store/sqlite.d.ts +31 -0
  221. package/dist/plugins/store/sqlite.js +1 -0
  222. package/dist/plugins/subAgents/availableRoutes.d.ts +53 -0
  223. package/dist/plugins/subAgents/fork.d.ts +32 -0
  224. package/dist/plugins/subAgents/index.d.ts +67 -0
  225. package/dist/plugins/subAgents/index.js +1 -0
  226. package/dist/plugins/subAgents/tool.d.ts +38 -0
  227. package/dist/plugins/toolPolicy/index.d.ts +61 -0
  228. package/dist/plugins/toolPolicy/index.js +1 -0
  229. package/dist/plugins/tools/editFiles.d.ts +128 -0
  230. package/dist/plugins/tools/fsRead.d.ts +17 -0
  231. package/dist/plugins/tools/html.d.ts +23 -0
  232. package/dist/plugins/tools/index.d.ts +59 -0
  233. package/dist/plugins/tools/index.js +1 -0
  234. package/dist/plugins/tools/network.d.ts +23 -0
  235. package/dist/plugins/tools/ripgrep.d.ts +20 -0
  236. package/dist/plugins/tools/textEdit.d.ts +67 -0
  237. package/dist/plugins/tools/web.d.ts +32 -0
  238. package/dist/plugins/truncateToolOutput.d.ts +26 -0
  239. package/dist/plugins/truncateToolOutput.js +1 -0
  240. package/dist/plugins/usage/index.d.ts +24 -0
  241. package/dist/plugins/usage/index.js +1 -0
  242. package/dist/plugins/usage/tracker.d.ts +34 -0
  243. package/dist/plugins/verify/facts.d.ts +356 -0
  244. package/dist/plugins/verify/index.d.ts +75 -0
  245. package/dist/plugins/verify/index.js +1 -0
  246. package/dist/plugins/verify/service.d.ts +90 -0
  247. package/dist/plugins/workflows/assignment.d.ts +16 -0
  248. package/dist/plugins/workflows/bindings.d.ts +95 -0
  249. package/dist/plugins/workflows/cleanup.d.ts +38 -0
  250. package/dist/plugins/workflows/definition.d.ts +184 -0
  251. package/dist/plugins/workflows/fold.d.ts +373 -0
  252. package/dist/plugins/workflows/index.d.ts +28 -0
  253. package/dist/plugins/workflows/index.js +6 -0
  254. package/dist/plugins/workflows/observations.d.ts +81 -0
  255. package/dist/plugins/workflows/participants.d.ts +143 -0
  256. package/dist/plugins/workflows/policy.d.ts +112 -0
  257. package/dist/plugins/workflows/providers.d.ts +146 -0
  258. package/dist/plugins/workflows/record.d.ts +2863 -0
  259. package/dist/plugins/workflows/routing.d.ts +116 -0
  260. package/dist/plugins/workflows/schema.d.ts +26 -0
  261. package/dist/plugins/workflows/service.d.ts +477 -0
  262. package/dist/plugins/workflows/submit.d.ts +8 -0
  263. package/dist/plugins/workflows/view.d.ts +103 -0
  264. package/dist/plugins/workflows/work.d.ts +21 -0
  265. package/dist/plugins/workspaceContext.d.ts +38 -0
  266. package/dist/plugins/workspaceContext.js +1 -0
  267. package/dist/presets/agents.d.ts +7 -0
  268. package/dist/presets/base.d.ts +10 -0
  269. package/dist/presets/codex.d.ts +60 -0
  270. package/dist/presets/index.d.ts +4 -0
  271. package/dist/presets/prompts.d.ts +56 -0
  272. package/dist/sandbox/absent.d.ts +32 -0
  273. package/dist/sandbox/client.d.ts +39 -0
  274. package/dist/sandbox/files.d.ts +28 -0
  275. package/dist/sandbox/index.d.ts +49 -0
  276. package/dist/sandbox/index.js +4 -0
  277. package/dist/sandbox/mode.d.ts +57 -0
  278. package/dist/sandbox/policy.d.ts +86 -0
  279. package/dist/sandbox/protocol.d.ts +107 -0
  280. package/dist/sandbox/service.d.ts +143 -0
  281. package/dist/sandbox/worker.d.ts +12 -0
  282. package/dist/sandbox/worker.js +1 -0
  283. package/dist/services/admission.d.ts +174 -0
  284. package/dist/services/agents.d.ts +37 -0
  285. package/dist/services/birth.d.ts +220 -0
  286. package/dist/services/contributions.d.ts +73 -0
  287. package/dist/services/core.d.ts +34 -0
  288. package/dist/services/journal.d.ts +26 -0
  289. package/dist/services/launches.d.ts +104 -0
  290. package/dist/services/llm.d.ts +80 -0
  291. package/dist/services/owner.d.ts +367 -0
  292. package/dist/services/preset.d.ts +154 -0
  293. package/dist/services/presets.d.ts +139 -0
  294. package/dist/services/prompts.d.ts +67 -0
  295. package/dist/services/runEvents.d.ts +79 -0
  296. package/dist/services/thread.d.ts +267 -0
  297. package/dist/services/threadActivation.d.ts +100 -0
  298. package/dist/services/threadDirs.d.ts +38 -0
  299. package/dist/services/threadView.d.ts +92 -0
  300. package/dist/services/threads.d.ts +449 -0
  301. package/dist/services/tools.d.ts +41 -0
  302. package/dist/sys/environment.d.ts +47 -0
  303. package/dist/sys/git.d.ts +60 -0
  304. package/dist/sys/paths.d.ts +56 -0
  305. package/dist/sys/spawn.d.ts +176 -0
  306. package/dist/testing/clock.d.ts +17 -0
  307. package/dist/testing/fakeLlm.d.ts +74 -0
  308. package/dist/testing/fedLlm.d.ts +32 -0
  309. package/dist/testing/helpers.d.ts +344 -0
  310. package/dist/testing/index.d.ts +13 -0
  311. package/dist/testing/index.js +1 -0
  312. package/dist/testing/processes.d.ts +13 -0
  313. package/dist/testing/sandbox.d.ts +71 -0
  314. package/dist/testing/settlement.d.ts +6 -0
  315. package/dist/testing/tmpDirs.d.ts +17 -0
  316. package/dist/util/async.d.ts +8 -0
  317. package/dist/util/diff.d.ts +25 -0
  318. package/dist/util/dispatch.d.ts +8 -0
  319. package/dist/util/errors.d.ts +28 -0
  320. package/dist/util/foldState.d.ts +17 -0
  321. package/dist/util/freeze.d.ts +2 -0
  322. package/dist/util/ids.d.ts +2 -0
  323. package/dist/util/json.d.ts +37 -0
  324. package/dist/util/log.d.ts +6 -0
  325. package/dist/util/text.d.ts +21 -0
  326. package/dist/util/version.d.ts +2 -0
  327. package/package.json +175 -3
@@ -0,0 +1,6 @@
1
+ import{e as Rn,f as An,m as le,q as Nn,r as He,s as ie}from"../../chunks/EGZI4XQX.js";import"../../chunks/UD3VJER6.js";import"../../chunks/SGGMBSBA.js";import"../../chunks/3QCW4WDJ.js";import"../../chunks/C5LYCXJG.js";import"../../chunks/J5S4URAW.js";import{d as Mn}from"../../chunks/G74AGRAJ.js";import{a as Tn}from"../../chunks/SL2YLB2F.js";import"../../chunks/JPZFKSWT.js";import"../../chunks/RK3VP2Q4.js";import"../../chunks/74HKUGRR.js";import"../../chunks/QMMLQJBS.js";import{a as Sn}from"../../chunks/YIR5MYGU.js";import"../../chunks/L3N4FIEN.js";import{a as _n,b as En}from"../../chunks/NAOUTU7A.js";import{a as Ke}from"../../chunks/UKXMCHHT.js";import{e as Ve}from"../../chunks/G6RXC3AL.js";import"../../chunks/GQGNVSKB.js";import"../../chunks/DXFXAYDN.js";import{b as te,e as qn}from"../../chunks/DRYAN665.js";import{d as xn}from"../../chunks/2OSESBIL.js";import{K as $n,X as On,a as ee,o as ne}from"../../chunks/YLNJXQ3Z.js";import{a as de,b as jn}from"../../chunks/DDANMY45.js";import{a as ue,d as U,e as N,f as Y,h as je}from"../../chunks/37YOGDGY.js";import{a as Be,i as yn,o as vn}from"../../chunks/KESCTXGO.js";import{e as kn}from"../../chunks/TYTQRLTX.js";import{k as Oe}from"../../chunks/D7E6EWIE.js";import{Service as Vi}from"@leuduan/cordis";import{z as y}from"zod";import{z as m}from"zod";var T="lagent:workflows",z=n=>n.requires.includes(T),P="submit_workflow_output",Pn="workflow_submission",x=m.string().min(1),Ft=m.discriminatedUnion("kind",[m.strictObject({kind:m.literal("input")}),m.strictObject({kind:m.literal("evidence"),provider:x,immutable:m.boolean(),detail:N}),m.strictObject({kind:m.literal("result"),result:x,participant:x.nullable(),decision:x.nullable(),mode:m.enum(["current","historical"])})]),xe=n=>n===null?null:n.kind==="evidence"?{...n,detail:Y(n.detail)}:{...n},Cn=m.strictObject({config:N}),zt=m.strictObject({participants:m.record(x,m.strictObject({configuration:m.strictObject({agent:x,route:kn,environment:vn,installations:m.array(yn)}).nullable(),checks:m.record(x,Cn)})),evidence:m.record(x,Cn)}),Ut=m.discriminatedUnion("context",[m.strictObject({context:m.literal("conversation"),id:x,participant:x,activation:x}),m.strictObject({context:m.literal("isolated"),id:x,participant:x,thread:x,task:x,generation:m.number().int().positive(),lifetime:m.enum(["instance","attempt"]),checks:m.array(x)})]),Jt=m.discriminatedUnion("kind",[m.strictObject({kind:m.literal("accepted"),submission:m.number().int().positive(),ending:m.number().int().positive(),output:N}),m.strictObject({kind:m.literal("ended"),settlement:m.enum(["failed","stopped","completed"]),detail:m.string(),candidate:m.strictObject({submission:m.number().int().positive(),output:N}).nullable(),report:m.string().nullable()}),m.strictObject({kind:m.literal("refused"),detail:m.string()}),m.strictObject({kind:m.literal("unfinished"),candidate:m.strictObject({submission:m.number().int().positive(),output:N}).nullable(),report:m.string().nullable()})]),Wn=m.strictObject({assignment:x,thread:x,task:x,generation:m.number().int().positive(),outcome:Jt}),In=m.discriminatedUnion("kind",[m.strictObject({kind:m.literal("opening")}),m.strictObject({kind:m.literal("routed"),result:x}),m.strictObject({kind:m.literal("decision"),decision:x})]),Ln=m.discriminatedUnion("op",[m.strictObject({op:m.literal("opened"),definition:x,canonical:m.record(m.string(),N),input:N,input_id:x,pins:zt}),m.strictObject({op:m.literal("entered"),transition:x,cause:In,step:x,attempt:x,ordinal:m.number().int().positive(),retires:m.array(x),inputs:m.record(x,Ft.nullable()),evidence:m.record(x,N),assignments:m.array(Ut)}),m.strictObject({op:m.literal("observed"),observations:m.array(Wn).min(1)}),m.strictObject({op:m.literal("stopped"),attempt:x,reason:m.string(),observations:m.array(Wn)}),m.strictObject({op:m.literal("completed"),transition:x,cause:In}),m.strictObject({op:m.literal("decided"),decision:x,operation_id:x,actor:m.string(),attempt:x,reason:m.enum(["gate","exhaustion","recovery"]),result:x.nullable(),verdict:m.enum(["approve","revise"]),option:x.nullable(),feedback:m.string().nullable(),restart:m.array(x)}).refine(n=>n.reason==="recovery"==(n.result===null),{message:"A recovery decision cites no result, and any other decision cites one"}),m.strictObject({op:m.literal("cancel-requested"),operation_id:x,actor:m.string(),reason:m.string()}),m.strictObject({op:m.literal("cancelled"),operation_id:x})]),L=te({plugin:"lagent:workflows",kind:"instance",version:6,policyState:!0,schema:Ln});function Dn(n,e,t,i){return Ln.parse({op:"opened",definition:n.id,canonical:n,input:e,input_id:t,pins:i})}var Fn=m.strictObject({assignment:x,output:N}),zn=n=>({[Pn]:Fn.parse(n)});function Se(n){if(n.name!==P||n.is_error||n.concludes_turn!==!0)return;let e=Fn.safeParse(n.metadata[Pn]);return e.success?e.data:void 0}var G=te({plugin:"lagent:workflows",kind:"reminder",version:1,schema:m.strictObject({assignment:x,epoch:m.number().int().positive()})}),Un=n=>encodeURIComponent(n),Jn=(n,e,t)=>`${n}#${Un(e)}:${t}`,Bn=(n,e)=>`${n}@${Un(e)}`,fe=(n,e)=>n.get(e)??1,Kn=n=>`${n}/result`,Qe=(n,e)=>`${n}/${e}`;function _e(n,e){switch(e.kind){case"opening":return`${n}#opening/next`;case"routed":return`${e.result}/next`;case"decision":return`${e.decision}/next`}}var Ee=n=>`${n}/input`,Vn=te({plugin:"lagent:workflows",kind:"transition",version:1,schema:m.strictObject({transition:x,assignment:x.nullable(),decision:x.nullable()})});var se=(n,e=new Set)=>Qn(n,t=>t.retired||e.has(t.revision));function Hn(n,e){let t=new Set;for(let i of n.attempts.values())if(i.seq<=e)for(let s of i.entered.retires)t.add(s);return Qn(n,i=>t.has(i.revision))}function Qn(n,e){let t=new Set;for(let i of n.results.values()){let s=n.attempts.get(i.attempt).entered.inputs,r=Object.values(s).some(o=>o?.kind==="result"&&o.mode==="current"&&t.has(o.result));(e(i)||r)&&t.add(i.revision)}return t}function qe(n,e){let t=e===null?void 0:n.decisions.get(e);if(t===void 0)return null;let{reason:i,verdict:s,option:r,feedback:o}=t;return{reason:i,verdict:s,option:r,feedback:o}}function Te(n,e,t){let i=e.inputs[t]??null;if(i===null)return null;if(i.kind==="input")return n.opened.input;if(i.kind==="evidence")return e.evidence[t];let s=n.results.get(i.result);return i.participant!==null?s.outputs[i.participant]:{outputs:s.outputs,decision:qe(n,i.decision)}}function Me(n,e,t){let{instance:i,step:s,cause:r}=t,o=e.steps[s];if(o===void 0)return{refused:`the definition has no step ${s}`};for(let{participant:v}of o.assignments)if(e.participants[v]?.context==="isolated"&&n.opened?.pins.participants[v]?.configuration==null)return{refused:`participant ${v} was not pinned when the instance opened: a new participant needs a new workflow id`};let c=(n.ordinals.get(s)??0)+1,a=Jn(i,s,c),u=_e(i,r),{evidence:d}=t,f=d?.attempt===a&&d.transition===u?d.inputs:new Map,l=Kt(n,s,se(n)),g=l===void 0?[]:[l.revision],p=se(n,new Set(g)),h={},w={},k=[];for(let[v,b]of Object.entries(o.inputs)){if(!("source"in b)){let{evidence:F,optional:Ue}=b,Q=f.get(v),Je=Dt=>({refused:`input ${v} (evidence ${F}): ${Dt}`});if(Q===void 0){k.push({input:v,provider:F});continue}if(Q.kind==="unavailable")return Je(`it could not be acquired: ${Q.reason}`);if(Q.kind==="absent"){if(!Ue)return Je("there is none");h[v]=null;continue}if(n.opened?.pins.evidence[F]===void 0)return Je("the instance recorded no pin for its provider");h[v]={kind:"evidence",provider:F,immutable:Q.immutable,detail:Q.detail},w[v]=Q.value;continue}if(b.source==="$input"){h[v]={kind:"input"};continue}let{step:j,participant:S=null}=b.source,A=F=>({refused:`input ${v} (${j}): ${F}`}),D=[...n.results.values()].filter(F=>F.step===j&&(S===null||Object.hasOwn(F.outputs,S))),C;if(b.mode==="historical")C=D.at(-1);else if(j!==s){if(C=D.filter(({revision:Ue})=>!p.has(Ue)).at(-1),C===void 0&&D.length>0)return A("its result is no longer current");let F=C===void 0?null:Bt(n,C,t.deciding);if(C!==void 0&&e.steps[j]?.gate===!0&&F?.verdict!=="approve")return A(`its current result ${C.revision} is not approved`)}if(C===void 0){if(!b.optional)return A("it has no accepted result");h[v]=null;continue}h[v]={kind:"result",result:C.revision,participant:S,decision:t.deciding?.result===C.revision?t.deciding.id:C.decision,mode:b.mode}}return k.length>0?{needs:{transition:u,attempt:a,step:s,inputs:k}}:{row:{op:"entered",transition:u,cause:r,step:s,attempt:a,ordinal:c,retires:g,inputs:h,evidence:w,assignments:o.assignments.map(({participant:v,checks:b})=>{let j=Bn(a,v),S=e.participants[v];if(S.context==="conversation")return{context:"conversation",id:j,participant:v,activation:t.activation};let A=fe(n.generations,v)+(t.deciding?.restart.includes(v)?1:0),D=T;return{context:"isolated",id:j,participant:v,thread:An({owner:D,instance:i,participant:v,attempt:S.lifetime==="attempt"?a:null,generation:A}),task:Rn({owner:D,instance:i,attempt:a,assignment:j,generation:A}),generation:A,lifetime:S.lifetime,checks:[...b]}})}}}var Bt=(n,e,t)=>t?.result===e.revision?t.decision:qe(n,e.decision);function Kt(n,e,t){return[...n.results.values()].filter(i=>i.step===e&&!t.has(i.revision)).at(-1)}function Ye(n,e,t){if(t===void 0||e===null)return!1;let i=n.calls.get(t),s=n.calls.get(e);return i!==void 0&&s!==void 0&&i>s}var Vt=()=>({instance:null,opened:null,attempts:new Map,current:null,results:new Map,decisions:new Map,operations:new Map,ordinals:new Map,counts:new Map,generations:new Map,observed:new Map,stop:null,cancellation:null,terminal:null,answer:ee.init(),calls:new Map,response:null,personAt:null}),_=n=>n.opened!==null&&n.terminal===null&&n.cancellation===null,q=je({key:"lagent:workflows/instance",onFork:"reset",init:Vt,apply(n,e){let t=L.read(e);if(t!==void 0)return ni(n,t,e),n;if(n.opened===null)return n;let i=n.answer;return n.answer=ee.apply(i,e),e.type==="inbox/spliced"&&Ht(n,e),e.type==="run/cause"&&Qt(n,e),e.type==="assistant/message"&&Xe(n,e),e.type==="tool/call"&&en(n,e),e.type==="input/message"&&(Yt(n,e),Gt(n,e)),e.type==="tool/result"&&Zt(n,e),Xt(n,i,e.seq),n}});function pe(n){return!_(n)||n.current===null?[]:n.current.assignments.filter(({state:e})=>e!=="accepted"&&e!=="superseded")}var Ae=n=>pe(n).filter(({context:e})=>e==="conversation");function Ge(n){return n.replacement===null?n.activation:n.replacement.queued.find(({person:e})=>e)?.id??null}var Ze=n=>Ae(n).filter(({state:e})=>e==="scheduled");function Ht(n,e){let{removed:t,inserted:i}=e.data;for(let s of Ze(n)){let{replacement:r}=s;if(r===null){t.includes(s.activation)&&(s.replacement={queued:[]});continue}let o=r.queued.filter(({id:c})=>!t.includes(c));r.queued.splice(0,r.queued.length,...o);for(let c of i)c.source===null&&r.queued.push({id:c.id,person:!1})}}function Qt(n,e){let{input_id:t,chain:i}=e.data;if(!(t===null||i!=="person"))for(let s of Ze(n)){let r=s.replacement?.queued.find(({id:o})=>o===t);r!==void 0&&(r.person=!0)}}function Yt(n,e){let{input_id:t}=e.data;if(t!==null){for(let i of Ze(n))if(Ge(i)===t)i.state="active",i.claimSeq=e.seq,i.replacement=null;else if(i.replacement!==null){let{queued:s}=i.replacement,r=s.findIndex(({id:o})=>o===t);r>=0&&s.splice(r,1)}}}function Xe(n,e){let{tool_calls:t}=e.data.response.message;e.data.interrupted||t.length===0||(n.response={seq:e.seq,ids:t.map(({call_id:i})=>i)},n.calls.clear())}function en(n,e){let{response:t}=n;if(t===null||!e.source_seqs.includes(t.seq))return;let i=t.ids.indexOf(e.data.call_id);i>=0&&n.calls.set(e.seq,i)}function Gt(n,e){if(e.data.source===null){n.personAt=e.seq;return}let t=G.readContribution(e);if(t===void 0)return;let i=Ae(n).find(({id:s})=>s===t.assignment);i!==void 0&&(i.reminded=t.epoch)}function Xn(n,e){return e.claimSeq===null?null:Math.max(e.claimSeq,n.personAt??0)}function Zt(n,e){let t=Se(e.data.result);if(t===void 0)return;let i=Ae(n).find(({id:s})=>s===t.assignment);i===void 0||i.state==="scheduled"||(i.state="candidate",i.candidate={output:t.output,seq:e.seq,call:e.source_seqs[0]??null},i.submitted=i.candidate)}function Xt(n,e,t){let{answer:i}=n;for(let s of Ae(n)){let{candidate:r}=s;if(r===null)continue;let o=i.status!=="none"&&i.seq===r.seq;o&&i.status==="pending"||(o&&i.status==="accepted"&&e.status==="pending"?(s.state="accepted",s.accepted=r,s.closed=t):s.state="active",s.candidate=null)}et(n)}function et(n){let e=n.current;if(e===null||e.result!==null||e.recovery!==null||!e.assignments.every(({state:i})=>i==="accepted"))return;let t=Math.max(...e.assignments.map(({accepted:i})=>i.seq));tt(n,e,t)}function Yn(n,e,t,i){let s=e.flatMap(a=>{let u=pe(n).find(({id:f})=>f===a.assignment);return u!==void 0&&u.context==="isolated"&&u.thread===a.thread&&u.task===a.task&&u.generation===a.generation?[{assignment:u,outcome:a.outcome}]:[]});for(let{assignment:a,outcome:u}of s)u.kind==="accepted"&&(a.state="accepted",a.accepted={output:u.output,seq:t,call:null},a.submitted=a.accepted,a.closed=t);let r=s.flatMap(({assignment:a,outcome:u})=>u.kind==="ended"||u.kind==="refused"?[{assignment:a,outcome:u}]:[]);if(r.length===0&&(et(n),i===null||!pe(n).some(({context:a})=>a==="isolated")))return;let o=new Map;for(let{assignment:a,outcome:u}of s)u.kind==="accepted"||u.kind==="refused"||(u.candidate!==null&&(a.submitted={output:u.candidate.output,seq:t,call:null}),u.report!==null&&o.set(a,u.report));let c=r.length>0?{cause:"failure",detail:r.map(({assignment:a,outcome:u})=>u.kind==="refused"?`${a.participant}: its task could not be started: ${u.detail}`:`${a.participant}: ${u.detail}`).join("; ")}:{cause:"stop",detail:`the user stopped it: ${i}`};nt(n,{...c,seq:t},a=>o.get(a)??null)}function ei(n,e){if(e.cause.kind!=="routed"||n.stop===null)return!1;let t=n.results.get(e.cause.result);return t!==void 0&&t.seq<=n.stop.seq}function nt(n,e,t){let i=n.current,s={},r={};for(let o of i.assignments){if(o.state==="accepted"||o.state==="superseded")continue;o.submitted!==null&&(s[o.participant]=o.submitted.output);let c=t(o);c!==null&&(r[o.participant]=c)}Re(n,e.seq),i.recovery={...e,candidates:s,reports:r,decision:null}}function tt(n,e,t){let i=Kn(e.entered.attempt);e.result=i,n.results.set(i,{revision:i,attempt:e.entered.attempt,step:e.entered.step,outputs:Object.fromEntries(e.assignments.map(({participant:s,accepted:r})=>[s,r.output])),seq:t,decision:null,routed:null,retired:!1})}function Re(n,e){for(let t of pe(n))t.state="superseded",t.candidate=null,t.closed=e}function Gn(n,e,t){let i=e.kind==="routed"?e.result:e.kind==="decision"?n.decisions.get(e.decision)?.result:void 0,s=i==null?void 0:n.results.get(i);s!==void 0&&(s.routed=t)}function Zn(n,e,t){let i=e.filter(({task:s,outcome:r})=>r.kind==="unfinished"||!n.observed.has(s));for(let s of i)s.outcome.kind!=="unfinished"&&n.observed.set(s.task,{...s,seq:t});return i}function ni(n,e,t){switch(e.op){case"opened":if(n.opened!==null)return;n.opened=e,n.instance=t.thread_id;return;case"entered":{if(!_(n)||n.attempts.has(e.attempt))return;Re(n,t.seq);for(let s of e.retires){let r=n.results.get(s);r!==void 0&&(r.retired=!0)}Gn(n,e.cause,e.transition),n.ordinals.set(e.step,e.ordinal),n.counts.set(e.step,(n.counts.get(e.step)??0)+1);let i={entered:e,seq:t.seq,assignments:e.assignments.map(s=>({id:s.id,participant:s.participant,context:s.context,...s.context==="conversation"?{thread:t.thread_id,task:null,generation:null,lifetime:null,checks:[],activation:s.activation}:{thread:s.thread,task:s.task,generation:s.generation,lifetime:s.lifetime,checks:s.checks,activation:s.task},state:"scheduled",replacement:null,claimSeq:null,candidate:null,submitted:null,accepted:null,reminded:null,closed:null})),result:null,recovery:null};if(n.attempts.set(e.attempt,i),n.current=i,i.assignments.length===0)tt(n,i,t.seq);else if(ei(n,e)&&i.assignments.some(({context:s})=>s==="isolated")){let s=`the user stopped it before its work began: ${n.stop.reason}`;nt(n,{cause:"stop",detail:s,seq:t.seq},()=>null)}return}case"observed":Yn(n,Zn(n,e.observations,t.seq),t.seq,null);return;case"stopped":if(!_(n)||n.current?.entered.attempt!==e.attempt)return;n.stop={seq:t.seq,reason:e.reason},Yn(n,Zn(n,e.observations,t.seq),t.seq,e.reason);return;case"completed":if(!_(n))return;Re(n,t.seq),Gn(n,e.cause,e.transition),n.terminal={kind:"completed",transition:e.transition};return;case"decided":{if(!_(n)||n.decisions.has(e.decision))return;if(e.result===null){let i=n.current?.entered.attempt===e.attempt?n.current.recovery:null;if(i===null||i.decision!==null)return;i.decision=e.decision}else{let i=n.results.get(e.result);if(i===void 0||i.decision!==null)return;i.decision=e.decision}n.decisions.set(e.decision,{...e,seq:t.seq}),n.operations.set(e.operation_id,e);for(let i of e.restart)n.generations.set(i,fe(n.generations,i)+1);n.counts.clear();return}case"cancel-requested":if(!_(n))return;Re(n,t.seq),n.cancellation=e,n.operations.set(e.operation_id,e);return;case"cancelled":n.terminal===null&&n.cancellation?.operation_id===e.operation_id&&(n.terminal={kind:"cancelled"});return}}function nn(n){let e=new Map;for(let t of n.attempts.values())for(let{participant:i,lifetime:s,thread:r,generation:o}of t.assignments)s==="instance"&&o===fe(n.generations,i)&&e.set(i,r);return e}function he(n){let e={};if(_(n)){for(let t of nn(n).keys())e[t]={context:"isolated",open:!1};for(let{participant:t,context:i}of pe(n))e[t]={context:i,open:!0}}return{id:n.opened.definition,step:_(n)?n.current?.entered.step??null:null,participants:e}}function me(n,e){let{id:t,step:i}=n;if(e===void 0||e.id!==t)return`definition ${t} is not registered`;let s=[],r=i===null?void 0:e.steps[i];i!==null&&r===void 0&&s.push(`its current step ${i} is gone`);for(let[o,{context:c,open:a}]of Object.entries(n.participants)){let u=a?"an open assignment":"a conversation of its own",d=e.participants[o];d===void 0?s.push(`participant ${o}, with ${u}, is gone`):d.context!==c?s.push(`participant ${o}, with ${u}, changed from ${c} to ${d.context}`):a&&r!==void 0&&!r.assignments.some(f=>f.participant===o)&&s.push(`step ${i} no longer assigns participant ${o}, whose assignment is open`)}return s.length===0?null:`definition ${t} no longer fits the instance: ${s.join("; ")}`}function it(n,e){if(n.opened!==null)return me(he(n),e)===null?e:void 0}function tn(n,e){return{outputs:(e.result===null?void 0:n.results.get(e.result))?.outputs??{},inputs:Object.fromEntries(Object.entries(e.entered.inputs).map(([i,s])=>[i,{value:Te(n,e.entered,i),citation:xe(s)}]))}}import{z as $}from"zod";import{z as W}from"zod";var ti=["title","description"],ii=["type","checks","error"],si={min_length:{props:["minimum"],sets:["minLength"]},max_length:{props:["maximum"],sets:["maxLength"]},length_equals:{props:["length"],sets:["minLength","maxLength"]},string_format:{props:["format","pattern"],sets:["pattern"]},greater_than:{props:["value","inclusive"],sets:["lower"]},less_than:{props:["value","inclusive"],sets:["upper"]},multiple_of:{props:["value"],sets:["multipleOf"]},number_format:{props:["format","type"],sets:["integer"]}},ri={string:["min_length","max_length","length_equals","string_format"],number:["greater_than","less_than","multiple_of","number_format"],array:["min_length","max_length","length_equals"]},ge=n=>n._zod.def,oi=W.string().min(0)._zod.def.checks[0]._zod.def.when,st=n=>n instanceof W.core.$ZodType,ai=n=>Number.isSafeInteger(n)&&n>=0;function rt(n,e){let t=[],i=[],s=(o,c)=>{if(!st(o)){t.push(`${c}: not a zod schema`);return}if(i.includes(o)){t.push(`${c}: a recursive schema`);return}i.push(o);try{return ci(o,c,s,t)}finally{i.pop()}},r=s(n,e);return{problems:t,schema:t.length===0?r:void 0}}function ci(n,e,t,i){let s=i.length,r=l=>{i.push(`${e}: ${l}`)},o={};for(let[l,g]of Object.entries(W.globalRegistry.get(n)??{}))ti.includes(l)?typeof g!="string"?r(`metadata "${l}" is not a string`):o[l]=g:r(`metadata "${l}" (only title and description are admitted)`);let c=ge(n),a=c.type,u=(...l)=>{for(let g of Object.keys(c))!ii.includes(g)&&!l.includes(g)&&r(`${String(a)} with "${g}"`)};if(c.coerce===!0){r("coercion");return}let d=ui(c,String(a),r),f=l=>{if(!(i.length>s||l===void 0))return Object.keys(o).length===0?l:l.meta(o)};switch(a){case"string":{u();let l=W.string();return d.minLength!==void 0&&(l=l.min(d.minLength)),d.maxLength!==void 0&&(l=l.max(d.maxLength)),d.pattern!==void 0&&(l=l.regex(new RegExp(d.pattern))),f(l)}case"number":{c.format==="safeint"&&c.check==="number_format"?(d.integer===!0&&r("the check number_format twice"),d.integer=!0,u("check","abort","format")):u();let l=d.integer===!0?W.int():W.number(),{lower:g,upper:p,multipleOf:h}=d;return g!==void 0&&(l=g.inclusive?l.gte(g.value):l.gt(g.value)),p!==void 0&&(l=p.inclusive?l.lte(p.value):l.lt(p.value)),h!==void 0&&(l=l.multipleOf(h)),f(l)}case"boolean":return u(),f(W.boolean());case"enum":{u("entries");let l=Object.entries(c.entries);if(!l.every(([,g])=>typeof g=="string"||typeof g=="number"&&Number.isFinite(g))){r("an enum with a value that is not a string or finite number");return}return f(W.enum(Object.fromEntries(l)))}case"literal":{u("values");let l=[...c.values];if(!l.every(g=>g===null||["string","boolean"].includes(typeof g)||typeof g=="number"&&Number.isFinite(g))){r("a literal that is not a JSON scalar");return}return f(W.literal(l))}case"object":{u("shape","catchall");let l=c.catchall;(!st(l)||ge(l).type!=="never")&&r("an object that is not strict (use z.strictObject: other objects strip or pass unknown keys)");let g={};for(let[p,h]of Object.entries(c.shape)){let w=t(h,`${e}.${p}`);w!==void 0&&(g[p]=w)}return f(W.strictObject(g))}case"array":{u("element");let l=t(c.element,`${e}[]`);if(l===void 0)return;let g=W.array(l);return d.minLength!==void 0&&(g=g.min(d.minLength)),d.maxLength!==void 0&&(g=g.max(d.maxLength)),f(g)}case"union":{u("options","discriminator","inclusive");let l=c.discriminator;c.inclusive===!1&&l===void 0&&r("an exclusive union");let g=c.options.map((w,k)=>t(w,`${e}|${k}`));if(g.some(w=>w===void 0)||i.length>s)return;let p=g;if(typeof l!="string")return f(W.union(p));let h=new Map;if(p.forEach((w,k)=>{let O=ge(w),v=O.type==="object"?O.shape[l]:void 0,b=v===void 0||!Object.hasOwn(O.shape,l)?void 0:ge(v),j=b?.type==="literal"?b.values:b?.type==="enum"?Object.values(b.entries):void 0;if(j===void 0){r(`branch ${k} of the discriminated union has no literal or enum ${l}`);return}for(let S of j){let A=h.get(S);A!==void 0?r(`branches ${A} and ${k} of the discriminated union share ${l} ${JSON.stringify(S)}`):h.set(S,k)}}),i.length>s)return;try{let w=W.discriminatedUnion(l,p);return w.safeParse(null),f(w)}catch(w){r(`a discriminated union zod refuses: ${w instanceof Error?w.message:String(w)}`);return}}case"nullable":case"optional":{u("innerType");let l=t(c.innerType,e);return f(l===void 0?void 0:a==="nullable"?l.nullable():l.optional())}default:r(`a ${String(a)} schema`);return}}function ui(n,e,t){let i={},s=new Set,r=ri[e]??[];for(let o of n.checks??[]){let c=o._zod.def,a=String(c.check),u=si[a];if(!r.includes(a)||u===void 0){t(a==="custom"?"a refinement":a==="overwrite"?"a normalizing check":`the check ${a}`);continue}for(let l of Object.keys(c))l==="when"&&c.when===oi||["check","error","abort",...u.props].includes(l)||t(`the check ${a} with "${l}"`);let d=u.sets.filter(l=>s.has(l));if(d.length>0){t(`a second check on ${d.join(" and ")} (${a}): one per node`);continue}for(let l of u.sets)s.add(l);let f=c.value;switch(a){case"min_length":case"max_length":case"length_equals":{let l=c[a==="min_length"?"minimum":a==="max_length"?"maximum":"length"];if(!ai(l)){t(`the check ${a} with ${String(l)}, not a non-negative integer`);break}a!=="max_length"&&(i.minLength=l),a!=="min_length"&&(i.maxLength=l);break}case"string_format":{let l=c.pattern;c.format!=="regex"||!(l instanceof RegExp)?t(`the string format ${String(c.format)}`):l.flags!==""?t(`a regex with flags "${l.flags}"`):i.pattern=l.source;break}case"greater_than":case"less_than":if(typeof f!="number"||!Number.isFinite(f)){t(`the check ${a} with ${String(f)}, not a finite number`);break}i[a==="greater_than"?"lower":"upper"]={value:f,inclusive:c.inclusive===!0};break;case"multiple_of":if(typeof f!="number"||!Number.isFinite(f)||f<=0){t(`the check multiple_of with ${String(f)}, not a positive finite number`);break}i.multipleOf=f;break;case"number_format":c.format!=="safeint"?t(`the number format ${String(c.format)}`):i.integer=!0;break}}return i}function re(n,e){if(e.length===0)return[n];let t=ge(n),[i,...s]=e;switch(t.type){case"nullable":case"optional":return re(t.innerType,e);case"union":return t.options.flatMap(r=>re(r,e));case"object":{let r=t.shape;return Object.hasOwn(r,i)?re(r[i],s):[]}case"array":return/^(0|[1-9]\d*)$/.test(i)?re(t.element,s):[];default:return[]}}var oe="$complete",J=class extends Error{workflow;problems;constructor(e,t){super(`Workflow ${e} is refused:
2
+ - ${t.join(`
3
+ - `)}`),this.name="WorkflowDefinitionError",this.workflow=e,this.problems=t}},M=$.string().min(1),ot=$.custom(n=>n instanceof $.ZodType,{error:"Expected a zod schema"}),di=$.strictObject({id:M,input:ot,entry:M,prerequisites:$.array(M).default([]),participants:$.record(M,$.discriminatedUnion("context",[$.strictObject({context:$.literal("conversation")}),$.strictObject({context:$.literal("isolated"),lifetime:$.enum(["instance","attempt"]),role:M,model:$.strictObject({provider:M,model:M,thinkingEffort:Oe.optional(),configurable:$.boolean()})})])),steps:$.record(M,$.strictObject({inputs:$.record(M,$.union([$.strictObject({source:$.union([$.literal("$input"),$.strictObject({step:M,participant:M.optional()})]),mode:$.enum(["current","historical"]),optional:$.boolean()}),$.strictObject({evidence:M,optional:$.boolean()})])),assignments:$.array($.strictObject({participant:M,reads:$.array(M),prompt:$.string(),output:ot,checks:$.array(M).default([])})),gate:$.boolean(),options:$.array($.strictObject({name:M,on:$.array($.enum(["gate","recovery"])).min(1)})).default([]),restriction:M.nullable(),maxAttempts:$.number().int().positive(),edges:$.array($.strictObject({when:$.union([$.literal("otherwise"),$.array($.strictObject({field:$.string(),equals:$.union([$.string(),$.number(),$.boolean(),$.null()])}))]),to:M}))}))}),sn=new WeakMap,at=n=>typeof n=="object"&&n!==null&&sn.has(n);function Ne(n,e){let t=sn.get(n),i=e==="$input"?t?.input:t?.outputs.get(e.step)?.get(e.participant);if(i===void 0)throw new Error(`Workflow ${n.id} has no schema for ${JSON.stringify(e)}`);return i}function li(n){let e=di.safeParse(n),t=fi(n);if(!e.success)throw new J(t,e.error.issues.map(c=>`${c.path.map(String).join(".")||"(definition)"}: ${c.message}`));let i=hi(e.data);if(i.problems.length>0)throw new J(t,i.problems);let s=i.data,r=wi(s);if(r.length>0)throw new J(t,r);let o=ue(pi(s));return sn.set(o,{input:s.input,outputs:new Map(Object.entries(s.steps).map(([c,{assignments:a}])=>[c,new Map(a.map(({participant:u,output:d})=>[u,d]))]))}),o}var fi=n=>{let{id:e}=typeof n=="object"&&n!==null?n:{};return typeof e=="string"?e:"?"};function pi(n){let{input:e,participants:t,steps:i,...s}=n;return JSON.parse(JSON.stringify({...s,input:Ke(e),participants:t,steps:Object.fromEntries(Object.entries(i).map(([r,{assignments:o,...c}])=>[r,{...c,assignments:o.map(({output:a,...u})=>({...u,output:Ke(a)}))}]))}))}function hi(n){let e=[],t=(s,r)=>{let o=rt(s,r);return e.push(...o.problems),o.schema??s},i=Object.fromEntries(Object.entries(n.steps).map(([s,r])=>[s,{...r,assignments:r.assignments.map(o=>({...o,output:t(o.output,`steps.${s}: ${o.participant}'s output`)}))}]));return{problems:e,data:{...n,input:t(n.input,"input"),steps:i}}}var mi=["reason","verdict","option"];function ct(n){if(!n.startsWith("/"))return;let e=n.slice(1).split("/");if(!e.some(t=>/~(?![01])/.test(t)))return e.map(t=>t.replaceAll("~1","/").replaceAll("~0","~"))}function gi(n,e){let t=n;for(let i of ct(e)??[])if(Array.isArray(t)){if(!/^(0|[1-9]\d*)$/.test(i))return;t=t[Number(i)]}else if(typeof t=="object"&&t!==null&&Object.hasOwn(t,i))t=t[i];else return;return t}function we(n,e){let t=ut(n,e);if(t===void 0)throw new Error("No edge matched: a registered step always ends with otherwise");return t}var ut=(n,e)=>n.find(t=>t.when==="otherwise"||t.when.every(({field:i,equals:s})=>gi(e,i)===s)),rn=(n,e)=>({outputs:{},decision:{reason:"recovery",verdict:"revise",option:n,feedback:e}});function on(n,e){let t=(i,s)=>n.when!=="otherwise"&&n.when.some(r=>r.field===i&&r.equals===s);return!t("/decision/reason","recovery")||!t("/decision/option",e)?`its first matching edge does not guard /decision/reason = recovery and /decision/option = ${e}`:n.to===oe?"its first matching edge completes the instance, which a recovery cannot":null}function wi(n){let e=[],{steps:t,participants:i}=n,s=c=>Object.hasOwn(t,c),r=Object.entries(i).filter(([,c])=>c.context==="conversation");r.length>1&&e.push(`participants: more than one conversation participant (${r.map(([c])=>c).join(", ")})`),s(n.entry)||e.push(`entry: unknown step ${n.entry}`);let o=new Set;for(let c of n.prerequisites)o.has(c)&&e.push(`prerequisites: ${c} is listed twice`),o.add(c);for(let[c,a]of Object.entries(t)){let u=`steps.${c}`,d=h=>{e.push(`${u}: ${h}`)};c.startsWith("$")&&d('a step name may not start with "$"');for(let[h,w]of Object.entries(a.inputs)){if(!("source"in w)||w.source==="$input")continue;let{step:k,participant:O}=w.source;if(!s(k)){d(`input ${h} binds unknown step ${k}`);continue}O!==void 0&&!t[k].assignments.some(v=>v.participant===O)&&d(`input ${h} binds participant ${O}, which step ${k} does not assign`),k===c&&w.mode==="current"&&!w.optional&&d(`input ${h} requires the step's own current result, which entering the step retires`)}a.assignments.length===0&&!a.gate&&d("a step with no assignments is a pure gate and must set gate: true");let f=new Set;for(let h of a.assignments){let{participant:w}=h;Object.hasOwn(i,w)||d(`assigns unknown participant ${w}`),f.has(w)&&d(`assigns participant ${w} twice`),f.add(w),h.checks.length>0&&i[w]?.context==="conversation"&&d(`${w}'s assignment lists checks, which only an isolated participant's may`),new Set(h.checks).size!==h.checks.length&&d(`${w}'s assignment lists a check twice`);let k=new Set;for(let O of h.reads)Object.hasOwn(a.inputs,O)||d(`${w} reads unknown input ${O}`),k.has(O)&&d(`${w} reads input ${O} twice`),k.add(O)}let l=new Map;for(let h of a.options)l.has(h.name)&&d(`option ${h.name} is declared twice`),l.set(h.name,h.on),new Set(h.on).size!==h.on.length&&d(`option ${h.name} lists a reason twice`),h.on.includes("gate")&&!a.gate&&d(`option ${h.name} is declared on gate, but the step has no gate`);let g=a.options.some(h=>h.on.includes("recovery"));if(g){let h=a.assignments.every(({participant:w})=>i[w]?.context==="isolated");(a.assignments.length===0||!h)&&d("a recovery option needs every assignment of the step isolated: a mixed step recovers only by retry or cancel");for(let{name:w,on:k}of a.options){if(!k.includes("recovery"))continue;let O=ut(a.edges,rn(w,null)),v=O===void 0?"no edge matches it":on(O,w);v!==null&&d(`option ${w} on recovery: ${v}`)}}(a.edges.length===0||a.edges.at(-1).when!=="otherwise")&&d("the last edge must be otherwise");let p=new Map;a.edges.forEach((h,w)=>{let k=`edge ${w}`;if(h.to!==oe&&!s(h.to)&&d(`${k} targets unknown step ${h.to}`),h.when==="otherwise"){w!==a.edges.length-1&&d(`${k} is otherwise but not last`);return}if(h.when.length===0){d(`${k} has no conditions (use otherwise)`);return}let O=new Map;for(let{field:j,equals:S}of h.when){O.has(j)&&O.get(j)!==S&&d(`${k} tests ${j} for two different values`),O.set(j,S);let D=bi(j,S,a,f,l,g);D!==null&&d(`${k}: ${D}`)}let v=U([...O].sort(([j],[S])=>j<S?-1:j>S?1:0)),b=p.get(v);b!==void 0?d(`${k} repeats the predicate of edge ${b}`):p.set(v,w)})}if(s(n.entry)){let c=new Set([n.entry]),a=[n.entry];for(let u=a.shift();u!==void 0;u=a.shift())for(let{to:d}of t[u].edges)d!==oe&&s(d)&&!c.has(d)&&(c.add(d),a.push(d));for(let u of Object.keys(t))c.has(u)||e.push(`steps.${u}: not reachable from the entry ${n.entry}`)}return e}function bi(n,e,t,i,s,r){let o=ct(n);if(o===void 0)return`${n} is not a JSON Pointer`;let[c,a,...u]=o;if(c==="outputs"){if(a===void 0||!i.has(a))return`${n} names no participant the step assigns`;let d=t.assignments.find(l=>l.participant===a).output,f=re(d,u);return f.length===0?`${n} is not a field of ${a}'s output`:f.some(l=>$.safeParse(l,e).success)?null:`${n} can never equal ${JSON.stringify(e)}`}if(c==="decision"&&u.length===0&&mi.includes(a))switch(a){case"verdict":return e==="approve"||e==="revise"?null:`${n} can never equal ${JSON.stringify(e)}`;case"reason":return e==="exhaustion"?null:e==="gate"?t.gate?null:`${n} tests gate on a step without a gate`:e==="recovery"?r?null:`${n} tests recovery on a step without a recovery option`:`${n} can never equal ${JSON.stringify(e)}`;default:return e===null||typeof e=="string"&&s.has(e)?null:`${n} tests the undeclared option ${JSON.stringify(e)}`}return`${n} is not a routing field (/outputs/<participant>/..., /decision/reason, /decision/verdict or /decision/option)`}function dt(n,e){let t=[],i=(s,r,o)=>{t.push(`${s}: ${r} ${o} is not bound by the host`)};for(let s of n.prerequisites)e.prerequisites.has(s)||t.push(`prerequisites: ${s} is not bound by the host`);for(let[s,r]of Object.entries(n.participants))r.context==="isolated"&&!e.roles.has(r.role)&&i(`participants.${s}`,"role",r.role);for(let[s,{restriction:r,inputs:o,assignments:c}]of Object.entries(n.steps)){let a=`steps.${s}`;r!==null&&!e.restrictions.has(r)&&i(a,"restriction",r);for(let u of Object.values(o))"evidence"in u&&!e.evidence.has(u.evidence)&&i(a,"evidence provider",u.evidence);for(let{checks:u}of c)for(let d of u)e.checks.has(d)||i(a,"check provider",d)}return[...new Set(t)]}var ki=(n,e,t)=>(n.counts.get(t)??0)>=e.steps[t].maxAttempts;function ft(n){let e=n.current;if(!_(n)||e===null||e.result===null)return;let t=n.results.get(e.result);return t.routed===null&&t.decision===null?{attempt:e,result:t}:void 0}var lt={required:[],allowed:[]};function R(n,e){let t=n.current;if(_(n)&&t!==null&&t.recovery!==null&&t.recovery.decision===null)return yi(n,e,t);let i=ft(n);if(i===void 0)return null;let{attempt:s,result:r}=i,o=e.steps[r.step];if(o===void 0)return null;let c=(u,d)=>({id:Qe(s.entered.attempt,u),attempt:s.entered.attempt,reason:u,result:r.revision,subject:tn(n,s),actions:{cleanupPending:!1,verdicts:["approve","revise"],options:an(e,r.step,u),restart:{retry:lt,options:Object.fromEntries(an(e,r.step,u).map(f=>[f,lt]))}},detail:d});if(o.gate)return c("gate",{});let{to:a}=we(o.edges,{outputs:r.outputs,decision:null});return a!==oe&&ki(n,e,a)?c("exhaustion",{blocked:{from:r.step,to:a}}):null}var an=(n,e,t)=>(n.steps[e]?.options??[]).filter(({on:i})=>i.includes(t)).map(({name:i})=>i);function yi(n,e,t){let i=t.recovery,s=d=>{let f=e.participants[d];return f?.context==="isolated"&&f.lifetime==="instance"},r=d=>[...new Set(d)].sort(),o=r(t.assignments.map(({participant:d})=>d).filter(s)),c=r([...n.attempts.values()].flatMap(({assignments:d})=>d.filter(({context:f})=>f==="isolated").map(({participant:f})=>f))).filter(s),{step:a}=t.entered,u=an(e,a,"recovery");return{id:Qe(t.entered.attempt,"recovery"),attempt:t.entered.attempt,reason:"recovery",result:null,subject:tn(n,t),actions:{cleanupPending:!1,verdicts:["revise"],options:u,restart:{retry:{required:[],allowed:o},options:Object.fromEntries(u.map(d=>[d,{required:[],allowed:c}]))}},detail:{recovery:{cause:i.cause,detail:i.detail,candidates:i.candidates,reports:i.reports}}}}function cn(n,e){if(n.reason!=="recovery")return n;let{draining:t,unresolved:i}=e.cleanup,s=t.length>0||i.length>0,r=({allowed:c})=>({required:c.filter(a=>e.uncontinuable.has(a)),allowed:c}),{actions:o}=n;return{...n,actions:{...o,cleanupPending:s,verdicts:s?[]:o.verdicts,restart:{retry:r(o.restart.retry),options:Object.fromEntries(Object.entries(o.restart.options).map(([c,a])=>[c,r(a)]))}}}}function pt(n,e,t,i,s,r){let o=n.instance,c=_e(o,i);if(t===oe)return{kind:"transition",row:{op:"completed",transition:c,cause:i}};let a=Me(n,e,{instance:o,step:t,cause:i,activation:Ee(c),deciding:r,evidence:s});return"needs"in a?{kind:"needs",needs:a.needs}:"refused"in a?{kind:"refused",reason:a.refused}:{kind:"transition",row:a.row}}function Z(n,e,t){let i=ft(n);if(i===void 0||R(n,e)!==null)return{kind:"none"};let{result:s}=i,r=we(e.steps[s.step].edges,{outputs:s.outputs,decision:null});return pt(n,e,r.to,{kind:"routed",result:s.revision},t)}function ht(n,e,t,i,s){let{operationId:r,verdict:o,option:c,feedback:a}=t;if(new Set(t.restart).size!==t.restart.length)return{kind:"refused",reason:"the restart list names a participant twice"};let u=[...t.restart].sort(),d=n.operations.get(r);if(d!==void 0)return d.op==="decided"&&d.decision===t.decision&&d.verdict===o&&d.option===c&&d.feedback===a&&d.restart.length===u.length&&d.restart.every((S,A)=>S===u[A])?{kind:"replay"}:{kind:"refused",reason:`operation ${r} was already used for another request`};if(n.opened===null)return{kind:"refused",reason:"no workflow instance is open on this thread"};if(n.terminal!==null)return{kind:"refused",reason:`the instance is ${n.terminal.kind}`};if(n.cancellation!==null)return{kind:"refused",reason:"the instance is being cancelled"};if(e===void 0)return{kind:"refused",reason:"the instance cannot execute: no definition it can continue on is registered"};let f=R(n,e);if(f===null||f.id!==t.decision)return{kind:"refused",reason:`decision ${t.decision} is not pending`};let l=cn(f,i);if(l.actions.cleanupPending){let{draining:j,unresolved:S}=i.cleanup;return{kind:"refused",reason:`the recovery's cleanup is not established yet: ${[...S,...j].join("; ")}`}}if(!l.actions.verdicts.includes(o))return{kind:"refused",reason:`${o} is not offered on a ${l.reason} decision`};if(c!==null){if(o==="approve")return{kind:"refused",reason:"an option accompanies only revise"};if(!l.actions.options.includes(c))return{kind:"refused",reason:`option ${c} is not declared for a ${l.reason} decision`}}let g=c===null?l.actions.restart.retry:l.actions.restart.options[c],p=u.filter(j=>!g.allowed.includes(j));if(p.length>0)return{kind:"refused",reason:`this decision cannot restart ${p.join(", ")}`};let h=g.required.filter(j=>!u.includes(j));if(h.length>0)return{kind:"refused",reason:`${h.map(S=>`${S} (${i.uncontinuable.get(S)})`).join(", ")} cannot be continued, so this decision must restart ${h.length===1?"it":"them"}`};let w={reason:l.reason,verdict:o,option:c,feedback:a},k=n.attempts.get(l.attempt),O=e.steps[k.entered.step],v;if(l.result!==null)v=we(O.edges,{outputs:n.results.get(l.result).outputs,decision:w}).to;else if(c===null)v=k.entered.step;else{let j=we(O.edges,rn(c,a)),S=on(j,c);if(S!==null)return{kind:"refused",reason:`option ${c} cannot route a recovery: ${S}`};v=j.to}let b=pt(n,e,v,{kind:"decision",decision:l.id},s,{result:l.result,id:l.id,decision:w,restart:u});return b.kind==="needs"?b:b.kind==="refused"?{kind:"refused",reason:`the selected step ${v} cannot be entered: ${b.reason}`}:{kind:"rows",rows:[{op:"decided",decision:l.id,operation_id:r,actor:t.actor,attempt:l.attempt,reason:l.reason,result:l.result,verdict:o,option:c,feedback:a,restart:u},b.row]}}function mt(n,e){let t=n.operations.get(e.operationId);return t!==void 0?t.op==="cancel-requested"&&t.reason===e.reason?{kind:"replay"}:{kind:"refused",reason:`operation ${e.operationId} was already used for another request`}:n.opened===null?{kind:"refused",reason:"no workflow instance is open on this thread"}:n.terminal!==null?{kind:"refused",reason:`the instance is ${n.terminal.kind}`}:n.cancellation!==null?{kind:"refused",reason:`the instance is already being cancelled (${n.cancellation.operation_id})`}:{kind:"rows",rows:[{op:"cancel-requested",operation_id:e.operationId,actor:e.actor,reason:e.reason}]}}var gt=()=>({managed:!1,claims:new Map,submissions:new Map,accepted:new Map,reminded:new Map,calls:new Map,response:null,answer:ee.init()}),be=je({key:"lagent:workflows/participant",init:gt,apply(n,e){if(e.type==="thread/spawned"){if(e.data.fork!==null)return gt();let i=e.data.origin?.cause;return n.managed=i?.kind==="assignment"&&i.owner===T,n}if(!n.managed)return n;let t=n.answer;if(n.answer=ee.apply(t,e),e.type==="input/message"&&e.data.input_id!==null&&!n.claims.has(e.data.input_id)&&n.claims.set(e.data.input_id,e.seq),e.type==="input/message"){let i=G.readContribution(e);i!==void 0&&n.reminded.set(i.assignment,i.epoch)}if(e.type==="assistant/message"&&Xe(n,e),e.type==="tool/call"&&en(n,e),e.type==="tool/result"){let i=Se(e.data.result);i!==void 0&&n.submissions.set(e.seq,{...i,call:e.source_seqs[0]??null})}return e.type==="turn/end"&&t.status==="pending"&&n.answer.status==="accepted"&&n.accepted.set(n.answer.seq,e.seq),n}});function un(n,e,t){let{id:i,thread:s,task:r,generation:o}=n;if(r===null||o===null)throw new Error(`Assignment ${i} runs on the root`);let c=e.claims.get(r),a=[...e.submissions].filter(([p,h])=>c!==void 0&&p>c&&h.assignment===i),u=p=>({assignment:i,thread:s,task:r,generation:o,outcome:p});for(let[p,{output:h}]of a){let w=e.accepted.get(p);if(w!==void 0)return u({kind:"accepted",submission:p,ending:w,output:Y(h)})}let d=a.at(-1),f=d===void 0?null:{submission:d[0],output:Y(d[1].output)},l=t?.latestText??null,g=t?.settlement??null;switch(g?.kind){case void 0:return u({kind:"unfinished",candidate:f,report:l});case"failed":return u({kind:"ended",settlement:"failed",detail:g.why,candidate:f,report:l});case"stopped":{let p=t?.stop==null?"":` (stopped by ${t.stop.by==="person"?"the user":t.stop.by})`;return u({kind:"ended",settlement:"stopped",detail:`${g.reason}${p}`,candidate:f,report:l})}case"completed":return u({kind:"ended",settlement:"completed",detail:"it answered without its answer being an accepted submission of the assignment",candidate:f,report:g.output})}}function wt(n,e){let t=V(e).flatMap(r=>{if(!n.isLoaded(r.thread))return[];let o=le(n,T,{taskId:r.task,childId:r.thread});return[un(r,n.state(be,r.thread),o)]}),i=t.some(({outcome:r})=>r.kind==="ended"),s=t.filter(({outcome:r})=>i||r.kind!=="unfinished");return s.length===0?[]:[{op:"observed",observations:s}]}function bt(n,e,t,i){let s=V(e),r=s.find(({id:f})=>f===t);if(r===void 0)return null;let o={taskId:r.task,childId:r.thread};if(n.summary(o.childId)!==void 0&&(!n.isLoaded(o.childId)||le(n,T,o)!==null))return null;let c=s.flatMap(f=>{if(f===r||!n.isLoaded(f.thread))return[];let l=le(n,T,{taskId:f.task,childId:f.thread});return[un(f,n.state(be,f.thread),l)]}),{id:a,thread:u,generation:d}=r;return{op:"observed",observations:[{assignment:a,thread:u,task:o.taskId,generation:d,outcome:{kind:"refused",detail:i}},...c]}}function V(n){return n.opened===null||n.terminal!==null||n.cancellation!==null||n.current===null?[]:n.current.assignments.filter(({context:e,state:t,task:i})=>e==="isolated"&&t!=="accepted"&&t!=="superseded"&&!n.observed.has(i))}function kt(n,e,t,i){let s=e.current;if(!_(e)||s===null||s.recovery!==null)return null;let r=s.result===null?void 0:e.results.get(s.result),o=r!==void 0&&r.routed===null&&r.decision===null&&R(e,t)===null,c=V(e);if(!o&&c.length===0)return null;let a=c.flatMap(u=>{if(n.summary(u.thread)===void 0)return[];let d=le(n,T,{taskId:u.task,childId:u.thread});return[un(u,n.state(be,u.thread),d)]});return{op:"stopped",attempt:s.entered.attempt,reason:i,observations:a}}import{scopeOf as vi}from"@leuduan/cordis";import{z as Ce}from"zod";var ln=Ce.strictObject({allow:Ce.array(Ce.string()),denial:Ce.string().optional()}),yt=n=>n.source_seq,ae=(n,e)=>n!==null&&n.caller_thread_id===e&&n.cause.kind==="assignment"&&n.cause.owner===T;function ce(n,e){let t=n.journal.origins.callers(e).threads,i=t.at(-1);if(i===void 0)return;if(i.origin!==null)return{unreadable:"This thread's conversation root cannot be found, so its workflow cannot be read."};if(!z(i))return;let s=i.thread_id,r=n.journal.state(q,s);if(r.opened!==null){if(t.length===1)return{root:s,state:r,kind:"root"};for(let o=0;o<t.length-1;o+=1){let c=t[o];if(ae(c.origin,s)){let a=n.journal.state(be,c.thread_id);if(o===0)return{root:s,state:r,kind:"participant",thread:c.thread_id,facts:a};let u=yt(t[o-1].origin);return{root:s,state:r,kind:"descendant",source:{kind:"participant",thread:c.thread_id,facts:a,seq:u}}}if(o===t.length-2)return{root:s,state:r,kind:"descendant",source:{kind:"root",seq:yt(c.origin)}}}}}var $t=(n,e)=>_(n)&&n.current?.assignments.includes(e)===!0&&e.state!=="accepted"&&e.state!=="superseded";function B(n){if(!(!_(n)||n.current===null))return n.current.assignments.find(e=>e.context==="conversation"&&$t(n,e))}function $i(n,e){for(let t of[...n.attempts.values()].reverse()){let i=t.assignments.find(({context:s,claimSeq:r,closed:o})=>s==="conversation"&&r!==null&&r<=e&&(o===null||o>e));if(i!==void 0)return i}}function X(n,e,t,i){let s;for(let r of n.attempts.values())for(let o of r.assignments){if(o.thread!==e||o.task===null)continue;let c=t.claims.get(o.task);c===void 0||i!==void 0&&c>i||(s===void 0||c>s.claimed)&&(s={assignment:o,claimed:c})}return s?.assignment}function Oi(n,e){let t=e.task===null?void 0:n.claims.get(e.task);if(t===void 0)return!1;for(let i of n.accepted.keys())if(i>t&&n.submissions.get(i)?.assignment===e.id)return!0;return!1}function ji(n,e,t){let i=e.executable(n);if(n.cancellation!==null)return{kind:"coordination",why:"the workflow is being cancelled"};if(i===void 0)return{kind:"coordination",why:"the workflow cannot continue on the definition registered"};if(R(n,i)!==null)return{kind:"coordination",why:"a decision is pending, which freezes submission and changes"};let s=B(n);return s===void 0||s.claimSeq===null?{kind:"coordination",why:"no assignment of yours is active"}:t===void 0||t<s.claimSeq?{kind:"coordination",why:`the call was asked for before assignment ${s.id} began`}:Ot(n,i,e,s)}function dn(n,e,t,i){let s=e.executable(n);return n.cancellation!==null?{kind:"closed",why:"its workflow is being cancelled"}:s===void 0?{kind:"closed",why:"its workflow cannot continue on the definition registered"}:R(n,s)!==null?{kind:"closed",why:"a decision is pending on its workflow, which freezes its work"}:t===void 0?{kind:"closed",why:"no workflow assignment covers it"}:$t(n,t)?i!==null&&Oi(i,t)?{kind:"closed",why:`workflow assignment ${t.id} was accepted`}:Ot(n,s,e,t):{kind:"closed",why:`workflow assignment ${t.id} has ended`}}function Ot(n,e,t,i){let s=e.steps[n.current.entered.step].restriction;return{kind:"assignment",assignment:i,restriction:s===null?null:t.restrictions[s]}}function fn(n,e,t){let{state:i}=n;switch(n.kind){case"root":return ji(i,e,t);case"participant":return dn(i,e,X(i,n.thread,n.facts,t),n.facts);case"descendant":{let{source:s}=n;if(s.kind==="participant")return dn(i,e,X(i,s.thread,s.facts,s.seq),s.facts);let r=$i(i,s.seq);return r!==void 0?dn(i,e,r,null):{kind:"coordination",why:"it was started while its conversation coordinated"}}}}var H=n=>({decision:"deny",reason:n});function xi(n,e){if(n.kind==="root"){let r=B(n.state),o=r?.candidate?.call??null;return Ye(n.state,o,e)?r:void 0}if(n.kind!=="participant")return;let{facts:t}=n,{answer:i}=t,s=i.status==="pending"?t.submissions.get(i.seq):void 0;if(!(s===void 0||!Ye(t,s.call,e)))return X(n.state,n.thread,t,void 0)}function vt(n,e,t){if(!n.allow.includes(e))return H(n.denial??`${e} is not allowed while ${t}.`)}function Si(n,e,t,i){let s=i.name===P,r=()=>s?H("No workflow assignment of yours is active, so there is nothing to submit."):void 0;if(n.journal.summary(t)===void 0)return r();let o=ce(n,t);if(o===void 0)return r();if("unreadable"in o)return H(o.unreadable);if(o.state.terminal!==null)return r();let c=n.journal.state(ne,t).dispatchedCalls.get(i.call_id),a=xi(o,c);if(a!==void 0)return H(`Not run: this response already submitted assignment ${a.id}, and that submission is its answer, so the calls after it do not run.`);let u=fn(o,e,c);if(u.kind==="closed")return H(s?`Nothing can be submitted now: ${u.why}.`:`This thread works under a workflow, and no workflow authority covers this call: ${u.why}.`);if(u.kind==="coordination")return s?H(`Nothing can be submitted now: ${u.why}.`):vt(e.coordination,i.name,u.why);if(s){if(u.assignment.thread!==t)return H(`Only the participant working assignment ${u.assignment.id} may submit it.`);let d=i.arguments.assignmentId;return d===u.assignment.id?void 0:H(`Your active assignment is ${u.assignment.id}; ${JSON.stringify(d)} is not.`)}return u.restriction===null?void 0:vt(u.restriction,i.name,`assignment ${u.assignment.id} is active`)}function jt(n,e){n.on("lagent/tool/authorize",({toolCall:t,threadId:i})=>Si(n,e,i,t)),n.on("lagent/thread/activate",t=>{let i=n.journal.summary(t.id),s=i?.origin==null?void 0:n.journal.summary(i.origin.caller_thread_id),r=i===void 0?void 0:i.origin===null?i:s?.origin===null&&ae(i.origin,s.thread_id)?s:void 0;if(r===void 0||!z(r))return;let o=()=>{if(!n.journal.isLoaded(r.thread_id))return!1;let a=n.journal.state(q,r.thread_id);return a.opened===null||a.terminal!==null};if(o())return;let c=vi(t.ctx);t.ctx.effect(()=>{let a=n.tools.grant(c,[t.agentName],P),u=n.journal.subscribe(d=>{a===null||d.thread_id!==r.thread_id||!o()||(a(),a=null)});return()=>{u(),a?.()}})})}function ke(n,e,t){let i=[],s=[];for(let r of t){let o=r===e?"":`thread ${r}, `,c=Mn(n,r,{descendants:!1});i.push(...c.draining.map(a=>`${o}${a}`)),s.push(...c.unresolved.map(a=>`${o}${a}`));for(let a of He(n.journal,r))i.push(`${o}the stop of ${a.targets.length} agent task(s) has not finished`)}if(!t.has(e))for(let r of He(n.journal,e)){let o=r.targets.filter(({childId:c})=>t.has(c));o.length>0&&i.push(`the stop of ${o.length} agent task(s) has not finished`)}for(let r of ie(n.journal,e))t.has(r.childId)&&(r.state==="unavailable"?s.push(`agent ${r.childId}: its task cannot be read (${r.error})`):r.state==="open"?i.push(`agent ${r.childId} has not finished`):(r.draining||r.cleanupPending)&&i.push(`agent ${r.childId} is still being cleaned up`));return{draining:i,unresolved:s}}function We(n,e,t){let i=new Set;for(let s of n.subtree(e,{self:!0})){let{origin:r}=s,o=r!==null&&!ae(r,t)&&i.has(r.caller_thread_id);(s.thread_id===e||o)&&i.add(s.thread_id)}return i}function xt(n,e,t){let i=e.instance,s=new Map;if(i===null||e.opened===null||e.terminal!==null)return{cleanup:{draining:[],unresolved:[]},uncontinuable:s};let r=n.journal.summaryMap(),o=t.map(p=>`the start of assignment ${p}'s task is still in flight`);if(e.cancellation!==null){let p=n.journal.origins.subtree(i,{self:!0}).map(({thread_id:w})=>w),h=ke(n,i,new Set(p));return{cleanup:{draining:[...h.draining,...o],unresolved:h.unresolved},uncontinuable:s}}let c=e.current;if(c?.recovery==null||c.recovery.decision!==null)return{cleanup:{draining:[],unresolved:[]},uncontinuable:s};let a=new Set;for(let{context:p,thread:h}of c.assignments)if(p==="isolated")for(let{thread_id:w}of n.journal.origins.subtree(h,{self:!0}))a.add(w);let u=c.assignments.some(({context:p})=>p==="conversation");if(u)for(let p of We(n.journal.origins,i,i))a.add(p);let d=ke(n,i,a),f=[...d.draining,...o],l=[...d.unresolved];if(u){let{pending:p,runs:h}=n.journal.state(ne,i).requests,w=p===null?void 0:h.get(p.runId)?.requestedAt;w!==void 0&&w<=c.recovery.seq&&f.push(`the conversation's run ${p.runId}, under way when its assignment was superseded, has not ended`)}let g=n.get("delegations");for(let[p,h]of nn(e)){if(!r.has(h))continue;let w=O=>{f.push(`whether ${p}'s conversation can be continued is not known yet: ${O}`)};if(g===void 0){w("delegations is not mounted");continue}if(!n.journal.isLoaded(h)){w("it is not loaded");continue}let k=g.continuation(h);k!==null&&(k.kind==="refusal"?s.set(p,k.reason):k.kind==="wait"?f.push(`${p}: ${k.reason}`):l.push(`${p}: ${k.reason}`))}return{cleanup:{draining:f,unresolved:l},uncontinuable:s}}var _i="another participant's task in the same workflow attempt ended without acceptance";function pn(n,e,t){let i=e.instance,s=new Set(t.observations.flatMap(({task:c,outcome:a})=>a.kind==="ended"||a.kind==="refused"?[c]:[]));if(i===null||s.size===0)return[];let r=new Map(ie(n.journal,i).flatMap(c=>c.state!=="unavailable"&&(c.state==="open"||c.draining)?[[c.taskId,c]]:[])),o=V(e).flatMap(({task:c,thread:a})=>c===null||s.has(c)||r.get(c)?.childId!==a?[]:[{taskId:c,childId:a}]);return o.length===0?[]:[Nn(i,_i,o)]}import{z as Ie}from"zod";var Ei=Ie.strictObject({instance:Ie.string().min(1),status:Ie.enum(["assignment","decision","blocked","cleanup","ended"]),subject:Ie.string().nullable()}),qi=te({plugin:"lagent:workflows",kind:"presentation",version:1,schema:Ei});function Ti(n,e,t){let{state:i,facts:s,thread:r,root:o}=n;if(i.terminal!==null||i.cancellation!==null||i.current===null||e===void 0||R(i,e)!==null)return;let c=new Set(t.claimed.map(({id:u})=>u)),a=i.current.assignments.find(u=>u.thread===r&&u.state!=="accepted"&&u.state!=="superseded"&&(c.has(u.task)||X(i,r,s,void 0)===u));return a===void 0?void 0:{instance:o,status:"assignment",subject:a.id}}function Mi(n,e,t){let i=n.instance;if(n.terminal!==null)return{instance:i,status:"ended",subject:n.terminal.kind};if(n.cancellation!==null)return{instance:i,status:"cleanup",subject:null};if(e===void 0)return{instance:i,status:"blocked",subject:"its definition is not registered, or no longer fits where it stands"};let s=R(n,e);if(s!==null)return{instance:i,status:"decision",subject:s.id};let r=B(n);if(r!==void 0){if(r.state!=="scheduled")return{instance:i,status:"assignment",subject:r.id};let c=Ge(r);return t.claimed.some(({id:a})=>a===c)?{instance:i,status:"assignment",subject:r.id}:void 0}let o=Z(n,e);return o.kind==="refused"?{instance:i,status:"blocked",subject:o.reason}:void 0}function _t(n,e){let t=i=>{if(n.journal.summary(i)===void 0)return;let s=ce(n,i);return s===void 0||"unreadable"in s?void 0:s};qn(n,{event:qi,rank:2,current:i=>{let s=t(i.threadId);if(s===void 0)return;let r=e.executable(s.state);return s.kind==="participant"?Ti(s,r,i):s.kind==="root"?Mi(s.state,r,i):void 0},render:(i,s,{step:r})=>{let o=n.journal.state(q,i.instance),c=e.executable(o);if(r.threadId!==i.instance){let f=o.current.assignments.find(({id:l})=>l===i.subject);return Be("workflow",St(o,c,f,e),{attrs:{id:i.instance,status:i.status}})}let a=o.opened.definition,u=f=>Be("workflow",f,{attrs:{id:i.instance,status:i.status}}),d=`Until then you work under the coordination policy: ${Ai(e.coordination)}`;switch(i.status){case"assignment":{let f=B(o);return u(St(o,c,f,e))}case"decision":{let{recovery:f}=o.current;return u(f!==null?Ri(a,o.current,i.subject,d):`Workflow ${a}: step ${o.current.entered.step}'s result awaits a decision (${i.subject}). Nothing can be submitted or changed until it is decided, and chat is discussion only: the user decides. `+d)}case"blocked":return u(`Workflow ${a} cannot go on: ${i.subject}. ${d}`);case"cleanup":return u(`Workflow ${a} is being cancelled. ${d}`);case"ended":return s===null||s.status==="ended"?null:u(`Workflow ${a} ${i.subject==="completed"?"is complete":"was cancelled"}: its restrictions no longer apply, and this conversation goes on as ordinary chat.`)}}})}function Ri(n,e,t,i){let s=e.recovery,{step:r,ordinal:o}=e.entered,c=[`Workflow ${n}: attempt ${o} of step ${r} cannot finish (${s.cause==="stop"?"stopped":"failed"}: ${s.detail}), and awaits a recovery decision (${t}): a retry, a declared option, or cancelling. Nothing can be submitted or changed until it is decided, and chat is discussion only: the user decides. ${i}`],a=Et(s,null);return a.length>0&&c.push("","Unaccepted, shown to you as its coordinator only:",...a),c.join(`
4
+ `)}function Et(n,e){let t=[],i=s=>e===null||s===e;for(let[s,r]of Object.entries(n.candidates))i(s)&&t.push(`- ${s}'s last submission, not accepted: ${JSON.stringify(r)}`);for(let[s,r]of Object.entries(n.reports))i(s)&&t.push(`- ${s}'s partial report, not accepted: ${r}`);return t}var Ai=n=>`${n.allow.length===0?"no tool may be called":`you may call only ${n.allow.join(", ")}`}; any other call is denied, and a listed tool still needs to be granted to you and allowed by the host's permissions.`,Ni=(n,e)=>`${n.allow.length===0?"no other tool may be called":`the only other tools you may call are ${n.allow.join(", ")}`}; any other call is denied, and a listed tool still needs to be granted to you and allowed by the host's permissions. ${P} for assignment ${e} stays available whatever the list says, subject to the host's permissions.`;function St(n,e,t,i){let s=n.current,{step:r,ordinal:o}=s.entered,c=e.steps[r],a=c.assignments.find(({participant:g})=>g===t.participant),u=[`Workflow ${e.id}, step ${r}, attempt ${o}: your assignment is ${t.id}.`,"",a.prompt];if(a.reads.length>0){u.push("","Inputs:");for(let g of a.reads){let p=s.entered.inputs[g]??null;u.push(`- ${g} (${Ci(n,p)}): ${JSON.stringify(Te(n,s.entered,g))}`)}}let d=Wi(n,s,t.participant);d!==null&&u.push("",d);let f=Ii(n,t);f.length>0&&(u.push("","Superseded since your previous assignment, so do not rely on them as you remember them:"),u.push(...f.map(g=>`- ${g}`))),u.push("",`Submit your output with ${P} ({ "assignmentId": "${t.id}", "output": ... }); the output must match this JSON Schema:`,JSON.stringify(a.output));let l=c.restriction===null?null:i.restrictions[c.restriction];return u.push("",l===null?`This step adds no restriction to your calls; ${P} for assignment ${t.id} is available, subject to the host's permissions.`:`While this assignment is active, ${Ni(l,t.id)}`,"","Status: the workflow is running; this step waits on your submission."),u.join(`
5
+ `)}function Pe(n){return n==="approve"?"approved":"sent back"}function Ci(n,e){if(e===null)return"optional, nothing to bind";if(e.kind==="input")return"the workflow's input";if(e.kind==="evidence"){let o=e.immutable?"a snapshot":"live: it describes the state at this step's entry, which may have changed since";return`evidence from ${e.provider}, ${o}`}let t=n.results.get(e.result),i=e.participant===null?"result":`${e.participant}'s output`,s=e.decision===null?void 0:n.decisions.get(e.decision),r=s===void 0?"":`, ${Pe(s.verdict)}`;return`${i} of step ${t.step}, revision ${t.revision}, ${e.mode}${r}`}function Wi(n,e,t){let{cause:i}=e.entered;if(i.kind!=="decision")return null;let s=n.decisions.get(i.decision),r=n.attempts.get(s.attempt),o=s.option===null?"":` (${s.option})`,c=s.feedback===null?"":`, with this feedback: ${s.feedback}`,a=`This attempt was opened when step ${r.entered.step} was ${Pe(s.verdict)}${o} (decision ${s.decision})${c}.`;if(r.recovery===null)return a;let u=Et(r.recovery,t),d=`That attempt could not finish: ${r.recovery.detail}.`;return u.length===0?`${a} ${d}`:[`${a} ${d} What you left in it, not accepted:`,...u].join(`
6
+ `)}function Ii(n,e){let t=null;for(let o of n.attempts.values()){if(o===n.current)break;for(let c of o.assignments)c.participant===e.participant&&(c.context==="isolated"?t=o.seq:c.claimSeq!==null&&(t=c.claimSeq))}if(t===null)return[];let i=se(n),s=Hn(n,t),r=[...n.results.values()].filter(({revision:o})=>!i.has(o));return[...i].filter(o=>!s.has(o)).map(o=>{let{step:c}=n.results.get(o),a=r.filter(u=>u.step===c).at(-1);return a===void 0?`${o} (step ${c}) is no longer current`:`${o} (step ${c}) is replaced by ${a.revision}`})}var Le=class{handle;inFlight=new Map;running=new Set;outcomes=new Map;reported=new Set;closing=!1;ctx;options;constructor(e,t){this.ctx=e,this.options=t}register(){let e=this.ctx.get("delegations");if(e===void 0)return()=>{};let t=e.registerOwner({name:T,authorize:(i,s)=>this.authorize(i,s),settled:i=>this.options.reconcile(i.callerThreadId)});return this.handle=t,()=>{this.handle===t&&(this.handle=void 0);for(let{controller:i}of this.inFlight.values())i.abort(new Error("The workflow owner was withdrawn"));t.dispose()}}changed(e){this.handle?.changed(e)}starting(e){return[...this.inFlight.values()].filter(t=>t.root===e).map(({assignment:t})=>t)}waiting(e){return[...this.outcomes.get(e)?.values()??[]].some(({kind:t})=>t==="wait")}held(e){return[...this.outcomes.get(e)?.values()??[]].some(({kind:t})=>t==="hold")}of(e){let t=this.outcomes.get(e);return t===void 0&&this.outcomes.set(e,t=new Map),t}states(e,t){let i=qt(this.ctx,e),s=new Map;for(let r of hn(t)){let o=i.has(r.task);s.set(r.id,o?{kind:"started"}:this.outcomes.get(e)?.get(r.id)??{kind:"starting"})}return s}dispatch(e,t){let i=this.ctx.journal.state(q,e),s=this.of(e);for(let r of s.keys())i.current?.assignments.some(o=>o.id===r)||s.delete(r);if(s.size===0&&this.outcomes.delete(e),!(this.closing||this.options.quarantined(e)!==null))for(let r of this.owed(e,i)){if(this.inFlight.has(r.task))continue;let o=this.outcomes.get(e)?.get(r.id);if(t==="capacity"&&!(o?.kind==="wait"&&o.on==="capacity"))continue;let c=new AbortController;this.inFlight.set(r.task,{root:e,assignment:r.id,controller:c});let a=this.start(e,r.id,c.signal).catch(u=>{this.of(e).set(r.id,{kind:"hold",reason:`assignment ${r.id} cannot start its task: ${de(u)}`}),this.ctx.reportError(u)}).finally(()=>{this.inFlight.delete(r.task),this.running.delete(a);let u=this.outcomes.get(e)?.get(r.id);this.options.ended(e,u===void 0),u!==void 0&&!(u.kind==="wait"&&u.on==="capacity")&&this.retryCapacity(e)});this.running.add(a)}}retryCapacity(e){if(![...this.outcomes.get(e)?.values()??[]].some(s=>s.kind==="wait"&&s.on==="capacity")||this.closing)return;let i=this.ctx.threads.retain(()=>[e],{lastRelease:"keep"}).then(s=>{try{this.dispatch(e,"capacity")}finally{s.release()}}).catch(s=>this.ctx.reportError(s)).finally(()=>this.running.delete(i));this.running.add(i)}async shutdown(){this.closing=!0,await Promise.allSettled([...this.running])}owed(e,t){let i=t.opened===null?void 0:this.options.executable(t);if(i===void 0||R(t,i)!==null)return[];let s=qt(this.ctx,e);return hn(t).filter(r=>!s.has(r.task))}async start(e,t,i){let s=await this.ctx.threads.retain(()=>[e],{lastRelease:"keep"});try{let r=this.ctx.journal.state(q,e),o=this.owed(e,r).find(d=>d.id===t);if(o===void 0)return;let c=this.handle;if(c===void 0){this.of(e).set(t,{kind:"hold",reason:"delegations, which starts isolated participants, is not mounted"});return}let a=this.request(r,o,i);if("hold"in a){this.of(e).set(t,{kind:"hold",reason:a.hold});return}let u=await c.start(a);u.kind==="refusal"?await this.options.refused(e,t,u.reason):this.settle(e,o,u)}finally{s.release()}}settle(e,t,i){let{id:s}=t;switch(i.kind){case"opened":case"discard":this.of(e).delete(s);return;case"wait":this.of(e).set(s,{kind:"wait",on:i.on,reason:i.reason});return;case"hold":this.of(e).set(s,{kind:"hold",reason:i.reason});return;case"conflict":case"vetoed":{let r=`assignment ${s} cannot start its task: ${i.reason}`;this.of(e).set(s,{kind:"hold",reason:r}),this.reported.has(r)||(this.reported.add(r),this.ctx.reportError(new Error(`Workflow ${e}: ${r}`)));return}}}request(e,t,i){let{opened:s}=e,r=this.options.executable(e),o=e.current.entered.step,{participant:c}=t,a=s.pins.participants[c];if(t.lifetime===null||a?.configuration==null)throw new Error(`Assignment ${t.id} names no isolated participant the instance pinned`);let u=[];for(let d of t.checks){let f=this.options.providers.problem("check",d,a.checks[d]);if(f!==null)return{hold:f};u.push(this.options.checks[d].owed({config:a.checks[d].config,owner:T,assignment:t.id,generation:t.generation,inputId:t.task}))}return{callerThreadId:e.instance,grantedSeq:e.current.seq,instance:e.instance,attempt:e.current.entered.attempt,assignment:t.id,participant:c,lifetime:t.lifetime,generation:t.generation,configuration:Pi(a,this.options.checks),task:`Workflow ${r.id}: assignment ${t.id} (step ${o}) is yours; its instructions come with your next step.`,...u.length===0?{}:{rows:Li(u)},signal:i}}authorize(e,t){let i=e.callerThreadId,s=this.options.quarantined(i);if(s!==null)return{kind:"hold",reason:`its workflow instance could not be repaired: ${s}`};if(t==="running"){let u=this.options.runnable(i);return u==="allow-all"?{kind:"allow"}:Array.isArray(u)?u.includes(e.taskId)?{kind:"allow"}:{kind:"hold",reason:`its workflow assignment ${e.assignment} does not run now`}:{kind:"hold",reason:`its workflow cannot be read: ${u.unavailable}`}}if(!this.ctx.journal.isLoaded(i))return{kind:"hold",reason:`its workflow's root ${i} is not loaded`};let r=this.ctx.journal.state(q,i);if(!_(r))return{kind:"discard",reason:"its workflow ended or is being cancelled"};let o=hn(r).find(({id:u})=>u===e.assignment);if(o===void 0||o.task!==e.taskId||o.thread!==e.childId||o.generation!==e.generation||r.current.seq!==e.grantedSeq)return{kind:"discard",reason:`workflow assignment ${e.assignment} is no longer open as this task`};let c=this.options.executable(r);if(c===void 0)return{kind:"hold",reason:"its workflow cannot continue on the definition registered"};if(R(r,c)!==null)return{kind:"hold",reason:"a decision is pending"};let a=r.opened.pins.participants[o.participant]?.checks??{};for(let u of o.checks){let d=this.options.providers.problem("check",u,a[u]);if(d!==null)return{kind:"hold",reason:d}}return{kind:"allow"}}};function hn(n){return!_(n)||n.current===null||n.current.recovery!==null?[]:n.current.assignments.filter(({context:e,state:t,task:i})=>e==="isolated"&&t!=="accepted"&&t!=="superseded"&&!n.observed.has(i))}function qt(n,e){return new Set(ie(n.journal,e).flatMap(t=>"taskId"in t?[t.taskId]:[]))}function Tt(n){let e=[];for(let t of n.attempts.values())for(let{task:i,state:s}of t.assignments){if(i===null)continue;let r=t===n.current&&s!=="accepted"&&s!=="superseded";(s==="accepted"||r)&&e.push(i)}return e}function Pi(n,e){let{agent:t,route:i,environment:s,installations:r}=n.configuration,o=new Set(Object.keys(n.checks).flatMap(c=>e[c]?.requires??[]));return{agent:t,route:i,environment:s,installations:r.map(({installation_id:c,preset_id:a,config:u,lifetime:d})=>({installationId:c,presetId:a,config:u,lifetime:d})),requires:[...o].sort()}}function Li(n){return e=>{let t=[];for(let i of n){let s=i(e);if($n(s))return s;t.push(...s)}return t}}import{z as Mt}from"zod";var mn=n=>typeof n=="function",Rt=n=>{if(typeof n!="object"||n===null)return!1;let e=n;return["unavailable","validate","pin","subscribe"].every(t=>mn(e[t]))},At=Mt.custom(n=>Rt(n)&&mn(n.owed)&&Array.isArray(n.requires),{error:"Expected a check provider binding"}),Nt=Mt.custom(n=>Rt(n)&&mn(n.acquire),{error:"Expected an evidence provider binding"}),De=class{disposed=new Set;inFlight=new Set;drained=new AbortController;bindings;constructor(e){this.bindings=e}watch(e){let t=["check","evidence"].flatMap(i=>Object.entries(this.table(i)).map(([s,r])=>r.subscribe(o=>{o==="disposed"&&this.dispose(ye(i,s)),e(i,s,o)})));return()=>{for(let i of t)i()}}problem(e,t,i){let s=this.table(e)[t],r=`${e} provider ${t}`;if(s===void 0)return`${r} is not bound`;if(this.disposed.has(ye(e,t)))return`${r} was disposed`;if(i===void 0)return`the instance recorded no pin for ${r}`;let o=s.validate(i.config);if(o!==null)return`${r} refuses the instance's pin: ${o}`;let c=s.unavailable();return c===null?null:`${r} is unavailable: ${c}`}async pin(e,t,i,s){let r=this.table(e)[t];if(r===void 0)return{refused:`${e} provider ${t} is not bound`};if(this.disposed.has(ye(e,t)))return{refused:`${e} provider ${t} was disposed`};let o=r.unavailable();if(o!==null)return{refused:`${e} provider ${t} is unavailable: ${o}`};let c;try{c=await this.tracked(ye(e,t),s,a=>r.pin(i,a))}catch(a){if(a instanceof K)throw a;c={refused:a instanceof Error?a.message:String(a)}}return"refused"in c?{refused:`${e} provider ${t} refuses this opening: ${c.refused}`}:{config:c.config}}async acquire(e,t,i){let s=this.problem("evidence",e,t);if(s!==null)return{kind:"unavailable",reason:s};let r=this.bindings.evidence[e];try{return await this.tracked(ye("evidence",e),i.signal,o=>r.acquire({...i,config:t.config,signal:o}))}catch(o){if(o instanceof K)throw o;return{kind:"unavailable",reason:o instanceof Error?o.message:String(o)}}}async drain(){this.drained.abort(new Error("The workflows plugin is unloading")),await Promise.allSettled([...this.inFlight].map(({done:e})=>e))}table(e){return e==="check"?this.bindings.checks:this.bindings.evidence}dispose(e){this.disposed.add(e);for(let t of this.inFlight)t.key===e&&t.controller.abort(new Error(`Provider ${e} was disposed`))}async tracked(e,t,i){let s=new AbortController,r=AbortSignal.any([t,s.signal,this.drained.signal]);if(r.aborted)throw new K(r.reason);let o=i(r),c={key:e,controller:s,done:o};this.inFlight.add(c),o.then(()=>this.inFlight.delete(c),()=>this.inFlight.delete(c));try{return await Promise.race([o,Di(r)])}catch(a){throw r.aborted?new K(r.reason):a}}},K=class extends Error{constructor(e){super(`Cancelled: ${e instanceof Error?e.message:String(e)}`,{cause:e}),this.name="CancelledError"}},ye=(n,e)=>`${n}:${e}`,Di=n=>new Promise((e,t)=>{n.aborted?t(n.reason):n.addEventListener("abort",()=>t(n.reason),{once:!0})});import{z as gn}from"zod";function Fi(n,e,t){let{draining:i,unresolved:s}=ke(n,t,We(n.journal.origins,t,e.root));return[...i,...s]}var zi=gn.strictObject({assignmentId:gn.string().min(1).describe("The id of the assignment this output answers, as it was presented."),output:N.describe("The assignment's output, matching the JSON Schema it was presented with.")});function Ui(n,e){return _n({name:P,description:"Submit the output of your active workflow assignment. A valid submission ends your turn as your answer; it is accepted when that answer is.",parameters:zi,onInterrupted:"rerun",executionMode:"exclusive",execute:async({assignmentId:t,output:i},{threadId:s,callSeq:r})=>{let o=h=>({output:`Not submitted: ${h}`,is_error:!0}),c=ce(n,s);if(c===void 0||"unreadable"in c||!_(c.state))return o("no workflow assignment of yours is active.");let a=fn(c,e,r);if(a.kind!=="assignment")return o(`${a.why}.`);let{assignment:u}=a;if(u.thread!==s)return o(`only the participant working ${u.id} may submit it.`);if(u.id!==t)return o(`your active assignment is ${u.id}, not ${JSON.stringify(t)}.`);let d=Fi(n,c,s);if(d.length>0)return o(`work you started has not ended: ${d.join("; ")}. Wait for it to end, or stop it, then submit again.`);let{state:f}=c,l=e.executable(f),g=f.current.entered.step,p=Ne(l,{step:g,participant:u.participant}).safeParse(i);return p.success?{output:`Submitted the output of assignment ${u.id}. It is accepted when this answer is.`,metadata:zn({assignment:u.id,output:i}),concludes_turn:!0}:o(`the output does not match the assignment's schema: ${gn.prettifyError(p.error)}`)}})}function Ji(n,e,t,i){if(!_(n))return;let s=t.executable(n);if(s===void 0||R(n,s)!==null)return;if(e.kind==="root"){let c=B(n),a=c===void 0?null:Xn(n,c);return c===void 0||a===null?void 0:{assignment:c,epoch:a,submitted:c.candidate?.seq===i,reminded:c.reminded}}if(e.kind!=="participant")return;let{facts:r}=e,o=X(n,e.thread,r,void 0);if(!(o===void 0||o.state==="accepted"||o.state==="superseded")&&n.current.assignments.includes(o))return{assignment:o,epoch:r.claims.get(o.task),submitted:r.submissions.get(i)?.assignment===o.id,reminded:r.reminded.get(o.id)??null}}function Bi(n,e){let t=(i,s)=>{let r=ce(n,i);if(r===void 0||"unreadable"in r)return null;let o=Ji(r.state,r,e,s);return o===void 0?null:{kind:r.kind,assignment:o.assignment.id,epoch:o.epoch,submitted:o.submitted,reminded:o.reminded}};n.on("lagent/turn/stop",({threadId:i,answer:s,observe:r})=>{r(()=>JSON.stringify(t(i,s.seq)));let o=t(i,s.seq);if(o===null||o.submitted)return;let{assignment:c,epoch:a}=o;if(o.reminded===a)return o.kind==="root"?void 0:G.rejection(`Assignment ${c} was answered without its submission after the one reminder, so its task fails and the workflow's recovery decides what comes next.`,{assignment:c,epoch:a});let u=o.kind==="root"?"If you need the user first, reply again saying what you need; the assignment stays open until you submit.":"Another reply without a submission fails your task.";return{decision:"continue",message:G.contribution({content:`Your workflow assignment ${c} is still open, and a reply does not finish it: submit its output with ${P} ({ "assignmentId": "${c}", "output": ... }), matching the schema it was presented with. ${u}`},{assignment:c,epoch:a})}})}function Ct(n,e){En(n,Ui(n,e)),Bi(n,e)}function It(n,e,t){let i=n.opened;if(i===null)throw new Error("No workflow instance was opened on this thread");let s=me(he(n),e),r=s===null?e:void 0,o=r??i.canonical,c=se(n),a=[...n.results.values()].map(b=>({revision:b.revision,step:b.step,outputs:b.outputs,decision:qe(n,b.decision),current:!c.has(b.revision),inputs:Object.fromEntries(Object.entries(n.attempts.get(b.attempt).entered.inputs).map(([j,S])=>[j,xe(S)]))})),u=i.input,d=Object.fromEntries(Object.entries(i.pins.participants).flatMap(([b,{configuration:j}])=>j===null?[]:[[b,{provider:j.route.provider,model:j.route.model,thinkingEffort:j.route.thinking_effort}]]));if(n.terminal!==null)return{definition:i.definition,input:u,models:d,status:n.terminal.kind,step:null,attempt:null,assignments:[],results:a,pending:null,blocked:null,waitingOn:null};let f=n.current,l=R(n,o),g={definition:i.definition,input:u,models:d,step:f?.entered.step??null,attempt:f===null?null:{id:f.entered.attempt,ordinal:f.entered.ordinal},assignments:(f?.assignments??[]).map(({id:b,participant:j,state:S,thread:A,task:D,generation:C})=>({id:b,participant:j,state:S,thread:A,task:D,generation:C})),results:a};if(n.cancellation!==null){let{unresolved:b}=t.barrier.cleanup;return b.length>0?{...g,status:"blocked",pending:null,blocked:{reason:"cleanup",detail:b.join("; ")},waitingOn:"cleanup"}:{...g,status:"running",pending:null,blocked:null,waitingOn:"cleanup"}}if(r===void 0)return{...g,status:"blocked",pending:l===null?null:Wt(l),blocked:{reason:"missing-binding",detail:s},waitingOn:null};let p=[...t.starts.values()].flatMap(b=>b.kind==="hold"?[b.reason]:[]),h=[...Ki(n,r,t),...p];if(h.length>0)return{...g,status:"blocked",pending:l===null?null:Wt(l),blocked:{reason:"missing-binding",detail:h.join("; ")},waitingOn:null};if(l!==null){let b=cn(l,t.barrier);if(!b.actions.cleanupPending)return{...g,status:"waiting",pending:b,blocked:null,waitingOn:"decision"};let{unresolved:j}=t.barrier.cleanup;return j.length>0?{...g,status:"blocked",pending:b,blocked:{reason:"cleanup",detail:j.join("; ")},waitingOn:"cleanup"}:{...g,status:"waiting",pending:b,blocked:null,waitingOn:"cleanup"}}let w=Z(n,r),k=w.kind==="refused"?w.reason:w.kind==="needs"&&t.entryRefusal?.transition===w.needs.transition?t.entryRefusal.reason:null;if(k!==null)return{...g,status:"blocked",pending:null,blocked:{reason:"entry-refused",detail:k},waitingOn:null};let O=[...t.starts.values()],v=t.settled&&B(n)!==void 0?"person-input":O.some(({kind:b})=>b==="starting"||b==="wait")?"dispatch":O.length>0?"participant":null;return{...g,status:"running",pending:null,blocked:null,waitingOn:v}}function Ki(n,e,t){let i=[],s=n.current;if(s!==null){for(let{participant:c,checks:a,state:u}of s.assignments)if(!(u==="accepted"||u==="superseded"))for(let d of a){let f=t.provider({check:d,participant:c});f!==null&&i.push(f)}}let r=Z(n,e);if(r.kind==="needs")for(let{provider:c}of r.needs.inputs){let a=t.provider({evidence:c});a!==null&&i.push(a)}let o=r.kind==="needs"?r.needs.step:r.kind==="transition"&&r.row.op==="entered"?r.row.step:null;for(let{participant:c,checks:a}of o===null?[]:e.steps[o].assignments)for(let u of a){let d=t.provider({check:u,participant:c});d!==null&&i.push(d)}return[...new Set(i)]}var Wt=n=>({...n,actions:{...n.actions,verdicts:[],options:[],restart:{retry:{required:[],allowed:[]},options:{}}}});var Hi=y.strictObject({definitions:y.array(y.custom(at,{error:"Expected a definition made by defineWorkflow"})),restrictions:y.record(y.string().min(1),ln),coordination:ln,prerequisites:y.record(y.string().min(1),y.custom(n=>typeof n=="function",{error:"Expected a prerequisite check"})),roles:y.record(y.string().min(1),y.custom(n=>typeof n=="function",{error:"Expected a role binding"})),modelProviders:y.array(y.string().min(1)),checks:y.record(y.string().min(1),At),evidence:y.record(y.string().min(1),Nt)}),I=y.string().min(1),Qi=y.strictObject({id:I,inputId:I,definition:I,input:N,conversation:y.strictObject({environment:y.strictObject({cwd:y.string(),read_roots:y.array(y.string())}),installations:y.array(y.custom())}),models:y.record(I,y.strictObject({provider:I,model:I,thinkingEffort:Oe.nullable()})).optional(),signal:y.instanceof(AbortSignal).optional()}),Yi=y.strictObject({operationId:I,instanceId:I,decision:I,verdict:y.enum(["approve","revise"]),option:I.optional(),feedback:y.string().optional(),restart:y.array(I).optional()}),Gi=y.strictObject({operationId:I,instanceId:I,reason:y.string()}),Zi=3,$e=class extends Error{constructor(e){super(`The workflow changed while its Stop was prepared: ${e}`),this.name="StaleStopError"}},E=class extends Error{constructor(e){super(e),this.name="WorkflowRefusedError"}},Xi=3,Pt="stale-wake",Lt="A workflow opens only on a new root conversation, never on a fork or a delegated thread",es=3,wn=new AbortController().signal,ve="The workflow instance could not be repaired",Fe=Tn({key:"workflow",version:1,schema:y.strictObject({references:y.strictObject({id:y.string(),step:y.string().nullable(),participants:y.record(y.string(),y.strictObject({context:y.enum(["conversation","isolated"]),open:y.boolean()}))}),terminal:y.boolean(),checks:y.array(y.strictObject({thread:y.string(),check:y.string(),pin:y.strictObject({config:N}).nullable()})),runnable:y.array(y.string())}).nullable(),applies:z,compute(n,e){let t=n.state(q,e);return t.opened===null?null:{references:he(t),terminal:t.terminal!==null,checks:ts(t),runnable:t.cancellation===null?Tt(t):[]}}}),ze=class extends Vi{static inject=["threads","journal","tools","presets"];config;registered;entries;cleanups=new Map;cancelling=new Set;unrepaired=new Map;sends=new Set;passes=new Map;closing=!1;repairing=!1;participants;refreshed=Promise.resolve([]);providers;constraint;entryRefusals=new Map;constructor(e,t){super(e,"workflows"),this.config=Hi.parse(t);let{definitions:i,restrictions:s,prerequisites:r,roles:o,checks:c,evidence:a}=this.config,u={restrictions:new Set(Object.keys(s)),prerequisites:new Set(Object.keys(r)),roles:new Set(Object.keys(o)),checks:new Set(Object.keys(c)),evidence:new Set(Object.keys(a))};this.providers=new De({checks:c,evidence:a});let d=e.get("delegations")!==void 0,f=new Map;for(let p of i){let h=p.id;if(f.has(h))throw new J(h,["its id is registered twice"]);let w=dt(p,u);if(Object.values(p.participants).some(({context:O})=>O==="isolated")&&!d&&w.push("isolated participants run as delegation tasks: mount delegations before workflows"),w.length>0)throw new J(h,w);f.set(h,p)}this.registered=f;let l=Object.freeze([...this.config.modelProviders]);this.entries=ue([...f.values()].map(({id:p,input:h,participants:w})=>({id:p,input:h,participants:Object.fromEntries(Object.entries(w).flatMap(([k,O])=>O.context==="isolated"?[[k,{provider:O.model.provider,model:O.model.model,thinkingEffort:O.model.thinkingEffort??null,configurable:O.model.configurable}]]:[])),modelProviders:l}))),this.participants=new Le(e,{providers:this.providers,checks:c,executable:p=>this.executable(p),runnable:p=>this.runnable(p),quarantined:p=>this.quarantined(p),reconcile:p=>this.track(this.reconcile(p)),ended:(p,h)=>{(h||this.cancelling.has(p))&&this.track(this.reconcile(p))},refused:(p,h,w)=>this.refused(p,h,w)}),e.effect(()=>e.journal.register(q));let g={restrictions:s,coordination:this.config.coordination,executable:p=>this.executable(p)};_t(e,g),jt(e,g),Ct(e,g),this.refreshed=Fe.register(e).refreshed,e.effect(()=>e.journal.subscribe(p=>this.onRow(p))),e.effect(()=>e.threads.onRunEvent(({threadId:p})=>{this.cancelling.has(p)&&this.track(this.holding(p,()=>this.finishCleanup(p)))})),e.effect(()=>{let p=e.threads.registerOwner({owner:T,constraint:{applies:h=>this.governs(h),evaluate:h=>this.evaluate(h)},repair:()=>this.repair()});return this.constraint=p,()=>{this.constraint=void 0,p.dispose()}}),e.effect(()=>this.providers.watch(()=>this.providerChanged())),e.effect(()=>this.participants.register()),Sn(e,()=>this.shutdown())}catalog(){return this.entries}definition(e){return this.registered.get(e)}async opening(e){let t=Qi.parse(e),{id:i,inputId:s,definition:r,input:o,models:c={},signal:a=wn}=t,u=this.definition(r);if(u===void 0)throw new E(`No workflow ${r} is registered`);let d=Ne(u,"$input").safeParse(o);if(!d.success)throw new E(`The input does not match the workflow's input schema: ${y.prettifyError(d.error)}`);let f=this.proposed(t.conversation),l=await this.pins(u,f,c,a),g=Dn(u,o,s,l),p={...q.init(),instance:i,opened:g},{plan:h}=await this.withEvidence(i,l,k=>{let O=Me(p,u,{instance:i,step:u.entry,cause:{kind:"opening"},activation:s,...k===void 0?{}:{evidence:k}});return"needs"in O?{kind:"needs",needs:O.needs}:"refused"in O?{kind:"refused",reason:O.refused}:{kind:"row",...O}},a);if(h.kind==="refused")throw new E(`The entry step cannot be entered: ${h.reason}`);let w=[g,h.row];return k=>{if(k.kind==="send")throw new Error("Workflow opening rows only open a thread");let{threadId:O}=k,v=k.kind==="fork"?Lt:this.openingRefusal(u,{instance:i,inputId:s,conversation:f},k)??this.pinsProblem(l);return v!==null?{refuse:{message:v}}:w.map(b=>L.entry(b,{threadId:O}))}}proposed(e){try{let t=this.ctx.presets.installationsFor(e.installations,"creation").map(({preset_id:i,config:s},r)=>({preset_id:i,config:s,lifetime:e.installations[r].lifetime}));return{environment:bn(e.environment),installations:t}}catch(t){throw new E(`The proposed conversation is refused: ${de(t)}`)}}async pins(e,t,i,s){for(let[a,u]of Object.entries(i)){let d=e.participants[a];if(d===void 0)throw new E(`The workflow has no participant ${a}`);if(d.context==="conversation")throw new E(`Participant ${a} runs on the conversation's route: it takes no model choice (${u.provider}/${u.model})`);if(!d.model.configurable)throw new E(`Participant ${a} runs on the model its workflow fixes`)}let r=async(a,u,d,f)=>{let l=await this.providers.pin(a,u,d,s);if("refused"in l)throw new E(`${f}: ${l.refused}`);return l},o={};for(let[a,u]of Object.entries(e.participants)){let d=u.context==="isolated"?this.configuration(a,u,t,i[a]):null,f=d===null?t:{environment:d.environment,installations:d.installations.map(({preset_id:g,config:p,lifetime:h})=>({preset_id:g,config:p,lifetime:h}))},l={};for(let g of Object.values(e.steps))for(let p of g.assignments)if(p.participant===a)for(let h of p.checks)l[h]??=await r("check",h,f,`Participant ${a}`);o[a]={configuration:d,checks:l}}let c={};for(let a of Object.values(e.steps))for(let u of Object.values(a.inputs))"evidence"in u&&(c[u.evidence]??=await r("evidence",u.evidence,t,"Evidence"));return{participants:o,evidence:c}}configuration(e,t,i,s){let r=u=>{throw new E(`Participant ${e}: ${u}`)},{model:o}=t,c=s===void 0?{provider:o.provider,model:o.model,thinking_effort:o.thinkingEffort??null}:{provider:s.provider,model:s.model,thinking_effort:s.thinkingEffort};this.config.modelProviders.includes(c.provider)||r(`model provider ${c.provider} is not offered by the host`);let a=this.config.roles[t.role](i);if("refused"in a)return r(`role ${t.role} refuses this conversation: ${a.refused}`);for(let u of a.installations)(u.lifetime!=="defining"||u.installationId===void 0)&&r(`role ${t.role}'s installation of ${u.presetId} must be defining and name its id`);try{return{agent:a.agent,route:c,environment:bn(a.environment),installations:this.ctx.presets.initialInstallations(a.installations,a.agent)}}catch(u){return r(`role ${t.role} resolves a configuration that is refused: ${de(u)}`)}}openingRefusal(e,t,i){let{threadId:s,runId:r,inputId:o,opening:c}=i;if(s!==t.instance)return`The workflow opens on thread ${t.instance}, not ${s}`;if(c.origin!==null)return Lt;let{spec:a}=c;if(!a.requires.includes(T))return`The conversation must require ${T}`;if(o!==t.inputId)return`The conversation's first input must be ${t.inputId}`;let u=e.steps[e.entry].assignments.some(({participant:f})=>e.participants[f]?.context==="conversation");if(u&&r===null)return"The conversation's creation must wake it: its entry step is its own";if(!u&&r!==null)return"The conversation's creation must not wake it: its entry step is not its own, and nothing runs it merely to start participants";let d={environment:bn(a.environment),installations:a.installations.map(({preset_id:f,config:l,lifetime:g})=>({preset_id:f,config:l,lifetime:g}))};if(U(d)!==U(t.conversation))return"The conversation is not created as the workflow's opening was prepared for: its environment or installations differ";for(let f of e.prerequisites){let l=this.config.prerequisites[f](c);if(l!==null)return`Prerequisite ${f} is not met: ${l}`}return null}read(e){return this.view(e)}decide(e,t){let i=Yi.parse(e),{instanceId:s}=i,r={operationId:i.operationId,decision:i.decision,verdict:i.verdict,option:i.option??null,feedback:i.feedback??null,restart:i.restart??[],actor:t};return this.retaining(this.subtree(s),async()=>{this.refuseQuarantined(s);for(let o=0;o<Xi;o+=1){let{plan:c,evidence:a}=await this.prepareDecision(s,r);if(c.kind==="replay")return this.view(s);if(c.kind==="refused")throw new E(c.reason);let[u,d]=c.rows,f=this.transition(s,d,u),l=w=>f.rootWork||On(this.ctx.journal.state(ne,w).requests),g=l(s)?{releases:!0,chain:"person"}:void 0,p=await this.send(s,f,g,({threadId:w,runId:k})=>{let O=this.quarantined(w);if(O!==null)return{refuse:{message:`${ve}: ${O}`}};let v=this.planDecision(w,r,a);if(v.kind!=="rows")return{refuse:{message:v.kind==="refused"?v.reason:"already recorded"}};let b=this.entryProblem(w,v.rows);return b!==null?{refuse:{message:`the selected step cannot be entered: ${b}`}}:U(v.rows)!==U(c.rows)?{refuse:{message:"The instance changed while the decision was written: decide again"}}:l(w)!==(k!==null)?{refuse:{message:"A Stop changed while the decision was written",code:Pt}}:v.rows.map(j=>L.entry(j,{threadId:w}))});if(p.status==="queued")return this.view(s);if(p.status==="refused"&&p.refusal.code===Pt)continue;this.refuseQuarantined(s);let h=this.planDecision(s,r,a);if(h.kind==="replay")return this.view(s);throw h.kind==="refused"?new E(h.reason):new E(p.status==="refused"?p.refusal.message:`The input of decision ${r.decision} was already sent`)}throw new E("The conversation was stopped and resumed while deciding: decide again")})}cancel(e,t){let{operationId:i,instanceId:s,reason:r}=Gi.parse(e);return this.holding(s,async()=>{this.refuseQuarantined(s);let{value:o}=await this.ctx.journal.transact(s,()=>{let c=this.quarantined(s);if(c!==null)return{rows:[],value:`${ve}: ${c}`};let a=mt(this.state(s),{operationId:i,reason:r,actor:t});return{rows:a.kind==="rows"?a.rows.map(u=>L.entry(u,{threadId:s})):[],value:a.kind==="refused"?a.reason:null}});if(o!==null)throw new E(o);return await this.cleanUp(s),this.view(s)})}async stop(e,t,i){for(let s=0;;s+=1){let r=await this.ctx.threads.retain(()=>[e],{lastRelease:"keep"});try{let o=this.stopping(e),c=await this.ctx.threads.retain(()=>o.children,{lastRelease:"keep"});try{await i(a=>{if(a!==e)throw new Error(`A Stop of thread ${e} was written on ${a}`);return this.stopRows(e,t,o)});return}finally{c.release()}}catch(o){if(!(o instanceof $e)||s+1>=Zi)throw o}finally{r.release()}}}stopping(e){let t=this.ctx.journal.summary(e);if(t===void 0||!z(t)||this.quarantined(e)!==null)return{attempt:null,children:[]};let i=this.ctx.journal.state(q,e),s=V(i).map(({thread:r})=>r).filter(r=>this.ctx.journal.summary(r)!==void 0);return{attempt:i.current?.entered.attempt??null,children:s}}stopRows(e,t,i){let s=this.stopping(e);if(s.attempt!==i.attempt)throw new $e(`it met attempt ${s.attempt}`);let r=s.children.filter(a=>!this.ctx.journal.isLoaded(a));if(r.length>0)throw new $e(`${r.join(", ")} not loaded`);if(s.attempt===null||this.quarantined(e)!==null)return[];let o=this.ctx.journal.state(q,e),c=kt(this.ctx.journal,o,this.procedure(o),t);return c===null?[]:[L.entry(c,{threadId:e})]}state(e){let t=this.ctx.journal.state(q,e);if(t.opened===null)throw new E(`No workflow instance is open on thread ${e}`);return t}view(e){let t=this.state(e),{state:i}=this.ctx.threads.inspect(e,{basis:"catalog"}),{pins:s}=t.opened,r=It(t,this.definition(t.opened.definition),{barrier:this.barrier(e,t),starts:this.participants.states(e,t),settled:i==="idle"||i==="held",provider:o=>"check"in o?this.providers.problem("check",o.check,s.participants[o.participant]?.checks[o.check]):this.providers.problem("evidence",o.evidence,s.evidence[o.evidence]),entryRefusal:this.entryRefusals.get(e)??null});return ue(structuredClone(r))}barrier(e,t){return xt(this.ctx,t,this.participants.starting(e))}executable(e){return it(e,this.definition(e.opened.definition))}procedure(e){return this.executable(e)??e.opened.canonical}planDecision(e,t,i){let s=this.state(e);return ht(s,this.executable(s),t,this.barrier(e,s),i)}async prepareDecision(e,t){try{return await this.withEvidence(e,this.state(e).opened.pins,i=>this.planDecision(e,t,i),wn)}catch(i){throw i instanceof K?new E(`The decision's evidence: ${i.message}`):i}}owed(e,t){let i=this.ctx.journal.state(q,e);if(i.opened===null)return{kind:"none"};let s=this.executable(i);return s===void 0?{kind:"none"}:Z(i,s,t)}async advance(e){let t;try{let u=this.ctx.journal.state(q,e);if(u.opened===null)return;t=await this.withEvidence(e,u.opened.pins,d=>this.owed(e,d),wn)}catch(u){if(u instanceof K||u instanceof E)return;throw u}let{plan:i,evidence:s}=t;if(i.kind==="none")return;if(i.kind==="refused"){s!==void 0&&this.entryRefusals.set(e,{transition:s.transition,reason:i.reason});return}let{row:r}=i,o=this.transition(e,r,null),c=o.rootWork?{releases:!1,chain:"fresh"}:void 0,a=await this.send(e,o,c,()=>{let u=this.quarantined(e);if(u!==null)return{refuse:{message:`${ve}: ${u}`}};let d=this.owed(e,s);if(d.kind!=="transition"||U(d.row)!==U(r))return{refuse:{message:"The transition is no longer owed"}};let f=this.entryProblem(e,[r]);return f!==null?{refuse:{message:f}}:[L.entry(r,{threadId:e})]});a.status==="refused"&&this.entryRefusals.set(e,{transition:r.transition,reason:a.refusal.message})}entryProblem(e,t){let i=this.state(e),{pins:s}=i.opened,r=this.procedure(i);for(let o of t){if(o.op!=="entered")continue;let c=r.steps[o.step];for(let a of Object.values(c?.inputs??{})){if(!("evidence"in a))continue;let u=this.providers.problem("evidence",a.evidence,s.evidence[a.evidence]);if(u!==null)return u}for(let a of o.assignments){let{participant:u}=a;for(let d of a.context==="isolated"?a.checks:[]){let f=this.providers.problem("check",d,s.participants[u]?.checks[d]);if(f!==null)return f}}}return null}pinsProblem(e){for(let{checks:t}of Object.values(e.participants))for(let[i,s]of Object.entries(t)){let r=this.providers.problem("check",i,s);if(r!==null)return r}for(let[t,i]of Object.entries(e.evidence)){let s=this.providers.problem("evidence",t,i);if(s!==null)return s}return null}async withEvidence(e,t,i,s){let r;for(let o=0;o<es;o+=1){let c=i(r);if(c.kind!=="needs")return{plan:c,evidence:r};let{needs:a}=c,u=await Promise.all(a.inputs.map(async({input:d,provider:f})=>[d,await this.providers.acquire(f,t.evidence[f],{instance:e,attempt:a.attempt,step:a.step,input:d,signal:s})]));r={transition:a.transition,attempt:a.attempt,inputs:new Map(u)}}throw new E("The instance moved on each time its entry evidence was acquired: try again")}send(e,t,i,s){let r=this.ctx.threads.get(e);if(r===void 0)throw new Error(`Unknown thread: ${e}`);let{input:o}=t;return r.send(o.message,{id:o.id,source:o.source,target:"next-turn",...i===void 0?{}:{wake:i},rows:s})}transition(e,t,i){let s=this.state(e),r=this.executable(s),o=t.op==="entered"?t.assignments.find(({participant:d})=>r.participants[d]?.context==="conversation"):void 0,c=i===null?void 0:s.attempts.get(i.attempt)?.entered.step,a=[`Workflow ${r.id}:`];if(i!==null){let d=i.option===null?"":` (${i.option})`,f=i.feedback===null?"":`, with this feedback: ${i.feedback}`;a.push(`step ${c} ${Pe(i.verdict)}${d}${f}.`)}t.op==="completed"?a.push("The workflow is complete; this conversation goes on as ordinary chat."):o!==void 0?a.push(`Step ${t.step} is now yours, as assignment ${o.id}; its instructions come with your next step.`):t.assignments.length===0?a.push(`Step ${t.step} now waits for a decision.`):a.push(`Step ${t.step} is being worked by other participants.`);let u=Ee(t.transition);return{row:t,input:{id:u,message:{role:"developer",content:a.join(" ")},source:Vn.record({transition:t.transition,assignment:o?.id??null,decision:i?.decision??null})},rootWork:o!==void 0}}cleanUp(e){let t=this.cleanups.get(e);if(t!==void 0)return t;this.cancelling.add(e);let i=this.runCleanup(e).finally(()=>this.cleanups.delete(e));return this.cleanups.set(e,i),i}async runCleanup(e){if(this.quarantined(e)!==null)return;let{cancellation:t,terminal:i}=this.state(e);if(t===null||i!==null)return;let s=this.ctx.threads.get(e),r=`The workflow was cancelled: ${t.reason}`,o=this.ctx.get("delegations");await s.cancel(r,{intent:"cleanup",...o===void 0?{}:{rows:o.stopObligationRows(r)}}),await o?.retryStops(e);let c=this.ctx.get("commands");if(c!==void 0){let a=this.ctx.journal.origins.subtree(e,{self:!0});await Promise.all(a.map(({thread_id:u})=>c.stopAll({threadId:u},"its workflow was cancelled")))}await this.ctx.journal.flush(),await this.finishCleanup(e)}async finishCleanup(e){await this.ctx.journal.transact(e,()=>{let t={rows:[],value:void 0};if(this.quarantined(e)!==null)return t;let i=this.state(e);if(i.terminal!==null||i.cancellation===null)return this.cancelling.delete(e),t;let{state:s,operation:r}=this.ctx.threads.inspect(e,{basis:"catalog"});if(s!=="idle"&&s!=="held"||r!==null)return t;let{draining:o,unresolved:c}=this.barrier(e,i).cleanup;return o.length>0||c.length>0?t:{rows:[L.entry({op:"cancelled",operation_id:i.cancellation.operation_id},{threadId:e})],value:void 0}})}governs(e){if(z(e))return!0;if(e.origin===null)return!1;let t=this.ctx.journal.origins.callers(e.thread_id).threads.at(-1);return t!==void 0&&t.origin===null&&z(t)}evaluate(e){let t=this.ctx.journal.origins.callers(e).threads,i=t.at(-1),s=i===void 0?null:this.quarantined(i.thread_id);if(s!==null)return{kind:"hold",reason:`${ve}: ${s}`};let r=i===void 0?void 0:Fe.read(this.ctx.journal,i.thread_id);if(r?.status!=="available")return{kind:"hold",reason:`Its workflow instance is unreadable: ${r?.status==="unavailable"?r.reason:"its instance state has not been computed"}`};let o=r.value;if(o===null)return{kind:"allow"};if(o.terminal)return{kind:"allow"};let{references:c}=o,a=this.definition(c.id),u=me(c,a);if(u!==null)return{kind:"hold",reason:`Its workflow cannot continue: ${u}`};let d=t.find(({origin:f})=>ae(f,i.thread_id))?.thread_id??i.thread_id;for(let{thread:f,check:l,pin:g}of o.checks){if(f!==d)continue;let p=this.providers.problem("check",l,g??void 0);if(p!==null)return{kind:"hold",reason:`Its workflow's ${p}`}}return{kind:"allow"}}governedChanged(e){for(let{thread_id:t}of this.ctx.journal.origins.subtree(e,{self:!0}))this.constraint?.changed(t),this.participants.changed(t)}runnable(e){let t=Fe.read(this.ctx.journal,e);if(t.status==="unavailable")return{unavailable:t.reason};if(t.status==="not-applicable")return{unavailable:"its instance state has not been computed"};let i=t.value;return i===null?{unavailable:"no instance is open on it"}:i.terminal?"allow-all":i.runnable}providerChanged(){let e=new Set(this.entryRefusals.keys());this.entryRefusals.clear();for(let t of this.ctx.journal.summaries()){let i=Fe.read(this.ctx.journal,t.thread_id);if(i.status!=="available")continue;let s=i.value;s!==null&&s.checks.length>0&&(this.governedChanged(t.thread_id),e.add(t.thread_id)),this.ctx.journal.isLoaded(t.thread_id)&&this.participants.held(t.thread_id)&&e.add(t.thread_id)}for(let t of e)this.track(this.reconcile(t))}onRow(e){let t=this.ctx.journal.summary(e.thread_id);if(t===void 0||(z(t)&&t.origin===null&&(e.type==="ext"&&this.governedChanged(e.thread_id),(L.read(e)!==void 0||e.type==="turn/end")&&this.track(this.reconcile(e.thread_id))),!ns.has(e.type)))return;let i=this.ctx.journal.origins.callers(e.thread_id).threads.at(-1),s=i?.thread_id;s===void 0||!z(i)||(this.cancelling.has(s)?this.track(this.holding(s,()=>this.finishCleanup(s))):s!==e.thread_id&&this.ctx.journal.isLoaded(s)&&this.participants.waiting(s)&&this.track(this.reconcile(s)))}reconcile(e){if(this.closing||!this.repairing||this.quarantined(e)!==null)return Promise.resolve();let t=this.passes.get(e);if(t!==void 0)return t.again=!0,t.done;let i={again:!0,done:Promise.resolve()};return i.done=(async()=>{try{for(;i.again&&!this.closing;)i.again=!1,await this.holding(e,async()=>{let s=this.ctx.journal.state(q,e);if(!(s.opened===null||s.terminal!==null)){if(s.cancellation!==null){this.cancelling.has(e)&&await this.finishCleanup(e);return}await this.observe(e),await this.advance(e),this.participants.dispatch(e)}})}finally{this.passes.delete(e)}})(),this.passes.set(e,i),i.done}async refused(e,t,i){await this.retaining(this.subtree(e),()=>this.ctx.journal.transact(e,()=>{let s={rows:[],value:void 0};if(this.quarantined(e)!==null)return s;let r=this.state(e),o=bt(this.ctx.journal,r,t,i);if(o===null)return s;let c=o.observations[0].thread;return this.ctx.journal.summary(c)!==void 0&&this.ctx.get("delegations")?.continuation(c)?.kind!=="refusal"?s:{rows:[L.entry(o,{threadId:e}),...pn(this.ctx,r,o)],value:void 0}}))}async observe(e){let t=this.ctx.journal.state(q,e),i=[...new Set(V(t).map(({thread:r})=>r))].filter(r=>this.ctx.journal.summary(r)!==void 0);if(i.length===0)return;let s=await this.ctx.threads.retain(()=>i,{lastRelease:"keep"});try{await this.ctx.journal.transact(e,()=>{if(this.quarantined(e)!==null)return{rows:[],value:void 0};let r=this.state(e);return{rows:wt(this.ctx.journal,r).flatMap(c=>[L.entry(c,{threadId:e}),...pn(this.ctx,r,c)]),value:void 0}})}finally{s.release()}}track(e){let t=e.catch(i=>this.ctx.reportError(i)).finally(()=>this.sends.delete(t));this.sends.add(t)}async repair(){for(let t of await this.refreshed.catch(()=>[]))this.ctx.reportError(new Error(`The workflow instance of thread ${t} could not be read into the catalog`));this.repairing=!0;let e=this.ctx.journal.summaries().filter(t=>z(t)&&t.origin===null).map(t=>t.thread_id);for(let t of e)try{await(await this.holding(t,()=>{let s=this.ctx.journal.state(q,t);return s.opened!==null&&s.terminal===null&&s.cancellation!==null})?this.holding(t,()=>this.cleanUp(t)):this.reconcile(t))}catch(i){let s=jn(i);this.unrepaired.set(t,s),this.ctx.reportError(new Error(`The workflow instance of thread ${t} could not be repaired: ${s}`,{cause:i})),this.governedChanged(t)}}quarantined(e){return this.unrepaired.get(e)??null}refuseQuarantined(e){let t=this.quarantined(e);if(t!==null)throw new E(`${ve}: ${t}`)}holding(e,t){return this.retaining(()=>[e],t)}async retaining(e,t){let i=await this.ctx.threads.retain(e,{lastRelease:"keep"});try{return await t()}finally{i.release()}}subtree(e){return()=>this.ctx.journal.origins.subtree(e,{self:!0}).map(({thread_id:t})=>t)}async shutdown(){this.closing=!0,await Promise.allSettled([this.providers.drain(),this.participants.shutdown(),...this.sends,...this.cleanups.values(),...[...this.passes.values()].map(({done:e})=>e)])}},ns=new Set(["turn/end","run/settled","thread/cancel","inbox/spliced","ext"]),bn=n=>({cwd:Ve(n.cwd,"A conversation cwd"),read_roots:[...new Set(n.read_roots.map(e=>Ve(e,"A read root")))]});function ts(n){if(!_(n)||n.current===null)return[];let{pins:e}=n.opened;return n.current.assignments.flatMap(({participant:t,thread:i,checks:s,state:r})=>r==="accepted"||r==="superseded"?[]:s.map(o=>{let c=e.participants[t]?.checks[o];return{thread:i,check:o,pin:c===void 0?null:{config:Y(c.config)}}}))}var lo={name:"lagent:workflows",async apply(n,e){xn(n,"workflows"),await n.plugin(ze,e)}};export{P as SUBMIT_TOOL,T as WORKFLOWS_OWNER,J as WorkflowDefinitionError,E as WorkflowRefusedError,li as defineWorkflow,lo as workflows};
@@ -0,0 +1,81 @@
1
+ import { type PluginJournal } from '../../journal/index.js';
2
+ import { type AnswerCheck } from '../../loop/index.js';
3
+ import type { Seq } from '../../models/index.js';
4
+ import { type AssignmentOutcome } from '../delegations/index.js';
5
+ import { type AssignmentView, type InstanceState, type ResponseCalls } from './fold.js';
6
+ import { type InstanceRowInput, type Observation, type Submission } from './record.js';
7
+ import type { CanonicalDefinition } from './definition.js';
8
+ import type { ReadonlyState } from '../../util/foldState.js';
9
+ /**
10
+ * What an isolated participant's child records of its submissions, folded on the child, since the
11
+ * root's fold cannot read a child's rows: every input a step claimed, every submission with the
12
+ * call that made it, each one core accepted as the answer at a completed ending, read with core's
13
+ * own `answerCheck`, as the root reads its own, the latest response's calls, which the response
14
+ * fence orders by, and the submission reminders it was sent. Only a child this plugin's assignments
15
+ * created keeps anything; a fork of one starts over and keeps nothing, since its spawn records no
16
+ * such origin.
17
+ */
18
+ export type ChildFacts = ResponseCalls & {
19
+ /** Whether the thread was created for an assignment of this plugin. */
20
+ managed: boolean;
21
+ /** The row that claimed each input a step took, by input id. */
22
+ readonly claims: Map<string, Seq>;
23
+ /** Each submission, by its `tool/result` row, with the `tool/call` row that made it (`null` when it cites none). */
24
+ readonly submissions: Map<Seq, Submission & {
25
+ readonly call: Seq | null;
26
+ }>;
27
+ /** Each accepted submission's row, with the `turn/end` row whose completed ending accepted it. */
28
+ readonly accepted: Map<Seq, Seq>;
29
+ /** The epoch of the latest submission reminder each assignment was sent, by assignment id. */
30
+ readonly reminded: Map<string, Seq>;
31
+ answer: AnswerCheck;
32
+ };
33
+ export declare const childFacts: import("../../journal/projection.js").PluginProjection<ChildFacts>;
34
+ /**
35
+ * What `assignment`, an isolated one, shows now, from its child's facts and its task's outcome as
36
+ * delegations records it. A submission counts only when it names exactly this assignment and was
37
+ * made after the step that claimed the assignment's task input: the earliest such one accepted at a
38
+ * completed ending is the acceptance, citing both rows and carrying the submitted output. A task
39
+ * delegations settled with no such acceptance `ended` without one, whatever its quoted completion
40
+ * text says; one not settled is `unfinished`. Either carries the latest such submission and the
41
+ * task's latest prose, unaccepted.
42
+ */
43
+ export declare function observationOf(assignment: AssignmentView, facts: ReadonlyState<ChildFacts>, outcome: AssignmentOutcome | null): Observation;
44
+ /**
45
+ * The observation row the root owes now, for a write on it, from the children as loaded: each open
46
+ * isolated assignment of the current attempt that accepted or ended and has no observation yet, and,
47
+ * once one of them ended, what every other one shows as of then, so the recovery it opens freezes
48
+ * every participant's diagnostics at once. A child not loaded, or not created yet, is skipped; one
49
+ * task gets at most one acceptance or ending, the fold keeping the first.
50
+ */
51
+ export declare function observationRows(journal: PluginJournal, state: ReadonlyState<InstanceState>): Extract<InstanceRowInput, {
52
+ op: 'observed';
53
+ }>[];
54
+ /**
55
+ * The observation row recording that delegations refused, for good, to start the task of the open
56
+ * isolated assignment `assignment`, for a write on the root, from the children as loaded: the
57
+ * refusal, beside what every other open isolated assignment shows then, as beside an ending
58
+ * ({@link observationRows}), so the recovery it opens freezes everyone's diagnostics at once.
59
+ * `null` when the assignment no longer waits for its start: it is not open in the current attempt,
60
+ * or its child, which must be loaded when it exists, records its task.
61
+ */
62
+ export declare function refusalRow(journal: PluginJournal, state: ReadonlyState<InstanceState>, assignment: string, detail: string): Extract<InstanceRowInput, {
63
+ op: 'observed';
64
+ }> | null;
65
+ /** The current attempt's open isolated assignments that have no observation yet: whose children ingestion reads. */
66
+ export declare function observable(state: ReadonlyState<InstanceState>): AssignmentView[];
67
+ /**
68
+ * The row a person's Stop of the root writes in its cancel write, decided inside that write from the
69
+ * children as loaded (the host retained them first), or `null` when the Stop leaves the instance as
70
+ * it is: the current attempt, when it is live, unrecovered and has isolated work open or a result
71
+ * whose transition it owes on its own, with what each open isolated assignment's child shows at
72
+ * this boundary. A child that accepted before it is carried as accepted, however far the root's
73
+ * ingestion lags, so acceptance lag never decides the race; one not created yet shows nothing, and
74
+ * its assignment is superseded with the rest. Every child that exists must be loaded: the caller
75
+ * holds them, and refuses the write when one is not. A root-only attempt stays active across a Stop, as core's
76
+ * hold leaves it, and an attempt already recovering, or a pending gate, is left alone. What is
77
+ * pending is read with `definition`, the procedure the instance runs by.
78
+ */
79
+ export declare function stopFact(journal: PluginJournal, state: ReadonlyState<InstanceState>, definition: CanonicalDefinition, reason: string): Extract<InstanceRowInput, {
80
+ op: 'stopped';
81
+ }> | null;
@@ -0,0 +1,143 @@
1
+ import type { Context } from '@leuduan/cordis';
2
+ import type { WorkflowDefinition } from './definition.js';
3
+ import { type InstanceState } from './fold.js';
4
+ import type { CheckProvider, Providers } from './providers.js';
5
+ import type { ReadonlyState } from '../../util/foldState.js';
6
+ /**
7
+ * Where an open isolated assignment's start stands, as the instance's view shows it: its task is
8
+ * recorded on its child (`started`); or not yet, its start in flight or about to be tried
9
+ * (`starting`), waiting for a slot of the origin tree or for its conversation's previous task to
10
+ * end (`wait`), or held while something it runs on cannot serve it (`hold`): a binding unavailable,
11
+ * delegations not mounted, or a pinned configuration its child conflicts with.
12
+ */
13
+ export type StartState = {
14
+ readonly kind: 'started' | 'starting';
15
+ } | {
16
+ readonly kind: 'wait' | 'hold';
17
+ readonly reason: string;
18
+ };
19
+ /** What the starts read and do beside the journal: the service's providers, registration and writes. */
20
+ export type ParticipantsOptions = {
21
+ readonly providers: Providers;
22
+ readonly checks: Readonly<Record<string, CheckProvider>>;
23
+ /** The definition `state` executes by; `undefined` while none it can continue on is registered. */
24
+ readonly executable: (state: ReadonlyState<InstanceState>) => WorkflowDefinition | undefined;
25
+ /**
26
+ * The tasks the root `root` lets run now, as its catalog entry says without loading it
27
+ * ({@link runnableTasks}): `allow-all` once its instance ended, or why it cannot be read.
28
+ */
29
+ readonly runnable: (root: string) => readonly string[] | 'allow-all' | {
30
+ readonly unavailable: string;
31
+ };
32
+ /**
33
+ * Why the repair left `root` held, or `null`: while it says so, no start of `root` is dispatched,
34
+ * and none in flight or running is admitted, so a held instance makes no progress.
35
+ */
36
+ readonly quarantined: (root: string) => string | null;
37
+ /** Asks the service for another reconciliation of `root`: a task of it settled. */
38
+ readonly reconcile: (root: string) => void;
39
+ /**
40
+ * Tells the service a start of `root` ended: `again` when it opened, discarded or refused its
41
+ * task, which changes what is owed; not when it waits or is held, which only a row under the
42
+ * root, a provider's notice or a remount changes, so asking again at once would only spin.
43
+ */
44
+ readonly ended: (root: string, again: boolean) => void;
45
+ /** Records, on the root, delegations' refusal for good of `assignment`'s start: its recovery. */
46
+ readonly refused: (root: string, assignment: string, reason: string) => Promise<void>;
47
+ };
48
+ /**
49
+ * Isolated participants' starts: the workflow as delegations' owner of assignment-origin tasks
50
+ * (`registerOwner`), the only way a participant's task opens, through delegations' one admission,
51
+ * slots and checks. The service's reconciliation asks it, with the root held, to start what the
52
+ * instance owes (`dispatch`): each open isolated assignment of the current attempt whose task its
53
+ * child does not record yet, with no start in flight, while the instance is live, executes its
54
+ * registered definition and owes no decision. A start runs in the background, never awaiting the
55
+ * child's work, and tells the service once it ends. Its typed admission (decision 3 of
56
+ * the slice-2 plan) maps to what the instance shows and does: `opened` starts it, a replay adopting
57
+ * the task an earlier start committed; `wait` (a slot, the conversation's previous task) shows it
58
+ * waiting on dispatch, tried again at the next reconciliation; `hold`, a `conflict` with what the
59
+ * child records, or its own rows `vetoed`, hold it; `discard` means it was superseded, so nothing is
60
+ * owed; a durable `refusal` is recorded on the root, rechecked there, as the assignment's recovery.
61
+ *
62
+ * Its `authorize` is the owner's say inside each write that opens a task and whenever core asks
63
+ * whether a task may run; `settled` asks for a reconciliation of the root, which ingests the child's
64
+ * facts. It owns the starts in flight: the owner's disposal aborts them, and their writes refuse
65
+ * (delegations' `hold`); shutdown joins them, while the journal still takes their rows.
66
+ */
67
+ export declare class Participants {
68
+ private handle;
69
+ private readonly inFlight;
70
+ private readonly running;
71
+ /** The latest admission each open assignment's start got that did not open its task, by root, then assignment. */
72
+ private readonly outcomes;
73
+ /** The conflicts and vetoes reported, so each is reported once. */
74
+ private readonly reported;
75
+ private closing;
76
+ private readonly ctx;
77
+ private readonly options;
78
+ constructor(ctx: Context, options: ParticipantsOptions);
79
+ /**
80
+ * Registers the workflow as delegations' owner of its tasks, until the returned function runs,
81
+ * which withdraws it and aborts the starts in flight. Nothing when delegations is not mounted:
82
+ * every isolated start is then held.
83
+ */
84
+ register(): () => void;
85
+ /** Asks delegations to judge again whether `childId`'s task may run. */
86
+ changed(childId: string): void;
87
+ /** The assignments of `root` whose start is in flight: work a barrier waits for. */
88
+ starting(root: string): string[];
89
+ /** Whether any assignment of `root` waits on a slot or its conversation's previous task, which rows under it may free. */
90
+ waiting(root: string): boolean;
91
+ /** Whether any assignment of `root` is held, which a binding's return may release. */
92
+ held(root: string): boolean;
93
+ /** The outcomes of `root`'s starts, by assignment; created on first use. */
94
+ private of;
95
+ /** Where each open isolated assignment of the current attempt stands, by assignment, for the view. */
96
+ states(root: string, state: ReadonlyState<InstanceState>): ReadonlyMap<string, StartState>;
97
+ /**
98
+ * Starts, in the background, the task of every open isolated assignment the instance on `root`
99
+ * owes one now and has none in flight; with `capacity`, only those whose latest start waited for
100
+ * a slot. The caller holds the root. Outcomes of `root`'s assignments no longer in its current
101
+ * attempt are dropped; other roots' are theirs.
102
+ */
103
+ dispatch(root: string, only?: 'capacity'): void;
104
+ /** Tries again, with the root held, the starts of `root` that waited for a slot, if any. */
105
+ private retryCapacity;
106
+ /** Lets the starts in flight land, starting no more. */
107
+ shutdown(): Promise<void>;
108
+ /**
109
+ * The open isolated assignments of the current attempt whose task their child does not record:
110
+ * none while the instance is not live, held off its definition, or a decision pending,
111
+ * which freezes starting.
112
+ */
113
+ private owed;
114
+ /** One start, with the root held so the writes it makes read the instance: its admission, and what that makes owed. */
115
+ private start;
116
+ /** What an admission, but a refusal, makes of the assignment's start. */
117
+ private settle;
118
+ /**
119
+ * The start of `assignment`'s task, as delegations takes it: on the child, lifetime and checks
120
+ * its entry recorded, whatever the definition says now; its participant's pinned configuration,
121
+ * requiring the owners its checks need; the rows each check records for it, composed into the
122
+ * write that opens the task; and a short cue as its input, its presentation carrying the rest.
123
+ * Held while a check it lists has no provider serving the instance's pin.
124
+ */
125
+ private request;
126
+ /**
127
+ * The owner's say on one of its tasks. Opening it, inside the write that opens it, with the root
128
+ * held: the exact assignment open in the current attempt, on that child, task and generation, with
129
+ * every check it lists served; `discard` once it is superseded, stopped or its instance ended or
130
+ * is being cancelled, `hold` while it is held off its definition, a decision is pending or a
131
+ * check's provider is missing. Running, from the root's catalog entry, which needs nothing loaded
132
+ * ({@link runnableTasks}): an open assignment's task, or an accepted one's still draining; anything
133
+ * else is held.
134
+ */
135
+ private authorize;
136
+ }
137
+ /**
138
+ * The tasks of a live instance's isolated assignments that may run now, for its root's catalog
139
+ * entry, from its rows alone: each open assignment's of the current attempt, and each accepted
140
+ * one's, which may still drain what it took before it settled. No decision is pending while an
141
+ * assignment is open: a recovery supersedes them, and a result forms only once all are accepted.
142
+ */
143
+ export declare function runnableTasks(state: ReadonlyState<InstanceState>): string[];
@@ -0,0 +1,112 @@
1
+ import { type Context } from '@leuduan/cordis';
2
+ import { z } from 'zod';
3
+ import type { Seq, ThreadOrigin } from '../../models/index.js';
4
+ import type { WorkflowDefinition } from './definition.js';
5
+ import { type AssignmentView, type InstanceState } from './fold.js';
6
+ import { type ChildFacts } from './observations.js';
7
+ import type { ReadonlyState } from '../../util/foldState.js';
8
+ /**
9
+ * A host-bound allowlist, the shape of a tool-policy mode's rules without `approve`: calls outside
10
+ * `allow` are denied; a listed call gains no grant and still needs the host's permission.
11
+ */
12
+ export declare const RestrictionSchema: z.ZodObject<{
13
+ allow: z.ZodArray<z.ZodString>;
14
+ denial: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strict>;
16
+ export type Restriction = z.output<typeof RestrictionSchema>;
17
+ /** What the workflow's authority reads besides the journal: the host's allowlists and what is registered. */
18
+ export type Governance = {
19
+ /** The restriction policies steps name, by name. */
20
+ readonly restrictions: Readonly<Record<string, Restriction>>;
21
+ /** The allowlist the root works under while no assignment of its own is active. */
22
+ readonly coordination: Restriction;
23
+ /** The definition `state` executes by; `undefined` while none it can continue on is registered. */
24
+ readonly executable: (state: ReadonlyState<InstanceState>) => WorkflowDefinition | undefined;
25
+ };
26
+ /**
27
+ * Where a thread's call stands under a live instance: working an assignment, under that step's
28
+ * restriction (`null` adds none); coordinating, under the coordination policy, with why; or with no
29
+ * workflow authority at all (`closed`), which denies every call, with why.
30
+ */
31
+ export type Standing = {
32
+ readonly kind: 'assignment';
33
+ readonly assignment: AssignmentView;
34
+ readonly restriction: Restriction | null;
35
+ } | {
36
+ readonly kind: 'coordination';
37
+ readonly why: string;
38
+ } | {
39
+ readonly kind: 'closed';
40
+ readonly why: string;
41
+ };
42
+ /**
43
+ * A thread under an instance that opened, by how it is governed: the instance's `root`; an isolated
44
+ * `participant`'s child, created by the instance's assignment origin, with its facts; or an ordinary
45
+ * `descendant` of either, with the row on the root or participant whose call (or grant) created the
46
+ * first thread of its line below them: the authority it keeps, whatever that thread's caller does
47
+ * later. A thread created by a call keeps that call's authority; a persistent parent's later
48
+ * assignment grants it nothing new.
49
+ */
50
+ export type Governed = {
51
+ readonly root: string;
52
+ readonly state: ReadonlyState<InstanceState>;
53
+ } & ({
54
+ readonly kind: 'root';
55
+ } | {
56
+ readonly kind: 'participant';
57
+ readonly thread: string;
58
+ readonly facts: ReadonlyState<ChildFacts>;
59
+ } | {
60
+ readonly kind: 'descendant';
61
+ readonly source: Source;
62
+ });
63
+ /** Where an ordinary descendant's line was created: on the root, or on a participant's child, at row `seq`. */
64
+ type Source = {
65
+ readonly kind: 'root';
66
+ readonly seq: Seq;
67
+ } | {
68
+ readonly kind: 'participant';
69
+ readonly thread: string;
70
+ readonly facts: ReadonlyState<ChildFacts>;
71
+ readonly seq: Seq;
72
+ };
73
+ /** Whether `origin` is an assignment of this plugin's on the root `root`: an isolated participant's child. */
74
+ export declare const participantOrigin: (origin: ThreadOrigin | null, root: string) => boolean;
75
+ /**
76
+ * How `threadId` is governed by the instance at the top of its origin tree, read from the catalog
77
+ * and the folds of the threads above it, which a run of it keeps loaded; `undefined` when no
78
+ * instance opened there; `unreadable` when its caller chain does not reach a root, so what governs
79
+ * it cannot be said, which fails closed.
80
+ */
81
+ export declare function governedBy(ctx: Context, threadId: string): Governed | {
82
+ readonly unreadable: string;
83
+ } | undefined;
84
+ /** The current attempt's assignment for the conversation participant, the root's own, while it is open. */
85
+ export declare function rootAssignment(state: ReadonlyState<InstanceState>): AssignmentView | undefined;
86
+ /**
87
+ * The assignment a participant's child `thread` was working at its row `seq` (now, when `undefined`):
88
+ * the one whose task input the child claimed last by then. A persistent participant's tasks run one
89
+ * after another, so that claim names the task a call of it serves, a parked call answered later
90
+ * included.
91
+ */
92
+ export declare function participantServing(state: ReadonlyState<InstanceState>, thread: string, facts: ReadonlyState<ChildFacts>, seq: Seq | undefined): AssignmentView | undefined;
93
+ /**
94
+ * Where a call recorded at `callSeq` on a governed thread stands (§10 of the design), each thread
95
+ * through the exact assignment serving it:
96
+ *
97
+ * - the root, by its own assignment ({@link rootStanding});
98
+ * - a participant's child, by the assignment whose task the call serves ({@link participantServing}):
99
+ * its step's restriction while that assignment is open, and nothing once it closed;
100
+ * - an ordinary descendant, by the authority that created its line: a line the root started while
101
+ * coordinating coordinates, one started under an assignment, the root's or a participant's,
102
+ * works under that assignment's restriction while it is open, and has none once it closed.
103
+ */
104
+ export declare function standingOf(governed: Governed, governance: Governance, callSeq: Seq | undefined): Standing;
105
+ /**
106
+ * Mounts the workflow's authority on the application root: the vote on every call, and the grant
107
+ * of `submit_workflow_output` to the agent of each instance root and each isolated participant's
108
+ * child, in its activation's scope, from activation while its instance has not ended until the row
109
+ * that ends it. The grant only offers the tool; the vote decides every call of it.
110
+ */
111
+ export declare function enforceAuthority(ctx: Context, governance: Governance): void;
112
+ export {};