@leuduan/lagent 0.0.0-stage → 44.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +16 -0
- package/README.md +157 -2
- package/dist/chunks/2GCIWSOA.js +5 -0
- package/dist/chunks/2P47AHNK.js +7 -0
- package/dist/chunks/34KW6VNQ.js +1 -0
- package/dist/chunks/3UMZMPWW.js +1 -0
- package/dist/chunks/5IRF47YB.js +1 -0
- package/dist/chunks/6DRCKZ2C.js +1 -0
- package/dist/chunks/6FRNHMCV.js +1 -0
- package/dist/chunks/7LI64H5X.js +17 -0
- package/dist/chunks/7VAPNE3L.js +1 -0
- package/dist/chunks/ASSQZH3F.js +1 -0
- package/dist/chunks/B4FXK5ER.js +77 -0
- package/dist/chunks/BBCW2FZK.js +1 -0
- package/dist/chunks/BPRCULZH.js +1 -0
- package/dist/chunks/CANPZYTH.js +24 -0
- package/dist/chunks/CQEVREBT.js +1 -0
- package/dist/chunks/CUK7CGC7.js +1 -0
- package/dist/chunks/D4PQP5MA.js +3 -0
- package/dist/chunks/DDANMY45.js +3 -0
- package/dist/chunks/DDZ7YF26.js +1 -0
- package/dist/chunks/EMRB4KCN.js +6 -0
- package/dist/chunks/EPYQ5M3B.js +3 -0
- package/dist/chunks/FJLU4UH3.js +1 -0
- package/dist/chunks/G44LG6VL.js +1 -0
- package/dist/chunks/GGSVIIWJ.js +2 -0
- package/dist/chunks/HK6ZSONF.js +1 -0
- package/dist/chunks/IAAEP6VL.js +30 -0
- package/dist/chunks/JCTBX33H.js +36 -0
- package/dist/chunks/JFX2MXBA.js +4 -0
- package/dist/chunks/JFZZXVWD.js +15 -0
- package/dist/chunks/KUZCL2SH.js +1 -0
- package/dist/chunks/MHC6VPB4.js +7 -0
- package/dist/chunks/MMNNZCBO.js +5 -0
- package/dist/chunks/MNJ4SRF7.js +1 -0
- package/dist/chunks/N6IXG2VL.js +1 -0
- package/dist/chunks/OCBPT7KE.js +1 -0
- package/dist/chunks/OL5A6ITQ.js +1 -0
- package/dist/chunks/PUSUPTAT.js +1 -0
- package/dist/chunks/Q75FUN7D.js +2 -0
- package/dist/chunks/Q7S5LFGN.js +1 -0
- package/dist/chunks/RCIHV3KG.js +1 -0
- package/dist/chunks/S34ZA2R6.js +1 -0
- package/dist/chunks/SS3B5W34.js +12 -0
- package/dist/chunks/VYMT4TXD.js +1 -0
- package/dist/chunks/W57RW55W.js +1 -0
- package/dist/compositions/base.d.ts +11 -0
- package/dist/compositions/codex.d.ts +66 -0
- package/dist/compositions/codexPrompts.d.ts +56 -0
- package/dist/context.d.ts +109 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +1 -0
- package/dist/journal/catalog.d.ts +112 -0
- package/dist/journal/forkChain.d.ts +16 -0
- package/dist/journal/index.d.ts +15 -0
- package/dist/journal/journal.d.ts +475 -0
- package/dist/journal/projection.d.ts +87 -0
- package/dist/journal/store.d.ts +181 -0
- package/dist/llm/client.d.ts +135 -0
- package/dist/llm/content.d.ts +52 -0
- package/dist/llm/failure.d.ts +82 -0
- package/dist/llm/index.d.ts +22 -0
- package/dist/llm/index.js +1 -0
- package/dist/llm/primitives.d.ts +286 -0
- package/dist/llm/prompt.d.ts +21 -0
- package/dist/llm/provider.d.ts +74 -0
- package/dist/llm/readLedger.d.ts +24 -0
- package/dist/llm/request.d.ts +58 -0
- package/dist/loop/agent.d.ts +18 -0
- package/dist/loop/authorization.d.ts +41 -0
- package/dist/loop/auxiliary.d.ts +58 -0
- package/dist/loop/chunks.d.ts +27 -0
- package/dist/loop/completion.d.ts +17 -0
- package/dist/loop/errors.d.ts +139 -0
- package/dist/loop/hooks.d.ts +274 -0
- package/dist/loop/index.d.ts +16 -0
- package/dist/loop/runner.d.ts +134 -0
- package/dist/loop/runtime.d.ts +76 -0
- package/dist/loop/strategy.d.ts +80 -0
- package/dist/loop/surfacePrepare.d.ts +30 -0
- package/dist/loop/tool.d.ts +106 -0
- package/dist/loop/toolCalls.d.ts +35 -0
- package/dist/plugin.d.ts +50 -0
- package/dist/plugin.js +1 -0
- package/dist/plugins/agentsMd.d.ts +80 -0
- package/dist/plugins/agentsMd.js +1 -0
- package/dist/plugins/ask/index.d.ts +26 -0
- package/dist/plugins/ask/index.js +1 -0
- package/dist/plugins/ask/service.d.ts +125 -0
- package/dist/plugins/ask/tools.d.ts +9 -0
- package/dist/plugins/commands/index.d.ts +43 -0
- package/dist/plugins/commands/index.js +1 -0
- package/dist/plugins/commands/output.d.ts +115 -0
- package/dist/plugins/commands/record.d.ts +558 -0
- package/dist/plugins/commands/service.d.ts +321 -0
- package/dist/plugins/commands/shell.d.ts +25 -0
- package/dist/plugins/commands/tools.d.ts +10 -0
- package/dist/plugins/compaction/checkpoint.d.ts +94 -0
- package/dist/plugins/compaction/config.d.ts +133 -0
- package/dist/plugins/compaction/estimate.d.ts +37 -0
- package/dist/plugins/compaction/index.d.ts +87 -0
- package/dist/plugins/compaction/index.js +7 -0
- package/dist/plugins/compaction/planner.d.ts +207 -0
- package/dist/plugins/compaction/prune.d.ts +9 -0
- package/dist/plugins/compaction/record.d.ts +227 -0
- package/dist/plugins/compaction/segments.d.ts +23 -0
- package/dist/plugins/compaction/state.d.ts +68 -0
- package/dist/plugins/compaction/summarize.d.ts +13 -0
- package/dist/plugins/dateAndBranch.d.ts +47 -0
- package/dist/plugins/dateAndBranch.js +1 -0
- package/dist/plugins/delegations/answers.d.ts +39 -0
- package/dist/plugins/delegations/assignmentKey.d.ts +22 -0
- package/dist/plugins/delegations/cleanup.d.ts +161 -0
- package/dist/plugins/delegations/constraint.d.ts +76 -0
- package/dist/plugins/delegations/index.d.ts +39 -0
- package/dist/plugins/delegations/index.js +1 -0
- package/dist/plugins/delegations/notices.d.ts +261 -0
- package/dist/plugins/delegations/obligations.d.ts +210 -0
- package/dist/plugins/delegations/record.d.ts +633 -0
- package/dist/plugins/delegations/request.d.ts +384 -0
- package/dist/plugins/delegations/role.d.ts +30 -0
- package/dist/plugins/delegations/service.d.ts +563 -0
- package/dist/plugins/delegations/standing.d.ts +19 -0
- package/dist/plugins/delegations/stopCheck.d.ts +21 -0
- package/dist/plugins/delegations/tools.d.ts +71 -0
- package/dist/plugins/delegations/waitContracts.d.ts +118 -0
- package/dist/plugins/delegations/waitResolver.d.ts +116 -0
- package/dist/plugins/diagnostics/digest.d.ts +14 -0
- package/dist/plugins/diagnostics/index.d.ts +68 -0
- package/dist/plugins/diagnostics/index.js +1 -0
- package/dist/plugins/fileTools/config.d.ts +10 -0
- package/dist/plugins/fileTools/editFiles.d.ts +117 -0
- package/dist/plugins/fileTools/fsRead.d.ts +17 -0
- package/dist/plugins/fileTools/gitDiscovery.d.ts +9 -0
- package/dist/plugins/fileTools/index.d.ts +18 -0
- package/dist/plugins/fileTools/index.js +1 -0
- package/dist/plugins/fileTools/ripgrep.d.ts +20 -0
- package/dist/plugins/fileTools/textEdit.d.ts +67 -0
- package/dist/plugins/fileTools/tools.d.ts +6 -0
- package/dist/plugins/historyRecall/history.d.ts +9 -0
- package/dist/plugins/historyRecall/index.d.ts +31 -0
- package/dist/plugins/historyRecall/index.js +1 -0
- package/dist/plugins/historyRecall/render.d.ts +34 -0
- package/dist/plugins/historyRecall/tools.d.ts +4 -0
- package/dist/plugins/mcp/catalog.d.ts +36 -0
- package/dist/plugins/mcp/config.d.ts +63 -0
- package/dist/plugins/mcp/connection.d.ts +53 -0
- package/dist/plugins/mcp/errors.d.ts +32 -0
- package/dist/plugins/mcp/index.d.ts +33 -0
- package/dist/plugins/mcp/index.js +5 -0
- package/dist/plugins/mcp/mount.d.ts +98 -0
- package/dist/plugins/mcp/names.d.ts +25 -0
- package/dist/plugins/mcp/render.d.ts +29 -0
- package/dist/plugins/mcp/slots.d.ts +15 -0
- package/dist/plugins/mcp/stdio.d.ts +49 -0
- package/dist/plugins/mcp/tools.d.ts +41 -0
- package/dist/plugins/mcp/version.d.ts +2 -0
- package/dist/plugins/routeNotice.d.ts +22 -0
- package/dist/plugins/routeNotice.js +1 -0
- package/dist/plugins/sandbox/absent.d.ts +33 -0
- package/dist/plugins/sandbox/client.d.ts +39 -0
- package/dist/plugins/sandbox/files.d.ts +28 -0
- package/dist/plugins/sandbox/index.d.ts +52 -0
- package/dist/plugins/sandbox/index.js +4 -0
- package/dist/plugins/sandbox/mode.d.ts +57 -0
- package/dist/plugins/sandbox/policy.d.ts +163 -0
- package/dist/plugins/sandbox/protocol.d.ts +107 -0
- package/dist/plugins/sandbox/service.d.ts +153 -0
- package/dist/plugins/sandbox/worker.d.ts +12 -0
- package/dist/plugins/sandbox/worker.js +1 -0
- package/dist/plugins/schedules/index.d.ts +21 -0
- package/dist/plugins/schedules/index.js +5 -0
- package/dist/plugins/schedules/record.d.ts +396 -0
- package/dist/plugins/schedules/service.d.ts +120 -0
- package/dist/plugins/schedules/time.d.ts +26 -0
- package/dist/plugins/schedules/tools.d.ts +6 -0
- package/dist/plugins/skills/discovery.d.ts +83 -0
- package/dist/plugins/skills/index.d.ts +31 -0
- package/dist/plugins/skills/index.js +1 -0
- package/dist/plugins/skills/tools.d.ts +11 -0
- package/dist/plugins/subAgents/availableRoutes.d.ts +53 -0
- package/dist/plugins/subAgents/index.d.ts +67 -0
- package/dist/plugins/subAgents/index.js +1 -0
- package/dist/plugins/subAgents/tools.d.ts +67 -0
- package/dist/plugins/threadDirs.d.ts +36 -0
- package/dist/plugins/threadDirs.js +1 -0
- package/dist/plugins/toolPolicy/index.d.ts +61 -0
- package/dist/plugins/toolPolicy/index.js +1 -0
- package/dist/plugins/truncateToolOutput.d.ts +30 -0
- package/dist/plugins/truncateToolOutput.js +6 -0
- package/dist/plugins/usage/index.d.ts +26 -0
- package/dist/plugins/usage/index.js +1 -0
- package/dist/plugins/usage/tracker.d.ts +34 -0
- package/dist/plugins/verify/index.d.ts +27 -0
- package/dist/plugins/verify/index.js +6 -0
- package/dist/plugins/verify/judgement.d.ts +16 -0
- package/dist/plugins/verify/record.d.ts +382 -0
- package/dist/plugins/verify/service.d.ts +93 -0
- package/dist/plugins/verify/state.d.ts +58 -0
- package/dist/plugins/webTools/html.d.ts +23 -0
- package/dist/plugins/webTools/index.d.ts +34 -0
- package/dist/plugins/webTools/index.js +1 -0
- package/dist/plugins/webTools/network.d.ts +23 -0
- package/dist/plugins/webTools/web.d.ts +32 -0
- package/dist/plugins/workflows/assignment.d.ts +20 -0
- package/dist/plugins/workflows/cleanup.d.ts +38 -0
- package/dist/plugins/workflows/definition.d.ts +184 -0
- package/dist/plugins/workflows/entryPlan.d.ts +95 -0
- package/dist/plugins/workflows/hostBindings.d.ts +146 -0
- package/dist/plugins/workflows/index.d.ts +28 -0
- package/dist/plugins/workflows/index.js +11 -0
- package/dist/plugins/workflows/observations.d.ts +81 -0
- package/dist/plugins/workflows/participantModels.d.ts +28 -0
- package/dist/plugins/workflows/participants.d.ts +143 -0
- package/dist/plugins/workflows/policy.d.ts +112 -0
- package/dist/plugins/workflows/record.d.ts +2849 -0
- package/dist/plugins/workflows/routing.d.ts +116 -0
- package/dist/plugins/workflows/schema.d.ts +26 -0
- package/dist/plugins/workflows/service.d.ts +477 -0
- package/dist/plugins/workflows/state.d.ts +373 -0
- package/dist/plugins/workflows/stopCheck.d.ts +13 -0
- package/dist/plugins/workflows/tools.d.ts +13 -0
- package/dist/plugins/workflows/view.d.ts +103 -0
- package/dist/plugins/workflows/workStatus.d.ts +21 -0
- package/dist/plugins/workspaceNotice.d.ts +36 -0
- package/dist/plugins/workspaceNotice.js +1 -0
- package/dist/providers/anthropic.d.ts +178 -0
- package/dist/providers/anthropicMessages.d.ts +66 -0
- package/dist/providers/codex.d.ts +71 -0
- package/dist/providers/codexAuth.d.ts +116 -0
- package/dist/providers/deepseek.d.ts +59 -0
- package/dist/providers/failure.d.ts +23 -0
- package/dist/providers/gateway.d.ts +24 -0
- package/dist/providers/index.d.ts +18 -0
- package/dist/providers/index.js +6 -0
- package/dist/providers/openaiChat.d.ts +73 -0
- package/dist/providers/openaiResponses.d.ts +109 -0
- package/dist/providers/opencodeCopilot.d.ts +23 -0
- package/dist/providers/opencodeGo.d.ts +109 -0
- package/dist/providers/shared.d.ts +112 -0
- package/dist/providers/stream.d.ts +156 -0
- package/dist/records/index.d.ts +13 -0
- package/dist/records/index.js +1 -0
- package/dist/records/journal.d.ts +2968 -0
- package/dist/records/toolResult.d.ts +65 -0
- package/dist/services/agents.d.ts +62 -0
- package/dist/services/catalogContributions.d.ts +73 -0
- package/dist/services/confinement/files.d.ts +118 -0
- package/dist/services/confinement/service.d.ts +219 -0
- package/dist/services/core.d.ts +28 -0
- package/dist/services/extensionEvents.d.ts +181 -0
- package/dist/services/journal.d.ts +26 -0
- package/dist/services/llm.d.ts +82 -0
- package/dist/services/modes.d.ts +65 -0
- package/dist/services/plugins.d.ts +34 -0
- package/dist/services/presets/definition.d.ts +154 -0
- package/dist/services/presets/installations.d.ts +139 -0
- package/dist/services/prompts.d.ts +85 -0
- package/dist/services/threads/activation.d.ts +100 -0
- package/dist/services/threads/admission.d.ts +174 -0
- package/dist/services/threads/birth.d.ts +219 -0
- package/dist/services/threads/index.d.ts +14 -0
- package/dist/services/threads/runEvents.d.ts +79 -0
- package/dist/services/threads/runOwner.d.ts +368 -0
- package/dist/services/threads/service.d.ts +450 -0
- package/dist/services/threads/thread.d.ts +268 -0
- package/dist/services/threads/view.d.ts +93 -0
- package/dist/services/tools.d.ts +118 -0
- package/dist/state/birth.d.ts +62 -0
- package/dist/state/chain.d.ts +46 -0
- package/dist/state/confirmations.d.ts +64 -0
- package/dist/state/continuation.d.ts +167 -0
- package/dist/state/decide.d.ts +72 -0
- package/dist/state/dispatches.d.ts +54 -0
- package/dist/state/errors.d.ts +26 -0
- package/dist/state/forks.d.ts +61 -0
- package/dist/state/holds.d.ts +104 -0
- package/dist/state/inbox.d.ts +188 -0
- package/dist/state/index.d.ts +31 -0
- package/dist/state/inputs.d.ts +58 -0
- package/dist/state/installations.d.ts +28 -0
- package/dist/state/limits.d.ts +14 -0
- package/dist/state/prompt.d.ts +13 -0
- package/dist/state/recovery.d.ts +7 -0
- package/dist/state/replace.d.ts +33 -0
- package/dist/state/requests.d.ts +129 -0
- package/dist/state/route.d.ts +61 -0
- package/dist/state/summary.d.ts +16 -0
- package/dist/state/surface.d.ts +153 -0
- package/dist/state/surfaceRead.d.ts +20 -0
- package/dist/state/thread.d.ts +73 -0
- package/dist/state/turns.d.ts +87 -0
- package/dist/state/waits.d.ts +38 -0
- package/dist/state/wake.d.ts +32 -0
- package/dist/stores/durableObject.d.ts +23 -0
- package/dist/stores/durableObject.js +1 -0
- package/dist/stores/durableObjectConnection.d.ts +27 -0
- package/dist/stores/memory.d.ts +29 -0
- package/dist/stores/sql.d.ts +59 -0
- package/dist/stores/sqlite.d.ts +31 -0
- package/dist/stores/sqlite.js +1 -0
- package/dist/sys/environment.d.ts +42 -0
- package/dist/sys/git.d.ts +47 -0
- package/dist/sys/paths.d.ts +9 -0
- package/dist/sys/spawn.d.ts +186 -0
- package/dist/testing/clock.d.ts +17 -0
- package/dist/testing/fakeLlm.d.ts +76 -0
- package/dist/testing/fedLlm.d.ts +34 -0
- package/dist/testing/helpers.d.ts +362 -0
- package/dist/testing/index.d.ts +13 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/processes.d.ts +13 -0
- package/dist/testing/settlement.d.ts +6 -0
- package/dist/testing/tmpDirs.d.ts +17 -0
- package/dist/util/async.d.ts +8 -0
- package/dist/util/diff.d.ts +25 -0
- package/dist/util/dispatch.d.ts +8 -0
- package/dist/util/errors.d.ts +28 -0
- package/dist/util/foldState.d.ts +17 -0
- package/dist/util/freeze.d.ts +2 -0
- package/dist/util/ids.d.ts +2 -0
- package/dist/util/json.d.ts +37 -0
- package/dist/util/jsonSchema.d.ts +7 -0
- package/dist/util/log.d.ts +6 -0
- package/dist/util/retries.d.ts +25 -0
- package/dist/util/text.d.ts +21 -0
- package/dist/util/timers.d.ts +43 -0
- package/package.json +183 -3
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{a as En,j as Ln,k as Dn,r as fe,v as Fn,w as He,x as re}from"../../chunks/CANPZYTH.js";import{c as Cn}from"../../chunks/VYMT4TXD.js";import"../../chunks/MNJ4SRF7.js";import{d as In}from"../../chunks/JFZZXVWD.js";import"../../chunks/N6IXG2VL.js";import"../../chunks/6DRCKZ2C.js";import"../../chunks/7LI64H5X.js";import"../../chunks/3UMZMPWW.js";import"../../chunks/34KW6VNQ.js";import"../../chunks/KUZCL2SH.js";import"../../chunks/CQEVREBT.js";import"../../chunks/HK6ZSONF.js";import{a as Pn}from"../../chunks/7VAPNE3L.js";import"../../chunks/EPYQ5M3B.js";import"../../chunks/5IRF47YB.js";import"../../chunks/OL5A6ITQ.js";import{b as An,c as Nn}from"../../chunks/JFX2MXBA.js";import{b as Mn,d as Rn}from"../../chunks/S34ZA2R6.js";import{b as se,e as Wn}from"../../chunks/6FRNHMCV.js";import"../../chunks/CUK7CGC7.js";import{a as te,s as ie,z as qn}from"../../chunks/BPRCULZH.js";import{a as Ve}from"../../chunks/FJLU4UH3.js";import{a as le,b as Tn}from"../../chunks/DDANMY45.js";import{c as U,d as A,e as G,g as ue,h as je}from"../../chunks/BBCW2FZK.js";import{a as H,b as jn,i as Sn,o as _n}from"../../chunks/MMNNZCBO.js";import{a as xn}from"../../chunks/G44LG6VL.js";import{f as xe}from"../../chunks/D4PQP5MA.js";import{Service as es}from"@leuduan/cordis";import{z as $}from"zod";import{z as m}from"zod";var T="lagent:workflows",F=n=>n.requires.includes(T),N="submit_workflow_output",Bn="workflow_submission",j=m.string().min(1),Yt=m.discriminatedUnion("kind",[m.strictObject({kind:m.literal("input")}),m.strictObject({kind:m.literal("evidence"),provider:j,immutable:m.boolean(),detail:A}),m.strictObject({kind:m.literal("result"),result:j,participant:j.nullable(),decision:j.nullable(),mode:m.enum(["current","historical"])})]),Se=n=>n===null?null:n.kind==="evidence"?{...n,detail:G(n.detail)}:{...n},zn=m.strictObject({config:A}),Gt=m.strictObject({participants:m.record(j,m.strictObject({configuration:m.strictObject({agent:j,route:xn,environment:_n,installations:m.array(Sn)}).nullable(),checks:m.record(j,zn)})),evidence:m.record(j,zn)}),Zt=m.discriminatedUnion("context",[m.strictObject({context:m.literal("conversation"),id:j,participant:j,activation:j}),m.strictObject({context:m.literal("isolated"),id:j,participant:j,thread:j,task:j,generation:m.number().int().positive(),lifetime:m.enum(["instance","attempt"]),checks:m.array(j)})]),Xt=m.discriminatedUnion("kind",[m.strictObject({kind:m.literal("accepted"),submission:m.number().int().positive(),ending:m.number().int().positive(),output:A}),m.strictObject({kind:m.literal("ended"),settlement:m.enum(["failed","stopped","completed"]),detail:m.string(),candidate:m.strictObject({submission:m.number().int().positive(),output:A}).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:A}).nullable(),report:m.string().nullable()})]),Un=m.strictObject({assignment:j,thread:j,task:j,generation:m.number().int().positive(),outcome:Xt}),Jn=m.discriminatedUnion("kind",[m.strictObject({kind:m.literal("opening")}),m.strictObject({kind:m.literal("routed"),result:j}),m.strictObject({kind:m.literal("decision"),decision:j})]),Kn=m.discriminatedUnion("op",[m.strictObject({op:m.literal("opened"),definition:j,canonical:m.record(m.string(),A),input:A,input_id:j,pins:Gt}),m.strictObject({op:m.literal("entered"),transition:j,cause:Jn,step:j,attempt:j,ordinal:m.number().int().positive(),retires:m.array(j),inputs:m.record(j,Yt.nullable()),evidence:m.record(j,A),assignments:m.array(Zt)}),m.strictObject({op:m.literal("observed"),observations:m.array(Un).min(1)}),m.strictObject({op:m.literal("stopped"),attempt:j,reason:m.string(),observations:m.array(Un)}),m.strictObject({op:m.literal("completed"),transition:j,cause:Jn}),m.strictObject({op:m.literal("decided"),decision:j,operation_id:j,actor:m.string(),attempt:j,reason:m.enum(["gate","exhaustion","recovery"]),result:j.nullable(),verdict:m.enum(["approve","revise"]),option:j.nullable(),feedback:m.string().nullable(),restart:m.array(j)}).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:j,actor:m.string(),reason:m.string()}),m.strictObject({op:m.literal("cancelled"),operation_id:j})]),I=se({plugin:"lagent:workflows",kind:"instance",version:7,policyState:!0,schema:Kn});function Vn(n,e,t,i){return Kn.parse({op:"opened",definition:n.id,canonical:n,input:e,input_id:t,pins:i})}var Hn=m.strictObject({assignment:j,output:A}),Qn=n=>({[Bn]:Hn.parse(n)});function _e(n){if(n.name!==N||n.is_error||n.concludes_turn!==!0)return;let e=Hn.safeParse(n.metadata[Bn]);return e.success?e.data:void 0}var Z=se({plugin:"lagent:workflows",kind:"reminder",version:1,schema:m.strictObject({assignment:j,epoch:m.number().int().positive()})}),Yn=n=>encodeURIComponent(n),Gn=(n,e,t)=>`${n}#${Yn(e)}:${t}`,Zn=(n,e)=>`${n}@${Yn(e)}`,pe=(n,e)=>n.get(e)??1,Xn=n=>`${n}/result`,Qe=(n,e)=>`${n}/${e}`;function Ee(n,e){switch(e.kind){case"opening":return`${n}#opening/next`;case"routed":return`${e.result}/next`;case"decision":return`${e.decision}/next`}}var qe=n=>`${n}/input`,et=se({plugin:"lagent:workflows",kind:"transition",version:1,schema:m.strictObject({transition:j,assignment:j.nullable(),decision:j.nullable()})});var oe=(n,e=new Set)=>tt(n,t=>t.retired||e.has(t.revision));function nt(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 tt(n,i=>t.has(i.revision))}function tt(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 Te(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 Me(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:Te(n,i.decision)}}function Re(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:b}of o.assignments)if(e.participants[b]?.context==="isolated"&&n.opened?.pins.participants[b]?.configuration==null)return{refused:`participant ${b} was not pinned when the instance opened: a new participant needs a new workflow id`};let a=(n.ordinals.get(s)??0)+1,c=Gn(i,s,a),d=Ee(i,r),{evidence:u}=t,f=u?.attempt===c&&u.transition===d?u.inputs:new Map,l=ni(n,s,oe(n)),w=l===void 0?[]:[l.revision],p=oe(n,new Set(w)),h={},g={},O=[];for(let[b,k]of Object.entries(o.inputs)){if(!("source"in k)){let{evidence:D,optional:Be}=k,Y=f.get(b),Ke=Qt=>({refused:`input ${b} (evidence ${D}): ${Qt}`});if(Y===void 0){O.push({input:b,provider:D});continue}if(Y.kind==="unavailable")return Ke(`it could not be acquired: ${Y.reason}`);if(Y.kind==="absent"){if(!Be)return Ke("there is none");h[b]=null;continue}if(n.opened?.pins.evidence[D]===void 0)return Ke("the instance recorded no pin for its provider");h[b]={kind:"evidence",provider:D,immutable:Y.immutable,detail:Y.detail},g[b]=Y.value;continue}if(k.source==="$input"){h[b]={kind:"input"};continue}let{step:x,participant:S=null}=k.source,C=D=>({refused:`input ${b} (${x}): ${D}`}),L=[...n.results.values()].filter(D=>D.step===x&&(S===null||Object.hasOwn(D.outputs,S))),W;if(k.mode==="historical")W=L.at(-1);else if(x!==s){if(W=L.filter(({revision:Be})=>!p.has(Be)).at(-1),W===void 0&&L.length>0)return C("its result is no longer current");let D=W===void 0?null:ei(n,W,t.deciding);if(W!==void 0&&e.steps[x]?.gate===!0&&D?.verdict!=="approve")return C(`its current result ${W.revision} is not approved`)}if(W===void 0){if(!k.optional)return C("it has no accepted result");h[b]=null;continue}h[b]={kind:"result",result:W.revision,participant:S,decision:t.deciding?.result===W.revision?t.deciding.id:W.decision,mode:k.mode}}return O.length>0?{needs:{transition:d,attempt:c,step:s,inputs:O}}:{row:{op:"entered",transition:d,cause:r,step:s,attempt:c,ordinal:a,retires:w,inputs:h,evidence:g,assignments:o.assignments.map(({participant:b,checks:k})=>{let x=Zn(c,b),S=e.participants[b];if(S.context==="conversation")return{context:"conversation",id:x,participant:b,activation:t.activation};let C=pe(n.generations,b)+(t.deciding?.restart.includes(b)?1:0),L=T;return{context:"isolated",id:x,participant:b,thread:Dn({owner:L,instance:i,participant:b,attempt:S.lifetime==="attempt"?c:null,generation:C}),task:Ln({owner:L,instance:i,attempt:c,assignment:x,generation:C}),generation:C,lifetime:S.lifetime,checks:[...k]}})}}}var ei=(n,e,t)=>t?.result===e.revision?t.decision:Te(n,e.decision);function ni(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 ti=()=>({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:te.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:ti,apply(n,e){let t=I.read(e);if(t!==void 0)return ui(n,t,e),n;if(n.opened===null)return n;let i=n.answer;return n.answer=te.apply(i,e),e.type==="inbox/spliced"&&ii(n,e),e.type==="run/cause"&&si(n,e),e.type==="assistant/message"&&Xe(n,e),e.type==="tool/call"&&en(n,e),e.type==="input/message"&&(ri(n,e),oi(n,e)),e.type==="tool/result"&&ai(n,e),ci(n,i,e.seq),n}});function he(n){return!_(n)||n.current===null?[]:n.current.assignments.filter(({state:e})=>e!=="accepted"&&e!=="superseded")}var Ae=n=>he(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 ii(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:a})=>!t.includes(a));r.queued.splice(0,r.queued.length,...o);for(let a of i)a.source===null&&r.queued.push({id:a.id,person:!1})}}function si(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 ri(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 oi(n,e){if(e.data.source===null){n.personAt=e.seq;return}let t=Z.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 ot(n,e){return e.claimSeq===null?null:Math.max(e.claimSeq,n.personAt??0)}function ai(n,e){let t=_e(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 ci(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)}at(n)}function at(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));dt(n,e,t)}function it(n,e,t,i){let s=e.flatMap(c=>{let d=he(n).find(({id:f})=>f===c.assignment);return d!==void 0&&d.context==="isolated"&&d.thread===c.thread&&d.task===c.task&&d.generation===c.generation?[{assignment:d,outcome:c.outcome}]:[]});for(let{assignment:c,outcome:d}of s)d.kind==="accepted"&&(c.state="accepted",c.accepted={output:d.output,seq:t,call:null},c.submitted=c.accepted,c.closed=t);let r=s.flatMap(({assignment:c,outcome:d})=>d.kind==="ended"||d.kind==="refused"?[{assignment:c,outcome:d}]:[]);if(r.length===0&&(at(n),i===null||!he(n).some(({context:c})=>c==="isolated")))return;let o=new Map;for(let{assignment:c,outcome:d}of s)d.kind==="accepted"||d.kind==="refused"||(d.candidate!==null&&(c.submitted={output:d.candidate.output,seq:t,call:null}),d.report!==null&&o.set(c,d.report));let a=r.length>0?{cause:"failure",detail:r.map(({assignment:c,outcome:d})=>d.kind==="refused"?`${c.participant}: its task could not be started: ${d.detail}`:`${c.participant}: ${d.detail}`).join("; ")}:{cause:"stop",detail:`the user stopped it: ${i}`};ct(n,{...a,seq:t},c=>o.get(c)??null)}function di(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 ct(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 a=t(o);a!==null&&(r[o.participant]=a)}Ce(n,e.seq),i.recovery={...e,candidates:s,reports:r,decision:null}}function dt(n,e,t){let i=Xn(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 Ce(n,e){for(let t of he(n))t.state="superseded",t.candidate=null,t.closed=e}function st(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 rt(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 ui(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;Ce(n,t.seq);for(let s of e.retires){let r=n.results.get(s);r!==void 0&&(r.retired=!0)}st(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)dt(n,i,t.seq);else if(di(n,e)&&i.assignments.some(({context:s})=>s==="isolated")){let s=`the user stopped it before its work began: ${n.stop.reason}`;ct(n,{cause:"stop",detail:s,seq:t.seq},()=>null)}return}case"observed":it(n,rt(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},it(n,rt(n,e.observations,t.seq),t.seq,e.reason);return;case"completed":if(!_(n))return;Ce(n,t.seq),st(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,pe(n.generations,i)+1);n.counts.clear();return}case"cancel-requested":if(!_(n))return;Ce(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===pe(n.generations,i)&&e.set(i,r);return e}function me(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 he(n))e[t]={context:i,open:!0}}return{id:n.opened.definition,step:_(n)?n.current?.entered.step??null:null,participants:e}}function ge(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:a,open:c}]of Object.entries(n.participants)){let d=c?"an open assignment":"a conversation of its own",u=e.participants[o];u===void 0?s.push(`participant ${o}, with ${d}, is gone`):u.context!==a?s.push(`participant ${o}, with ${d}, changed from ${a} to ${u.context}`):c&&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 ut(n,e){if(n.opened!==null)return ge(me(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:Me(n,e.entered,i),citation:Se(s)}]))}}import{z as v}from"zod";import{z as P}from"zod";var li=["title","description"],fi=["type","checks","error"],pi={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"]}},hi={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"]},we=n=>n._zod.def,mi=P.string().min(0)._zod.def.checks[0]._zod.def.when,lt=n=>n instanceof P.core.$ZodType,gi=n=>Number.isSafeInteger(n)&&n>=0;function ft(n,e){let t=[],i=[],s=(o,a)=>{if(!lt(o)){t.push(`${a}: not a zod schema`);return}if(i.includes(o)){t.push(`${a}: a recursive schema`);return}i.push(o);try{return wi(o,a,s,t)}finally{i.pop()}},r=s(n,e);return{problems:t,schema:t.length===0?r:void 0}}function wi(n,e,t,i){let s=i.length,r=l=>{i.push(`${e}: ${l}`)},o={};for(let[l,w]of Object.entries(P.globalRegistry.get(n)??{}))li.includes(l)?typeof w!="string"?r(`metadata "${l}" is not a string`):o[l]=w:r(`metadata "${l}" (only title and description are admitted)`);let a=we(n),c=a.type,d=(...l)=>{for(let w of Object.keys(a))!fi.includes(w)&&!l.includes(w)&&r(`${String(c)} with "${w}"`)};if(a.coerce===!0){r("coercion");return}let u=bi(a,String(c),r),f=l=>{if(!(i.length>s||l===void 0))return Object.keys(o).length===0?l:l.meta(o)};switch(c){case"string":{d();let l=P.string();return u.minLength!==void 0&&(l=l.min(u.minLength)),u.maxLength!==void 0&&(l=l.max(u.maxLength)),u.pattern!==void 0&&(l=l.regex(new RegExp(u.pattern))),f(l)}case"number":{a.format==="safeint"&&a.check==="number_format"?(u.integer===!0&&r("the check number_format twice"),u.integer=!0,d("check","abort","format")):d();let l=u.integer===!0?P.int():P.number(),{lower:w,upper:p,multipleOf:h}=u;return w!==void 0&&(l=w.inclusive?l.gte(w.value):l.gt(w.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 d(),f(P.boolean());case"enum":{d("entries");let l=Object.entries(a.entries);if(!l.every(([,w])=>typeof w=="string"||typeof w=="number"&&Number.isFinite(w))){r("an enum with a value that is not a string or finite number");return}return f(P.enum(Object.fromEntries(l)))}case"literal":{d("values");let l=[...a.values];if(!l.every(w=>w===null||["string","boolean"].includes(typeof w)||typeof w=="number"&&Number.isFinite(w))){r("a literal that is not a JSON scalar");return}return f(P.literal(l))}case"object":{d("shape","catchall");let l=a.catchall;(!lt(l)||we(l).type!=="never")&&r("an object that is not strict (use z.strictObject: other objects strip or pass unknown keys)");let w={};for(let[p,h]of Object.entries(a.shape)){let g=t(h,`${e}.${p}`);g!==void 0&&(w[p]=g)}return f(P.strictObject(w))}case"array":{d("element");let l=t(a.element,`${e}[]`);if(l===void 0)return;let w=P.array(l);return u.minLength!==void 0&&(w=w.min(u.minLength)),u.maxLength!==void 0&&(w=w.max(u.maxLength)),f(w)}case"union":{d("options","discriminator","inclusive");let l=a.discriminator;a.inclusive===!1&&l===void 0&&r("an exclusive union");let w=a.options.map((g,O)=>t(g,`${e}|${O}`));if(w.some(g=>g===void 0)||i.length>s)return;let p=w;if(typeof l!="string")return f(P.union(p));let h=new Map;if(p.forEach((g,O)=>{let y=we(g),b=y.type==="object"?y.shape[l]:void 0,k=b===void 0||!Object.hasOwn(y.shape,l)?void 0:we(b),x=k?.type==="literal"?k.values:k?.type==="enum"?Object.values(k.entries):void 0;if(x===void 0){r(`branch ${O} of the discriminated union has no literal or enum ${l}`);return}for(let S of x){let C=h.get(S);C!==void 0?r(`branches ${C} and ${O} of the discriminated union share ${l} ${JSON.stringify(S)}`):h.set(S,O)}}),i.length>s)return;try{let g=P.discriminatedUnion(l,p);return g.safeParse(null),f(g)}catch(g){r(`a discriminated union zod refuses: ${g instanceof Error?g.message:String(g)}`);return}}case"nullable":case"optional":{d("innerType");let l=t(a.innerType,e);return f(l===void 0?void 0:c==="nullable"?l.nullable():l.optional())}default:r(`a ${String(c)} schema`);return}}function bi(n,e,t){let i={},s=new Set,r=hi[e]??[];for(let o of n.checks??[]){let a=o._zod.def,c=String(a.check),d=pi[c];if(!r.includes(c)||d===void 0){t(c==="custom"?"a refinement":c==="overwrite"?"a normalizing check":`the check ${c}`);continue}for(let l of Object.keys(a))l==="when"&&a.when===mi||["check","error","abort",...d.props].includes(l)||t(`the check ${c} with "${l}"`);let u=d.sets.filter(l=>s.has(l));if(u.length>0){t(`a second check on ${u.join(" and ")} (${c}): one per node`);continue}for(let l of d.sets)s.add(l);let f=a.value;switch(c){case"min_length":case"max_length":case"length_equals":{let l=a[c==="min_length"?"minimum":c==="max_length"?"maximum":"length"];if(!gi(l)){t(`the check ${c} with ${String(l)}, not a non-negative integer`);break}c!=="max_length"&&(i.minLength=l),c!=="min_length"&&(i.maxLength=l);break}case"string_format":{let l=a.pattern;a.format!=="regex"||!(l instanceof RegExp)?t(`the string format ${String(a.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 ${c} with ${String(f)}, not a finite number`);break}i[c==="greater_than"?"lower":"upper"]={value:f,inclusive:a.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":a.format!=="safeint"?t(`the number format ${String(a.format)}`):i.integer=!0;break}}return i}function ae(n,e){if(e.length===0)return[n];let t=we(n),[i,...s]=e;switch(t.type){case"nullable":case"optional":return ae(t.innerType,e);case"union":return t.options.flatMap(r=>ae(r,e));case"object":{let r=t.shape;return Object.hasOwn(r,i)?ae(r[i],s):[]}case"array":return/^(0|[1-9]\d*)$/.test(i)?ae(t.element,s):[];default:return[]}}var ce="$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=v.string().min(1),pt=v.custom(n=>n instanceof v.ZodType,{error:"Expected a zod schema"}),ki=v.strictObject({id:M,input:pt,entry:M,prerequisites:v.array(M).default([]),participants:v.record(M,v.discriminatedUnion("context",[v.strictObject({context:v.literal("conversation")}),v.strictObject({context:v.literal("isolated"),lifetime:v.enum(["instance","attempt"]),role:M,model:v.strictObject({provider:M,model:M,thinkingEffort:xe.optional(),configurable:v.boolean()})})])),steps:v.record(M,v.strictObject({inputs:v.record(M,v.union([v.strictObject({source:v.union([v.literal("$input"),v.strictObject({step:M,participant:M.optional()})]),mode:v.enum(["current","historical"]),optional:v.boolean()}),v.strictObject({evidence:M,optional:v.boolean()})])),assignments:v.array(v.strictObject({participant:M,reads:v.array(M),prompt:v.string(),output:pt,checks:v.array(M).default([])})),gate:v.boolean(),options:v.array(v.strictObject({name:M,on:v.array(v.enum(["gate","recovery"])).min(1)})).default([]),restriction:M.nullable(),maxAttempts:v.number().int().positive(),edges:v.array(v.strictObject({when:v.union([v.literal("otherwise"),v.array(v.strictObject({field:v.string(),equals:v.union([v.string(),v.number(),v.boolean(),v.null()])}))]),to:M}))}))}),sn=new WeakMap,ht=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 vi(n){let e=ki.safeParse(n),t=yi(n);if(!e.success)throw new J(t,e.error.issues.map(a=>`${a.path.map(String).join(".")||"(definition)"}: ${a.message}`));let i=Oi(e.data);if(i.problems.length>0)throw new J(t,i.problems);let s=i.data,r=Si(s);if(r.length>0)throw new J(t,r);let o=ue($i(s));return sn.set(o,{input:s.input,outputs:new Map(Object.entries(s.steps).map(([a,{assignments:c}])=>[a,new Map(c.map(({participant:d,output:u})=>[d,u]))]))}),o}var yi=n=>{let{id:e}=typeof n=="object"&&n!==null?n:{};return typeof e=="string"?e:"?"};function $i(n){let{input:e,participants:t,steps:i,...s}=n;return JSON.parse(JSON.stringify({...s,input:Ve(e),participants:t,steps:Object.fromEntries(Object.entries(i).map(([r,{assignments:o,...a}])=>[r,{...a,assignments:o.map(({output:c,...d})=>({...d,output:Ve(c)}))}]))}))}function Oi(n){let e=[],t=(s,r)=>{let o=ft(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 xi=["reason","verdict","option"];function mt(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 ji(n,e){let t=n;for(let i of mt(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 be(n,e){let t=gt(n,e);if(t===void 0)throw new Error("No edge matched: a registered step always ends with otherwise");return t}var gt=(n,e)=>n.find(t=>t.when==="otherwise"||t.when.every(({field:i,equals:s})=>ji(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===ce?"its first matching edge completes the instance, which a recovery cannot":null}function Si(n){let e=[],{steps:t,participants:i}=n,s=a=>Object.hasOwn(t,a),r=Object.entries(i).filter(([,a])=>a.context==="conversation");r.length>1&&e.push(`participants: more than one conversation participant (${r.map(([a])=>a).join(", ")})`),s(n.entry)||e.push(`entry: unknown step ${n.entry}`);let o=new Set;for(let a of n.prerequisites)o.has(a)&&e.push(`prerequisites: ${a} is listed twice`),o.add(a);for(let[a,c]of Object.entries(t)){let d=`steps.${a}`,u=h=>{e.push(`${d}: ${h}`)};a.startsWith("$")&&u('a step name may not start with "$"');for(let[h,g]of Object.entries(c.inputs)){if(!("source"in g)||g.source==="$input")continue;let{step:O,participant:y}=g.source;if(!s(O)){u(`input ${h} binds unknown step ${O}`);continue}y!==void 0&&!t[O].assignments.some(b=>b.participant===y)&&u(`input ${h} binds participant ${y}, which step ${O} does not assign`),O===a&&g.mode==="current"&&!g.optional&&u(`input ${h} requires the step's own current result, which entering the step retires`)}c.assignments.length===0&&!c.gate&&u("a step with no assignments is a pure gate and must set gate: true");let f=new Set;for(let h of c.assignments){let{participant:g}=h;Object.hasOwn(i,g)||u(`assigns unknown participant ${g}`),f.has(g)&&u(`assigns participant ${g} twice`),f.add(g),h.checks.length>0&&i[g]?.context==="conversation"&&u(`${g}'s assignment lists checks, which only an isolated participant's may`),new Set(h.checks).size!==h.checks.length&&u(`${g}'s assignment lists a check twice`);let O=new Set;for(let y of h.reads)Object.hasOwn(c.inputs,y)||u(`${g} reads unknown input ${y}`),O.has(y)&&u(`${g} reads input ${y} twice`),O.add(y)}let l=new Map;for(let h of c.options)l.has(h.name)&&u(`option ${h.name} is declared twice`),l.set(h.name,h.on),new Set(h.on).size!==h.on.length&&u(`option ${h.name} lists a reason twice`),h.on.includes("gate")&&!c.gate&&u(`option ${h.name} is declared on gate, but the step has no gate`);let w=c.options.some(h=>h.on.includes("recovery"));if(w){let h=c.assignments.every(({participant:g})=>i[g]?.context==="isolated");(c.assignments.length===0||!h)&&u("a recovery option needs every assignment of the step isolated: a mixed step recovers only by retry or cancel");for(let{name:g,on:O}of c.options){if(!O.includes("recovery"))continue;let y=gt(c.edges,rn(g,null)),b=y===void 0?"no edge matches it":on(y,g);b!==null&&u(`option ${g} on recovery: ${b}`)}}(c.edges.length===0||c.edges.at(-1).when!=="otherwise")&&u("the last edge must be otherwise");let p=new Map;c.edges.forEach((h,g)=>{let O=`edge ${g}`;if(h.to!==ce&&!s(h.to)&&u(`${O} targets unknown step ${h.to}`),h.when==="otherwise"){g!==c.edges.length-1&&u(`${O} is otherwise but not last`);return}if(h.when.length===0){u(`${O} has no conditions (use otherwise)`);return}let y=new Map;for(let{field:x,equals:S}of h.when){y.has(x)&&y.get(x)!==S&&u(`${O} tests ${x} for two different values`),y.set(x,S);let L=_i(x,S,c,f,l,w);L!==null&&u(`${O}: ${L}`)}let b=U([...y].sort(([x],[S])=>x<S?-1:x>S?1:0)),k=p.get(b);k!==void 0?u(`${O} repeats the predicate of edge ${k}`):p.set(b,g)})}if(s(n.entry)){let a=new Set([n.entry]),c=[n.entry];for(let d=c.shift();d!==void 0;d=c.shift())for(let{to:u}of t[d].edges)u!==ce&&s(u)&&!a.has(u)&&(a.add(u),c.push(u));for(let d of Object.keys(t))a.has(d)||e.push(`steps.${d}: not reachable from the entry ${n.entry}`)}return e}function _i(n,e,t,i,s,r){let o=mt(n);if(o===void 0)return`${n} is not a JSON Pointer`;let[a,c,...d]=o;if(a==="outputs"){if(c===void 0||!i.has(c))return`${n} names no participant the step assigns`;let u=t.assignments.find(l=>l.participant===c).output,f=ae(u,d);return f.length===0?`${n} is not a field of ${c}'s output`:f.some(l=>v.safeParse(l,e).success)?null:`${n} can never equal ${JSON.stringify(e)}`}if(a==="decision"&&d.length===0&&xi.includes(c))switch(c){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 wt(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:a}]of Object.entries(n.steps)){let c=`steps.${s}`;r!==null&&!e.restrictions.has(r)&&i(c,"restriction",r);for(let d of Object.values(o))"evidence"in d&&!e.evidence.has(d.evidence)&&i(c,"evidence provider",d.evidence);for(let{checks:d}of a)for(let u of d)e.checks.has(u)||i(c,"check provider",u)}return[...new Set(t)]}var Ei=(n,e,t)=>(n.counts.get(t)??0)>=e.steps[t].maxAttempts;function kt(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 bt={required:[],allowed:[]};function R(n,e){let t=n.current;if(_(n)&&t!==null&&t.recovery!==null&&t.recovery.decision===null)return qi(n,e,t);let i=kt(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 a=(d,u)=>({id:Qe(s.entered.attempt,d),attempt:s.entered.attempt,reason:d,result:r.revision,subject:tn(n,s),actions:{cleanupPending:!1,verdicts:["approve","revise"],options:an(e,r.step,d),restart:{retry:bt,options:Object.fromEntries(an(e,r.step,d).map(f=>[f,bt]))}},detail:u});if(o.gate)return a("gate",{});let{to:c}=be(o.edges,{outputs:r.outputs,decision:null});return c!==ce&&Ei(n,e,c)?a("exhaustion",{blocked:{from:r.step,to:c}}):null}var an=(n,e,t)=>(n.steps[e]?.options??[]).filter(({on:i})=>i.includes(t)).map(({name:i})=>i);function qi(n,e,t){let i=t.recovery,s=u=>{let f=e.participants[u];return f?.context==="isolated"&&f.lifetime==="instance"},r=u=>[...new Set(u)].sort(),o=r(t.assignments.map(({participant:u})=>u).filter(s)),a=r([...n.attempts.values()].flatMap(({assignments:u})=>u.filter(({context:f})=>f==="isolated").map(({participant:f})=>f))).filter(s),{step:c}=t.entered,d=an(e,c,"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:d,restart:{retry:{required:[],allowed:o},options:Object.fromEntries(d.map(u=>[u,{required:[],allowed:a}]))}},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:a})=>({required:a.filter(c=>e.uncontinuable.has(c)),allowed:a}),{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(([a,c])=>[a,r(c)]))}}}}function vt(n,e,t,i,s,r){let o=n.instance,a=Ee(o,i);if(t===ce)return{kind:"transition",row:{op:"completed",transition:a,cause:i}};let c=Re(n,e,{instance:o,step:t,cause:i,activation:qe(a),deciding:r,evidence:s});return"needs"in c?{kind:"needs",needs:c.needs}:"refused"in c?{kind:"refused",reason:c.refused}:{kind:"transition",row:c.row}}function X(n,e,t){let i=kt(n);if(i===void 0||R(n,e)!==null)return{kind:"none"};let{result:s}=i,r=be(e.steps[s.step].edges,{outputs:s.outputs,decision:null});return vt(n,e,r.to,{kind:"routed",result:s.revision},t)}function yt(n,e,t,i,s){let{operationId:r,verdict:o,option:a,feedback:c}=t;if(new Set(t.restart).size!==t.restart.length)return{kind:"refused",reason:"the restart list names a participant twice"};let d=[...t.restart].sort(),u=n.operations.get(r);if(u!==void 0)return u.op==="decided"&&u.decision===t.decision&&u.verdict===o&&u.option===a&&u.feedback===c&&u.restart.length===d.length&&u.restart.every((S,C)=>S===d[C])?{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:x,unresolved:S}=i.cleanup;return{kind:"refused",reason:`the recovery's cleanup is not established yet: ${[...S,...x].join("; ")}`}}if(!l.actions.verdicts.includes(o))return{kind:"refused",reason:`${o} is not offered on a ${l.reason} decision`};if(a!==null){if(o==="approve")return{kind:"refused",reason:"an option accompanies only revise"};if(!l.actions.options.includes(a))return{kind:"refused",reason:`option ${a} is not declared for a ${l.reason} decision`}}let w=a===null?l.actions.restart.retry:l.actions.restart.options[a],p=d.filter(x=>!w.allowed.includes(x));if(p.length>0)return{kind:"refused",reason:`this decision cannot restart ${p.join(", ")}`};let h=w.required.filter(x=>!d.includes(x));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 g={reason:l.reason,verdict:o,option:a,feedback:c},O=n.attempts.get(l.attempt),y=e.steps[O.entered.step],b;if(l.result!==null)b=be(y.edges,{outputs:n.results.get(l.result).outputs,decision:g}).to;else if(a===null)b=O.entered.step;else{let x=be(y.edges,rn(a,c)),S=on(x,a);if(S!==null)return{kind:"refused",reason:`option ${a} cannot route a recovery: ${S}`};b=x.to}let k=vt(n,e,b,{kind:"decision",decision:l.id},s,{result:l.result,id:l.id,decision:g,restart:d});return k.kind==="needs"?k:k.kind==="refused"?{kind:"refused",reason:`the selected step ${b} cannot be entered: ${k.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:a,feedback:c,restart:d},k.row]}}function $t(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 Ot=()=>({managed:!1,claims:new Map,submissions:new Map,accepted:new Map,reminded:new Map,calls:new Map,response:null,answer:te.init()}),ke=je({key:"lagent:workflows/participant",init:Ot,apply(n,e){if(e.type==="thread/spawned"){if(e.data.fork!==null)return Ot();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=te.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=Z.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=_e(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 dn(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 a=e.claims.get(r),c=[...e.submissions].filter(([p,h])=>a!==void 0&&p>a&&h.assignment===i),d=p=>({assignment:i,thread:s,task:r,generation:o,outcome:p});for(let[p,{output:h}]of c){let g=e.accepted.get(p);if(g!==void 0)return d({kind:"accepted",submission:p,ending:g,output:G(h)})}let u=c.at(-1),f=u===void 0?null:{submission:u[0],output:G(u[1].output)},l=t?.latestText??null,w=t?.settlement??null;switch(w?.kind){case void 0:return d({kind:"unfinished",candidate:f,report:l});case"failed":return d({kind:"ended",settlement:"failed",detail:w.why,candidate:f,report:l});case"stopped":{let p=t?.stop==null?"":` (stopped by ${t.stop.by==="person"?"the user":t.stop.by})`;return d({kind:"ended",settlement:"stopped",detail:`${w.reason}${p}`,candidate:f,report:l})}case"completed":return d({kind:"ended",settlement:"completed",detail:"it answered without its answer being an accepted submission of the assignment",candidate:f,report:w.output})}}function xt(n,e){let t=Q(e).flatMap(r=>{if(!n.isLoaded(r.thread))return[];let o=fe(n,T,{taskId:r.task,childId:r.thread});return[dn(r,n.state(ke,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 jt(n,e,t,i){let s=Q(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)||fe(n,T,o)!==null))return null;let a=s.flatMap(f=>{if(f===r||!n.isLoaded(f.thread))return[];let l=fe(n,T,{taskId:f.task,childId:f.thread});return[dn(f,n.state(ke,f.thread),l)]}),{id:c,thread:d,generation:u}=r;return{op:"observed",observations:[{assignment:c,thread:d,task:o.taskId,generation:u,outcome:{kind:"refused",detail:i}},...a]}}function Q(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 St(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,a=Q(e);if(!o&&a.length===0)return null;let c=a.flatMap(d=>{if(n.summary(d.thread)===void 0)return[];let u=fe(n,T,{taskId:d.task,childId:d.thread});return[dn(d,n.state(ke,d.thread),u)]});return{op:"stopped",attempt:s.entered.attempt,reason:i,observations:c}}import{scopeOf as Ti}from"@leuduan/cordis";import{z as We}from"zod";var ln=We.strictObject({allow:We.array(We.string()),denial:We.string().optional()}),_t=n=>n.source_seq,de=(n,e)=>n!==null&&n.caller_thread_id===e&&n.cause.kind==="assignment"&&n.cause.owner===T;function ne(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(!F(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 a=t[o];if(de(a.origin,s)){let c=n.journal.state(ke,a.thread_id);if(o===0)return{root:s,state:r,kind:"participant",thread:a.thread_id,facts:c};let d=_t(t[o-1].origin);return{root:s,state:r,kind:"descendant",source:{kind:"participant",thread:a.thread_id,facts:c,seq:d}}}if(o===t.length-2)return{root:s,state:r,kind:"descendant",source:{kind:"root",seq:_t(a.origin)}}}}}var qt=(n,e)=>_(n)&&n.current?.assignments.includes(e)===!0&&e.state!=="accepted"&&e.state!=="superseded";function K(n){if(!(!_(n)||n.current===null))return n.current.assignments.find(e=>e.context==="conversation"&&qt(n,e))}function Mi(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 ee(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 a=t.claims.get(o.task);a===void 0||i!==void 0&&a>i||(s===void 0||a>s.claimed)&&(s={assignment:o,claimed:a})}return s?.assignment}function Ri(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 Ci(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=K(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`}:Tt(n,i,e,s)}function un(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"}:qt(n,t)?i!==null&&Ri(i,t)?{kind:"closed",why:`workflow assignment ${t.id} was accepted`}:Tt(n,s,e,t):{kind:"closed",why:`workflow assignment ${t.id} has ended`}}function Tt(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 Ci(i,e,t);case"participant":return un(i,e,ee(i,n.thread,n.facts,t),n.facts);case"descendant":{let{source:s}=n;if(s.kind==="participant")return un(i,e,ee(i,s.thread,s.facts,s.seq),s.facts);let r=Mi(i,s.seq);return r!==void 0?un(i,e,r,null):{kind:"coordination",why:"it was started while its conversation coordinated"}}}}var B=n=>({decision:"deny",reason:n});function Ai(n,e){if(n.kind==="root"){let r=K(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 ee(n.state,n.thread,t,void 0)}function Et(n,e,t){if(!n.allow.includes(e))return B(n.denial??`${e} is not allowed while ${t}.`)}function Ni(n,e,t,i,s){let r=i.name===N,o=()=>r?B("No workflow assignment of yours is active, so there is nothing to submit."):void 0;if(n.journal.summary(t)===void 0)return o();let a=ne(n,t);if(a===void 0)return o();if("unreadable"in a)return B(a.unreadable);if(a.state.terminal!==null)return o();let c=n.journal.state(ie,t),d=s===void 0?void 0:c.executions.get(s.requestSeq);if(s!==void 0&&(d===void 0||d.request.owner!==s.owner||d.request.candidate_seq!==s.candidateSeq||c.answerCheck.status!=="pending"||c.answerCheck.seq!==s.candidateSeq||d.request.operation.name!==i.name||JSON.stringify(d.request.operation.arguments)!==JSON.stringify(i.arguments)))return B("Runtime preparation no longer belongs to this pending workflow candidate.");let u=s?.requestSeq??c.dispatchedCalls.get(i.call_id),f=s===void 0?Ai(a,u):void 0;if(f!==void 0)return B(`Not run: this response already submitted assignment ${f.id}, and that submission is its answer, so the calls after it do not run.`);let l=fn(a,e,u);if(l.kind==="closed")return B(r?`Nothing can be submitted now: ${l.why}.`:`This thread works under a workflow, and no workflow authority covers this call: ${l.why}.`);if(l.kind==="coordination")return r?B(`Nothing can be submitted now: ${l.why}.`):Et(e.coordination,i.name,l.why);if(r){if(l.assignment.thread!==t)return B(`Only the participant working assignment ${l.assignment.id} may submit it.`);let w=i.arguments.assignmentId;return w===l.assignment.id?void 0:B(`Your active assignment is ${l.assignment.id}; ${JSON.stringify(w)} is not.`)}return l.restriction===null?void 0:Et(l.restriction,i.name,`assignment ${l.assignment.id} is active`)}function Mt(n,e){n.on("lagent/tool/authorize",({toolCall:t,threadId:i,origin:s})=>Ni(n,e,i,t,s)),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&&de(i.origin,s.thread_id)?s:void 0;if(r===void 0||!F(r))return;let o=()=>{if(!n.journal.isLoaded(r.thread_id))return!1;let c=n.journal.state(q,r.thread_id);return c.opened===null||c.terminal!==null};if(o())return;let a=Ti(t.ctx);t.ctx.effect(()=>{let c=n.tools.grant(a,[t.agentName],N),d=n.journal.subscribe(u=>{c===null||u.thread_id!==r.thread_id||!o()||(c(),c=null)});return()=>{d(),c?.()}})})}function ve(n,e,t){let i=[],s=[];for(let r of t){let o=r===e?"":`thread ${r}, `,a=In(n,r,{descendants:!1});i.push(...a.draining.map(c=>`${o}${c}`)),s.push(...a.unresolved.map(c=>`${o}${c}`));for(let c of He(n.journal,r))i.push(`${o}the stop of ${c.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:a})=>t.has(a));o.length>0&&i.push(`the stop of ${o.length} agent task(s) has not finished`)}for(let r of re(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 Pe(n,e,t){let i=new Set;for(let s of n.subtree(e,{self:!0})){let{origin:r}=s,o=r!==null&&!de(r,t)&&i.has(r.caller_thread_id);(s.thread_id===e||o)&&i.add(s.thread_id)}return i}function Rt(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:g})=>g),h=ve(n,i,new Set(p));return{cleanup:{draining:[...h.draining,...o],unresolved:h.unresolved},uncontinuable:s}}let a=e.current;if(a?.recovery==null||a.recovery.decision!==null)return{cleanup:{draining:[],unresolved:[]},uncontinuable:s};let c=new Set;for(let{context:p,thread:h}of a.assignments)if(p==="isolated")for(let{thread_id:g}of n.journal.origins.subtree(h,{self:!0}))c.add(g);let d=a.assignments.some(({context:p})=>p==="conversation");if(d)for(let p of Pe(n.journal.origins,i,i))c.add(p);let u=ve(n,i,c),f=[...u.draining,...o],l=[...u.unresolved];if(d){let{pending:p,runs:h}=n.journal.state(ie,i).requests,g=p===null?void 0:h.get(p.runId)?.requestedAt;g!==void 0&&g<=a.recovery.seq&&f.push(`the conversation's run ${p.runId}, under way when its assignment was superseded, has not ended`)}let w=n.get("delegations");for(let[p,h]of nn(e)){if(!r.has(h))continue;let g=y=>{f.push(`whether ${p}'s conversation can be continued is not known yet: ${y}`)};if(w===void 0){g("delegations is not mounted");continue}if(!n.journal.isLoaded(h)){g("it is not loaded");continue}let O=w.continuation(h);O!==null&&(O.kind==="refusal"?s.set(p,O.reason):O.kind==="wait"?f.push(`${p}: ${O.reason}`):l.push(`${p}: ${O.reason}`))}return{cleanup:{draining:f,unresolved:l},uncontinuable:s}}var Wi="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:a,outcome:c})=>c.kind==="ended"||c.kind==="refused"?[a]:[]));if(i===null||s.size===0)return[];let r=new Map(re(n.journal,i).flatMap(a=>a.state!=="unavailable"&&(a.state==="open"||a.draining)?[[a.taskId,a]]:[])),o=Q(e).flatMap(({task:a,thread:c})=>a===null||s.has(a)||r.get(a)?.childId!==c?[]:[{taskId:a,childId:c}]);return o.length===0?[]:[Fn(i,Wi,o)]}import{z as Ie}from"zod";var hn=Ie.string().min(1),mn=Ie.record(hn,Ie.strictObject({provider:hn,model:hn,thinkingEffort:xe.nullable()}));function gn(n,e,t){let i=mn.safeParse(e);if(!i.success)throw new E(`The model choices are invalid: ${Ie.prettifyError(i.error)}`);let s=i.data;for(let[o,a]of Object.entries(s)){let c=n.participants[o];if(c===void 0)throw new E(`The workflow has no participant ${o}`);if(c.context==="conversation")throw new E(`Participant ${o} runs on the conversation's route: it takes no model choice (${a.provider}/${a.model})`);if(!c.model.configurable)throw new E(`Participant ${o} runs on the model its workflow fixes`)}let r={};for(let[o,a]of Object.entries(n.participants)){if(a.context!=="isolated")continue;let c=s[o],{model:d}=a,u=c===void 0?{provider:d.provider,model:d.model,thinkingEffort:d.thinkingEffort??null}:{provider:c.provider,model:c.model,thinkingEffort:c.thinkingEffort};if(!t.includes(u.provider))throw new E(`Participant ${o}: model provider ${u.provider} is not offered by the host`);r[o]=u}return r}var E=class extends Error{constructor(e){super(e),this.name="WorkflowRefusedError"}};import{z as Le}from"zod";var Pi=Le.strictObject({instance:Le.string().min(1),status:Le.enum(["assignment","decision","blocked","cleanup","ended"]),subject:Le.string().nullable()}),Ii=se({plugin:"lagent:workflows",kind:"presentation",version:1,schema:Pi});function Li(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 a=new Set(t.claimed.map(({id:d})=>d)),c=i.current.assignments.find(d=>d.thread===r&&d.state!=="accepted"&&d.state!=="superseded"&&(a.has(d.task)||ee(i,r,s,void 0)===d));return c===void 0?void 0:{instance:o,status:"assignment",subject:c.id}}function Di(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=K(n);if(r!==void 0){if(r.state!=="scheduled")return{instance:i,status:"assignment",subject:r.id};let a=Ge(r);return t.claimed.some(({id:c})=>c===a)?{instance:i,status:"assignment",subject:r.id}:void 0}let o=X(n,e);return o.kind==="refused"?{instance:i,status:"blocked",subject:o.reason}:void 0}function At(n,e){let t=i=>{if(n.journal.summary(i)===void 0)return;let s=ne(n,i);return s===void 0||"unreadable"in s?void 0:s};Wn(n,{event:Ii,rank:2,current:i=>{let s=t(i.threadId);if(s===void 0)return;let r=e.executable(s.state);return s.kind==="participant"?Li(s,r,i):s.kind==="root"?Di(s.state,r,i):void 0},render:(i,s,{step:r})=>{let o=n.journal.state(q,i.instance),a=e.executable(o);if(r.threadId!==i.instance){let f=o.current.assignments.find(({id:l})=>l===i.subject);return H("workflow",Ct(o,a,f,e),{attrs:{id:i.instance,status:i.status}})}let c=o.opened.definition,d=f=>H("workflow",f,{attrs:{id:i.instance,status:i.status}}),u=`Until then you work under the coordination policy: ${zi(e.coordination)}`;switch(i.status){case"assignment":{let f=K(o);return d(Ct(o,a,f,e))}case"decision":{let{recovery:f}=o.current;return d(f!==null?Fi(c,o.current,i.subject,u):`Workflow ${c}: 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. `+u)}case"blocked":return d(`Workflow ${c} cannot go on: ${i.subject}. ${u}`);case"cleanup":return d(`Workflow ${c} is being cancelled. ${u}`);case"ended":return s===null||s.status==="ended"?null:d(`Workflow ${c} ${i.subject==="completed"?"is complete":"was cancelled"}: its restrictions no longer apply, and this conversation goes on as ordinary chat.`)}}})}var wn=(n,e)=>JSON.stringify(n,null,e).replaceAll("<","\\u003c"),De=n=>jn(n,["workflow"]);function Fi(n,e,t,i){let s=e.recovery,{step:r,ordinal:o}=e.entered,a=[`Workflow ${n}: attempt ${o} of step ${r} cannot finish (${s.cause==="stop"?"stopped":"failed"}: ${De(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}`],c=Nt(s,null);return c.length>0&&a.push("","Unaccepted, shown to you as its coordinator only:",...c),a.join(`
|
|
4
|
+
`)}function Nt(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: ${wn(r)}`);for(let[s,r]of Object.entries(n.reports))i(s)&&t.push(`- ${s}'s partial report, not accepted: ${De(r)}`);return t}var zi=n=>n.allow.length===0?"no tool may be called.":`you may call only ${n.allow.join(", ")}; any other call is denied.`,Ui=n=>n===null?`Tools: no step restriction; ${N} is available.`:`Tools: ${n.allow.length===0?`${N} only`:[...n.allow,N].join(", ")}; any other call is denied.`;function Ct(n,e,t,i){let s=n.current,{step:r,ordinal:o}=s.entered,a=e.steps[r],c=a.assignments.find(({participant:l})=>l===t.participant),d=[`Workflow ${e.id}, step ${r}, attempt ${o}. Submit with ${N}, assignmentId "${t.id}".`],u=Bi(n,s,t.participant);u!==null&&d.push("",u);for(let l of c.reads){let w=s.entered.inputs[l]??null,p=wn(Me(n,s.entered,l),2);d.push("",H("input",p,{namespace:"workflow",attrs:{name:l,citation:Ji(n,w)}}))}d.push("",H("output-schema",wn(c.output),{namespace:"workflow"})),d.push("",Ui(a.restriction===null?null:i.restrictions[a.restriction]));let f=Ki(n,t);return f.length>0&&(d.push("","Superseded since your previous assignment, so do not rely on them as you remember them:"),d.push(...f.map(l=>`- ${l}`))),[H("step-guidance",c.prompt,{namespace:"workflow"}),H("step-input",d.join(`
|
|
5
|
+
`),{namespace:"workflow"})].join(`
|
|
6
|
+
|
|
7
|
+
`)}function Wt({reason:n,verdict:e,option:t}){return n==="recovery"?t===null?"retried":"recovered":e==="approve"?"approved":"sent back"}function bn(n,e){let t=`step ${n} was ${Wt(e)}${e.option===null?"":` (${e.option})`}`;return e.feedback===null?`${t}.`:`${t}, with this feedback:
|
|
8
|
+
${H("feedback",De(e.feedback),{namespace:"workflow"})}`}function Ji(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?"":`, ${Wt(s)}`;return`${i} of step ${t.step}, revision ${t.revision}, ${e.mode}${r}`}function Bi(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=[`This attempt was opened when ${bn(r.entered.step,s)}`];if(r.recovery===null)return o.join(`
|
|
9
|
+
`);o.push(`That attempt could not finish: ${De(r.recovery.detail)}.`);let a=Nt(r.recovery,t);return a.length>0&&o.push("What you left in it, not accepted:",...a),o.join(`
|
|
10
|
+
`)}function Ki(n,e){let t=null;for(let o of n.attempts.values()){if(o===n.current)break;for(let a of o.assignments)a.participant===e.participant&&(a.context==="isolated"?t=o.seq:a.claimSeq!==null&&(t=a.claimSeq))}if(t===null)return[];let i=oe(n),s=nt(n,t),r=[...n.results.values()].filter(({revision:o})=>!i.has(o));return[...i].filter(o=>!s.has(o)).map(o=>{let{step:a}=n.results.get(o),c=r.filter(d=>d.step===a).at(-1);return c===void 0?`${o} (step ${a}) is no longer current`:`${o} (step ${a}) is replaced by ${c.revision}`})}var Fe=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=Pt(this.ctx,e),s=new Map;for(let r of kn(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 a=new AbortController;this.inFlight.set(r.task,{root:e,assignment:r.id,controller:a});let c=this.start(e,r.id,a.signal).catch(d=>{this.of(e).set(r.id,{kind:"hold",reason:`assignment ${r.id} cannot start its task: ${le(d)}`}),this.ctx.reportError(d)}).finally(()=>{this.inFlight.delete(r.task),this.running.delete(c);let d=this.outcomes.get(e)?.get(r.id);this.options.ended(e,d===void 0),d!==void 0&&!(d.kind==="wait"&&d.on==="capacity")&&this.retryCapacity(e)});this.running.add(c)}}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=Pt(this.ctx,e);return kn(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(u=>u.id===t);if(o===void 0)return;let a=this.handle;if(a===void 0){this.of(e).set(t,{kind:"hold",reason:"delegations, which starts isolated participants, is not mounted"});return}let c=this.request(r,o,i);if("hold"in c){this.of(e).set(t,{kind:"hold",reason:c.hold});return}let d=await a.start(c);d.kind==="refusal"?await this.options.refused(e,t,d.reason):this.settle(e,o,d)}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:a}=t,c=s.pins.participants[a];if(t.lifetime===null||c?.configuration==null)throw new Error(`Assignment ${t.id} names no isolated participant the instance pinned`);let d=[];for(let u of t.checks){let f=this.options.providers.problem("check",u,c.checks[u]);if(f!==null)return{hold:f};d.push(this.options.checks[u].owed({config:c.checks[u].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:a,lifetime:t.lifetime,generation:t.generation,configuration:Vi(c,this.options.checks),task:`Workflow ${r.id}: assignment ${t.id} (step ${o}) is yours; its instructions come with your next step.`,...d.length===0?{}:{rows:Hi(d)},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 d=this.options.runnable(i);return d==="allow-all"?{kind:"allow"}:Array.isArray(d)?d.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: ${d.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=kn(r).find(({id:d})=>d===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 a=this.options.executable(r);if(a===void 0)return{kind:"hold",reason:"its workflow cannot continue on the definition registered"};if(R(r,a)!==null)return{kind:"hold",reason:"a decision is pending"};let c=r.opened.pins.participants[o.participant]?.checks??{};for(let d of o.checks){let u=this.options.providers.problem("check",d,c[d]);if(u!==null)return{kind:"hold",reason:u}}return{kind:"allow"}}};function kn(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 Pt(n,e){return new Set(re(n.journal,e).flatMap(t=>"taskId"in t?[t.taskId]:[]))}function It(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 Vi(n,e){let{agent:t,route:i,environment:s,installations:r}=n.configuration,o=new Set(Object.keys(n.checks).flatMap(a=>e[a]?.requires??[]));return{agent:t,route:i,environment:s,installations:r.map(({installation_id:a,preset_id:c,config:d,lifetime:u})=>({installationId:a,presetId:c,config:d,lifetime:u})),requires:[...o].sort()}}function Hi(n){return e=>{let t=[];for(let i of n){let s=i(e);if(qn(s))return s;t.push(...s)}return t}}import{z as Lt}from"zod";var vn=n=>typeof n=="function",Dt=n=>{if(typeof n!="object"||n===null)return!1;let e=n;return["unavailable","validate","pin","subscribe"].every(t=>vn(e[t]))},Ft=Lt.custom(n=>Dt(n)&&vn(n.owed)&&Array.isArray(n.requires),{error:"Expected a check provider binding"}),zt=Lt.custom(n=>Dt(n)&&vn(n.acquire),{error:"Expected an evidence provider binding"}),ze=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 a=s.unavailable();return a===null?null:`${r} is unavailable: ${a}`}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 a;try{a=await this.tracked(ye(e,t),s,c=>r.pin(i,c))}catch(c){if(c instanceof V)throw c;a={refused:c instanceof Error?c.message:String(c)}}return"refused"in a?{refused:`${e} provider ${t} refuses this opening: ${a.refused}`}:{config:a.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 V)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 V(r.reason);let o=i(r),a={key:e,controller:s,done:o};this.inFlight.add(a),o.then(()=>this.inFlight.delete(a),()=>this.inFlight.delete(a));try{return await Promise.race([o,Qi(r)])}catch(c){throw r.aborted?new V(r.reason):c}}},V=class extends Error{constructor(e){super(`Cancelled: ${e instanceof Error?e.message:String(e)}`,{cause:e}),this.name="CancelledError"}},ye=(n,e)=>`${n}:${e}`,Qi=n=>new Promise((e,t)=>{n.aborted?t(n.reason):n.addEventListener("abort",()=>t(n.reason),{once:!0})});function Yi(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 a=K(n),c=a===void 0?null:ot(n,a);return a===void 0||c===null?void 0:{assignment:a,epoch:c,submitted:a.candidate?.seq===i,reminded:a.reminded}}if(e.kind!=="participant")return;let{facts:r}=e,o=ee(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 Ut(n,e){let t=(i,s)=>{let r=ne(n,i);if(r===void 0||"unreadable"in r)return null;let o=Yi(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:a,epoch:c}=o;if(o.reminded===c)return o.kind==="root"?void 0:Z.rejection(`Assignment ${a} was answered without its submission after the one reminder, so its task fails and the workflow's recovery decides what comes next.`,{assignment:a,epoch:c});let d=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:Z.contribution({content:`Your workflow assignment ${a} is still open, and a reply does not finish it: submit its output with ${N} ({ "assignmentId": "${a}", "output": ... }), matching the schema it was presented with. ${d}`},{assignment:a,epoch:c})}})}import{z as yn}from"zod";function Gi(n,e,t){let{draining:i,unresolved:s}=ve(n,t,Pe(n.journal.origins,t,e.root));return[...i,...s]}var Zi=yn.strictObject({assignmentId:yn.string().min(1).describe("The id of the assignment this output answers, as it was presented."),output:A.describe("The assignment's output, matching the JSON Schema it was presented with.")});function Jt(n,e){return An({name:N,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}),a=ne(n,s);if(a===void 0||"unreadable"in a||!_(a.state))return o("no workflow assignment of yours is active.");let c=fn(a,e,r);if(c.kind!=="assignment")return o(`${c.why}.`);let{assignment:d}=c;if(d.thread!==s)return o(`only the participant working ${d.id} may submit it.`);if(d.id!==t)return o(`your active assignment is ${d.id}, not ${JSON.stringify(t)}.`);let u=Gi(n,a,s);if(u.length>0)return o(`work you started has not ended: ${u.join("; ")}. Wait for it to end, or stop it, then submit again.`);let{state:f}=a,l=e.executable(f),w=f.current.entered.step,p=Ne(l,{step:w,participant:d.participant}).safeParse(i);return p.success?{output:`Submitted the output of assignment ${d.id}. It is accepted when this answer is.`,metadata:Qn({assignment:d.id,output:i}),concludes_turn:!0}:o(`the output does not match the assignment's schema: ${yn.prettifyError(p.error)}`)}})}function Kt(n,e,t){let i=n.opened;if(i===null)throw new Error("No workflow instance was opened on this thread");let s=ge(me(n),e),r=s===null?e:void 0,o=r??i.canonical,a=oe(n),c=[...n.results.values()].map(k=>({revision:k.revision,step:k.step,outputs:k.outputs,decision:Te(n,k.decision),current:!a.has(k.revision),inputs:Object.fromEntries(Object.entries(n.attempts.get(k.attempt).entered.inputs).map(([x,S])=>[x,Se(S)]))})),d=i.input,u=Object.fromEntries(Object.entries(i.pins.participants).flatMap(([k,{configuration:x}])=>x===null?[]:[[k,{provider:x.route.provider,model:x.route.model,thinkingEffort:x.route.thinking_effort}]]));if(n.terminal!==null)return{definition:i.definition,input:d,models:u,status:n.terminal.kind,step:null,attempt:null,assignments:[],results:c,pending:null,blocked:null,waitingOn:null};let f=n.current,l=R(n,o),w={definition:i.definition,input:d,models:u,step:f?.entered.step??null,attempt:f===null?null:{id:f.entered.attempt,ordinal:f.entered.ordinal},assignments:(f?.assignments??[]).map(({id:k,participant:x,state:S,thread:C,task:L,generation:W})=>({id:k,participant:x,state:S,thread:C,task:L,generation:W})),results:c};if(n.cancellation!==null){let{unresolved:k}=t.barrier.cleanup;return k.length>0?{...w,status:"blocked",pending:null,blocked:{reason:"cleanup",detail:k.join("; ")},waitingOn:"cleanup"}:{...w,status:"running",pending:null,blocked:null,waitingOn:"cleanup"}}if(r===void 0)return{...w,status:"blocked",pending:l===null?null:Bt(l),blocked:{reason:"missing-binding",detail:s},waitingOn:null};let p=[...t.starts.values()].flatMap(k=>k.kind==="hold"?[k.reason]:[]),h=[...Xi(n,r,t),...p];if(h.length>0)return{...w,status:"blocked",pending:l===null?null:Bt(l),blocked:{reason:"missing-binding",detail:h.join("; ")},waitingOn:null};if(l!==null){let k=cn(l,t.barrier);if(!k.actions.cleanupPending)return{...w,status:"waiting",pending:k,blocked:null,waitingOn:"decision"};let{unresolved:x}=t.barrier.cleanup;return x.length>0?{...w,status:"blocked",pending:k,blocked:{reason:"cleanup",detail:x.join("; ")},waitingOn:"cleanup"}:{...w,status:"waiting",pending:k,blocked:null,waitingOn:"cleanup"}}let g=X(n,r),O=g.kind==="refused"?g.reason:g.kind==="needs"&&t.entryRefusal?.transition===g.needs.transition?t.entryRefusal.reason:null;if(O!==null)return{...w,status:"blocked",pending:null,blocked:{reason:"entry-refused",detail:O},waitingOn:null};let y=[...t.starts.values()],b=t.settled&&K(n)!==void 0?"person-input":y.some(({kind:k})=>k==="starting"||k==="wait")?"dispatch":y.length>0?"participant":null;return{...w,status:"running",pending:null,blocked:null,waitingOn:b}}function Xi(n,e,t){let i=[],s=n.current;if(s!==null){for(let{participant:a,checks:c,state:d}of s.assignments)if(!(d==="accepted"||d==="superseded"))for(let u of c){let f=t.provider({check:u,participant:a});f!==null&&i.push(f)}}let r=X(n,e);if(r.kind==="needs")for(let{provider:a}of r.needs.inputs){let c=t.provider({evidence:a});c!==null&&i.push(c)}let o=r.kind==="needs"?r.needs.step:r.kind==="transition"&&r.row.op==="entered"?r.row.step:null;for(let{participant:a,checks:c}of o===null?[]:e.steps[o].assignments)for(let d of c){let u=t.provider({check:d,participant:a});u!==null&&i.push(u)}return[...new Set(i)]}var Bt=n=>({...n,actions:{...n.actions,verdicts:[],options:[],restart:{retry:{required:[],allowed:[]},options:{}}}});var ns=$.strictObject({definitions:$.array($.custom(ht,{error:"Expected a definition made by defineWorkflow"})),restrictions:$.record($.string().min(1),ln),coordination:ln,prerequisites:$.record($.string().min(1),$.custom(n=>typeof n=="function",{error:"Expected a prerequisite check"})),roles:$.record($.string().min(1),$.custom(n=>typeof n=="function",{error:"Expected a role binding"})),modelProviders:$.array($.string().min(1)),checks:$.record($.string().min(1),Ft),evidence:$.record($.string().min(1),zt)}),z=$.string().min(1),ts=$.strictObject({id:z,inputId:z,definition:z,input:A,conversation:$.strictObject({environment:$.strictObject({cwd:$.string()}),installations:$.array($.custom())}),models:mn.optional(),signal:$.instanceof(AbortSignal).optional()}),is=$.strictObject({operationId:z,instanceId:z,decision:z,verdict:$.enum(["approve","revise"]),option:z.optional(),feedback:$.string().optional(),restart:$.array(z).optional()}),ss=$.strictObject({operationId:z,instanceId:z,reason:$.string()}),rs=3,Oe=class extends Error{constructor(e){super(`The workflow changed while its Stop was prepared: ${e}`),this.name="StaleStopError"}},os=3,Vt="stale-wake",Ht="A workflow opens only on a new root conversation, never on a fork or a delegated thread",as=3,$n=new AbortController().signal,$e="The workflow instance could not be repaired",Ue=Pn({key:"workflow",version:1,schema:$.strictObject({references:$.strictObject({id:$.string(),step:$.string().nullable(),participants:$.record($.string(),$.strictObject({context:$.enum(["conversation","isolated"]),open:$.boolean()}))}),terminal:$.boolean(),checks:$.array($.strictObject({thread:$.string(),check:$.string(),pin:$.strictObject({config:A}).nullable()})),runnable:$.array($.string())}).nullable(),applies:F,compute(n,e){let t=n.state(q,e);return t.opened===null?null:{references:me(t),terminal:t.terminal!==null,checks:ds(t),runnable:t.cancellation===null?It(t):[]}}}),Je=class extends es{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=ns.parse(t);let{definitions:i,restrictions:s,prerequisites:r,roles:o,checks:a,evidence:c}=this.config,d={restrictions:new Set(Object.keys(s)),prerequisites:new Set(Object.keys(r)),roles:new Set(Object.keys(o)),checks:new Set(Object.keys(a)),evidence:new Set(Object.keys(c))};this.providers=new ze({checks:a,evidence:c});let u=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 g=wt(p,d);if(Object.values(p.participants).some(({context:y})=>y==="isolated")&&!u&&g.push("isolated participants run as delegation tasks: mount delegations before workflows"),g.length>0)throw new J(h,g);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:g})=>({id:p,input:h,participants:Object.fromEntries(Object.entries(g).flatMap(([O,y])=>y.context==="isolated"?[[O,{provider:y.model.provider,model:y.model.model,thinkingEffort:y.model.thinkingEffort??null,configurable:y.model.configurable}]]:[])),modelProviders:l}))),this.participants=new Fe(e,{providers:this.providers,checks:a,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,g)=>this.refused(p,h,g)}),e.effect(()=>e.journal.register(q));let w={restrictions:s,coordination:this.config.coordination,executable:p=>this.executable(p)};At(e,w),Mt(e,w),Nn(e,Jt(e,w)),Ut(e,w),this.refreshed=Ue.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()),Mn(e,()=>this.shutdown())}catalog(){return this.entries}definition(e){return this.registered.get(e)}async opening(e){let t=ts.parse(e),{id:i,inputId:s,definition:r,input:o,models:a={},signal:c=$n}=t,d=this.definition(r);if(d===void 0)throw new E(`No workflow ${r} is registered`);let u=Ne(d,"$input").safeParse(o);if(!u.success)throw new E(`The input does not match the workflow's input schema: ${$.prettifyError(u.error)}`);let f=this.proposed(t.conversation),l=gn(d,a,this.config.modelProviders),w=await this.pins(d,f,l,c),p=Vn(d,o,s,w),h={...q.init(),instance:i,opened:p},{plan:g}=await this.withEvidence(i,w,y=>{let b=Re(h,d,{instance:i,step:d.entry,cause:{kind:"opening"},activation:s,...y===void 0?{}:{evidence:y}});return"needs"in b?{kind:"needs",needs:b.needs}:"refused"in b?{kind:"refused",reason:b.refused}:{kind:"row",...b}},c);if(g.kind==="refused")throw new E(`The entry step cannot be entered: ${g.reason}`);let O=[p,g.row];return y=>{if(y.kind==="send")throw new Error("Workflow opening rows only open a thread");let{threadId:b}=y,k=y.kind==="fork"?Ht:this.openingRefusal(d,{instance:i,inputId:s,conversation:f},y)??this.pinsProblem(w);return k!==null?{refuse:{message:k}}:O.map(x=>I.entry(x,{threadId:b}))}}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:On(e.environment),installations:t}}catch(t){throw new E(`The proposed conversation is refused: ${le(t)}`)}}async pins(e,t,i,s){let r=async(c,d,u,f)=>{let l=await this.providers.pin(c,d,u,s);if("refused"in l)throw new E(`${f}: ${l.refused}`);return l},o={};for(let[c,d]of Object.entries(e.participants)){let u=d.context==="isolated"?this.configuration(c,d,t,i[c]):null,f=u===null?t:{environment:u.environment,installations:u.installations.map(({preset_id:w,config:p,lifetime:h})=>({preset_id:w,config:p,lifetime:h}))},l={};for(let w of Object.values(e.steps))for(let p of w.assignments)if(p.participant===c)for(let h of p.checks)l[h]??=await r("check",h,f,`Participant ${c}`);o[c]={configuration:u,checks:l}}let a={};for(let c of Object.values(e.steps))for(let d of Object.values(c.inputs))"evidence"in d&&(a[d.evidence]??=await r("evidence",d.evidence,t,"Evidence"));return{participants:o,evidence:a}}configuration(e,t,i,s){let r=c=>{throw new E(`Participant ${e}: ${c}`)},o={provider:s.provider,model:s.model,thinking_effort:s.thinkingEffort},a=this.config.roles[t.role](i);if("refused"in a)return r(`role ${t.role} refuses this conversation: ${a.refused}`);for(let c of a.installations)(c.lifetime!=="defining"||c.installationId===void 0)&&r(`role ${t.role}'s installation of ${c.presetId} must be defining and name its id`);try{return{agent:a.agent,route:o,environment:On(a.environment),installations:this.ctx.presets.initialInstallations(a.installations,a.agent)}}catch(c){return r(`role ${t.role} resolves a configuration that is refused: ${le(c)}`)}}openingRefusal(e,t,i){let{threadId:s,runId:r,inputId:o,opening:a}=i;if(s!==t.instance)return`The workflow opens on thread ${t.instance}, not ${s}`;if(a.origin!==null)return Ht;let{spec:c}=a;if(!c.requires.includes(T))return`The conversation must require ${T}`;if(o!==t.inputId)return`The conversation's first input must be ${t.inputId}`;let d=e.steps[e.entry].assignments.some(({participant:f})=>e.participants[f]?.context==="conversation");if(d&&r===null)return"The conversation's creation must wake it: its entry step is its own";if(!d&&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 u={environment:On(c.environment),installations:c.installations.map(({preset_id:f,config:l,lifetime:w})=>({preset_id:f,config:l,lifetime:w}))};if(U(u)!==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](a);if(l!==null)return`Prerequisite ${f} is not met: ${l}`}return null}read(e){return this.view(e)}decide(e,t){let i=is.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<os;o+=1){let{plan:a,evidence:c}=await this.prepareDecision(s,r);if(a.kind==="replay")return this.view(s);if(a.kind==="refused")throw new E(a.reason);let[d,u]=a.rows,f=this.transition(s,u,d),l=g=>f.rootWork||En(this.ctx.journal.state(ie,g).requests),w=l(s)?{releases:!0,chain:"person"}:void 0,p=await this.send(s,f,w,({threadId:g,runId:O})=>{let y=this.quarantined(g);if(y!==null)return{refuse:{message:`${$e}: ${y}`}};let b=this.planDecision(g,r,c);if(b.kind!=="rows")return{refuse:{message:b.kind==="refused"?b.reason:"already recorded"}};let k=this.entryProblem(g,b.rows);return k!==null?{refuse:{message:`the selected step cannot be entered: ${k}`}}:U(b.rows)!==U(a.rows)?{refuse:{message:"The instance changed while the decision was written: decide again"}}:l(g)!==(O!==null)?{refuse:{message:"A Stop changed while the decision was written",code:Vt}}:b.rows.map(x=>I.entry(x,{threadId:g}))});if(p.status==="queued")return this.view(s);if(p.status==="refused"&&p.refusal.code===Vt)continue;this.refuseQuarantined(s);let h=this.planDecision(s,r,c);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}=ss.parse(e);return this.holding(s,async()=>{this.refuseQuarantined(s);let{value:o}=await this.ctx.journal.transact(s,()=>{let a=this.quarantined(s);if(a!==null)return{rows:[],value:`${$e}: ${a}`};let c=$t(this.state(s),{operationId:i,reason:r,actor:t});return{rows:c.kind==="rows"?c.rows.map(d=>I.entry(d,{threadId:s})):[],value:c.kind==="refused"?c.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),a=await this.ctx.threads.retain(()=>o.children,{lastRelease:"keep"});try{await i(c=>{if(c!==e)throw new Error(`A Stop of thread ${e} was written on ${c}`);return this.stopRows(e,t,o)});return}finally{a.release()}}catch(o){if(!(o instanceof Oe)||s+1>=rs)throw o}finally{r.release()}}}stopping(e){let t=this.ctx.journal.summary(e);if(t===void 0||!F(t)||this.quarantined(e)!==null)return{attempt:null,children:[]};let i=this.ctx.journal.state(q,e),s=Q(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 Oe(`it met attempt ${s.attempt}`);let r=s.children.filter(c=>!this.ctx.journal.isLoaded(c));if(r.length>0)throw new Oe(`${r.join(", ")} not loaded`);if(s.attempt===null||this.quarantined(e)!==null)return[];let o=this.ctx.journal.state(q,e),a=St(this.ctx.journal,o,this.procedure(o),t);return a===null?[]:[I.entry(a,{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=Kt(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 Rt(this.ctx,t,this.participants.starting(e))}executable(e){return ut(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 yt(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),$n)}catch(i){throw i instanceof V?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"}:X(i,s,t)}async advance(e){let t;try{let d=this.ctx.journal.state(q,e);if(d.opened===null)return;t=await this.withEvidence(e,d.opened.pins,u=>this.owed(e,u),$n)}catch(d){if(d instanceof V||d instanceof E)return;throw d}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),a=o.rootWork?{releases:!1,chain:"fresh"}:void 0,c=await this.send(e,o,a,()=>{let d=this.quarantined(e);if(d!==null)return{refuse:{message:`${$e}: ${d}`}};let u=this.owed(e,s);if(u.kind!=="transition"||U(u.row)!==U(r))return{refuse:{message:"The transition is no longer owed"}};let f=this.entryProblem(e,[r]);return f!==null?{refuse:{message:f}}:[I.entry(r,{threadId:e})]});c.status==="refused"&&this.entryRefusals.set(e,{transition:r.transition,reason:c.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 a=r.steps[o.step];for(let c of Object.values(a?.inputs??{})){if(!("evidence"in c))continue;let d=this.providers.problem("evidence",c.evidence,s.evidence[c.evidence]);if(d!==null)return d}for(let c of o.assignments){let{participant:d}=c;for(let u of c.context==="isolated"?c.checks:[]){let f=this.providers.problem("check",u,s.participants[d]?.checks[u]);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<as;o+=1){let a=i(r);if(a.kind!=="needs")return{plan:a,evidence:r};let{needs:c}=a,d=await Promise.all(c.inputs.map(async({input:u,provider:f})=>[u,await this.providers.acquire(f,t.evidence[f],{instance:e,attempt:c.attempt,step:c.step,input:u,signal:s})]));r={transition:c.transition,attempt:c.attempt,inputs:new Map(d)}}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:t.rootWork?"next-turn":"next-step",...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:u})=>r.participants[u]?.context==="conversation"):void 0,a=`Workflow ${r.id}:`,c=u=>a+=`${a.endsWith(">")?`
|
|
11
|
+
`:" "}${u}`;if(i!==null){let u=s.attempts.get(i.attempt).entered.step;c(bn(u,i))}else t.cause.kind==="routed"&&c(`step ${s.results.get(t.cause.result).step}'s result was accepted.`);t.op==="completed"?c("The workflow completed."):o!==void 0?c(`Step ${t.step} was assigned to you as ${o.id}.`):t.assignments.length>0&&c(`Step ${t.step} was handed to other participants.`);let d=qe(t.transition);return{row:t,input:{id:d,message:{role:"developer",content:a},source:et.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 a=this.ctx.get("commands");if(a!==void 0){let c=this.ctx.journal.origins.subtree(e,{self:!0});await Promise.all(c.map(({thread_id:d})=>a.stopAll({threadId:d},"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:a}=this.barrier(e,i).cleanup;return o.length>0||a.length>0?t:{rows:[I.entry({op:"cancelled",operation_id:i.cancellation.operation_id},{threadId:e})],value:void 0}})}governs(e){if(F(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&&F(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:`${$e}: ${s}`};let r=i===void 0?void 0:Ue.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:a}=o,c=this.definition(a.id),d=ge(a,c);if(d!==null)return{kind:"hold",reason:`Its workflow cannot continue: ${d}`};let u=t.find(({origin:f})=>de(f,i.thread_id))?.thread_id??i.thread_id;for(let{thread:f,check:l,pin:w}of o.checks){if(f!==u)continue;let p=this.providers.problem("check",l,w??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=Ue.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=Ue.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||(F(t)&&t.origin===null&&(e.type==="ext"&&this.governedChanged(e.thread_id),(I.read(e)!==void 0||e.type==="turn/end")&&this.track(this.reconcile(e.thread_id))),!cs.has(e.type)))return;let i=this.ctx.journal.origins.callers(e.thread_id).threads.at(-1),s=i?.thread_id;s===void 0||!F(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=jt(this.ctx.journal,r,t,i);if(o===null)return s;let a=o.observations[0].thread;return this.ctx.journal.summary(a)!==void 0&&this.ctx.get("delegations")?.continuation(a)?.kind!=="refusal"?s:{rows:[I.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(Q(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:xt(this.ctx.journal,r).flatMap(a=>[I.entry(a,{threadId:e}),...pn(this.ctx,r,a)]),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=>F(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=Tn(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(`${$e}: ${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)])}},cs=new Set(["turn/end","run/settled","thread/cancel","inbox/spliced","ext"]),On=n=>({cwd:Cn(n.cwd,"A conversation cwd")});function ds(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 a=e.participants[t]?.checks[o];return{thread:i,check:o,pin:a===void 0?null:{config:G(a.config)}}}))}var _o={name:"lagent:workflows",async apply(n,e){Rn(n,"workflows"),await n.plugin(Je,e)}};export{N as SUBMIT_TOOL,T as WORKFLOWS_OWNER,J as WorkflowDefinitionError,E as WorkflowRefusedError,vi as defineWorkflow,gn as resolveParticipantModels,_o as workflows};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type PluginJournal } from '../../journal/index.js';
|
|
2
|
+
import { type AnswerCheck } from '../../state/index.js';
|
|
3
|
+
import type { Seq } from '../../records/journal.js';
|
|
4
|
+
import { type AssignmentOutcome } from '../delegations/index.js';
|
|
5
|
+
import { type AssignmentView, type InstanceState, type ResponseCalls } from './state.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,28 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { WorkflowDefinition } from './definition.js';
|
|
3
|
+
import type { InstanceView } from './view.js';
|
|
4
|
+
/** Complete models a starter chose for configurable isolated participants, by participant. */
|
|
5
|
+
export declare const ModelChoicesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
6
|
+
provider: z.ZodString;
|
|
7
|
+
model: z.ZodString;
|
|
8
|
+
thinkingEffort: z.ZodNullable<z.ZodEnum<{
|
|
9
|
+
low: "low";
|
|
10
|
+
high: "high";
|
|
11
|
+
none: "none";
|
|
12
|
+
medium: "medium";
|
|
13
|
+
max: "max";
|
|
14
|
+
}>>;
|
|
15
|
+
}, z.core.$strict>>;
|
|
16
|
+
/**
|
|
17
|
+
* Every isolated participant's model for an opening: the default its definition names (an omitted
|
|
18
|
+
* effort is `null`) or the starter's complete choice, which only a configurable participant takes.
|
|
19
|
+
* `choices` is the untrusted choice map as `OpeningRequest.models` takes it. Refused, with
|
|
20
|
+
* {@link WorkflowRefusedError}, are: a choice that fails the schema, one for an unknown, conversation or
|
|
21
|
+
* fixed-model participant, and a provider outside `allowedProviders`, a definition's default
|
|
22
|
+
* included. Nothing is read or recorded: the result is fresh and its inputs are untouched.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveParticipantModels(definition: WorkflowDefinition, choices: unknown, allowedProviders: readonly string[]): InstanceView['models'];
|
|
25
|
+
/** A request the workflow refuses, with why: nothing was recorded. */
|
|
26
|
+
export declare class WorkflowRefusedError extends Error {
|
|
27
|
+
constructor(reason: string);
|
|
28
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { Context } from '@leuduan/cordis';
|
|
2
|
+
import type { WorkflowDefinition } from './definition.js';
|
|
3
|
+
import { type InstanceState } from './state.js';
|
|
4
|
+
import type { CheckProvider, Providers } from './hostBindings.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[];
|