@jr2/orchestrator 0.4.1 → 0.5.1
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/README.md +20 -2
- package/console/components/app.ts +2 -0
- package/console/components/fleet.ts +14 -1
- package/console/components/machine-pane.ts +41 -2
- package/console/main.ts +13 -1
- package/console/store.ts +102 -6
- package/console/style.css +21 -0
- package/docs/agents-block.md +5 -0
- package/docs/concepts/agents-and-turns.md +442 -0
- package/docs/concepts/architecture.md +230 -0
- package/docs/concepts/charts.md +143 -0
- package/docs/concepts/composition.md +357 -0
- package/docs/concepts/converge.md +254 -0
- package/docs/concepts/durable-runs.md +189 -0
- package/docs/concepts/effects.md +603 -0
- package/docs/concepts/gates.md +208 -0
- package/docs/concepts/machines-and-workflows.md +289 -0
- package/docs/concepts/pools-and-sources.md +230 -0
- package/docs/concepts/secrets-and-trust.md +222 -0
- package/docs/concepts/the-menu.md +378 -0
- package/docs/concepts/workspaces.md +678 -0
- package/docs/get-started/a-model-decides.md +563 -0
- package/docs/get-started/an-agent-in-a-sandbox.md +381 -0
- package/docs/get-started/connect-a-model.md +248 -0
- package/docs/get-started/create-an-instance.md +194 -0
- package/docs/get-started/have-your-assistant-write-a-machine.md +922 -0
- package/docs/get-started/install.md +126 -0
- package/docs/guides/add-tools-to-the-sandbox.md +295 -0
- package/docs/guides/answer-a-gate.md +304 -0
- package/docs/guides/bind-open-parts.md +223 -0
- package/docs/guides/cancel-a-run.md +146 -0
- package/docs/guides/clean-up.md +206 -0
- package/docs/guides/fix-a-failed-converge.md +361 -0
- package/docs/guides/give-the-cluster-git-credentials.md +222 -0
- package/docs/guides/iterate-on-a-machine-on-kind.md +190 -0
- package/docs/guides/let-an-agent-write-a-chart.md +226 -0
- package/docs/guides/look-inside-a-sandbox.md +174 -0
- package/docs/guides/mirror-the-kit-images.md +176 -0
- package/docs/guides/move-from-kind-to-a-shared-cluster.md +302 -0
- package/docs/guides/open-the-console.md +91 -0
- package/docs/guides/publish-a-machine-as-an-npm-package.md +350 -0
- package/docs/guides/push-and-sign-a-branch.md +486 -0
- package/docs/guides/run-a-chart-by-name.md +270 -0
- package/docs/guides/run-a-command-or-call-a-url.md +544 -0
- package/docs/guides/run-one-worker-per-item.md +321 -0
- package/docs/guides/set-an-agents-access-and-dials.md +375 -0
- package/docs/guides/size-a-workspace.md +204 -0
- package/docs/guides/start-a-run-from-a-run.md +237 -0
- package/docs/guides/start-a-run.md +207 -0
- package/docs/guides/upgrade-the-kit-version.md +240 -0
- package/docs/guides/use-a-hosted-provider.md +208 -0
- package/docs/guides/use-a-local-model.md +313 -0
- package/docs/guides/watch-a-run.md +326 -0
- package/docs/guides/write-a-workflow.md +318 -0
- package/docs/index.md +44 -0
- package/docs/llms.txt +216 -0
- package/docs/reference/authoring-surface/agent.md +128 -0
- package/docs/reference/authoring-surface/answer.md +140 -0
- package/docs/reference/authoring-surface/arg.md +60 -0
- package/docs/reference/authoring-surface/basic.md +62 -0
- package/docs/reference/authoring-surface/bearer.md +53 -0
- package/docs/reference/authoring-surface/chartschema.md +23 -0
- package/docs/reference/authoring-surface/chartschemafor.md +48 -0
- package/docs/reference/authoring-surface/command.md +191 -0
- package/docs/reference/authoring-surface/customize.md +64 -0
- package/docs/reference/authoring-surface/defineconfig.md +41 -0
- package/docs/reference/authoring-surface/defineevent.md +114 -0
- package/docs/reference/authoring-surface/dispatch.md +126 -0
- package/docs/reference/authoring-surface/fail.md +83 -0
- package/docs/reference/authoring-surface/file.md +122 -0
- package/docs/reference/authoring-surface/frompick.md +277 -0
- package/docs/reference/authoring-surface/http.md +159 -0
- package/docs/reference/authoring-surface/isfailure.md +58 -0
- package/docs/reference/authoring-surface/jr2setup.md +237 -0
- package/docs/reference/authoring-surface/open.md +74 -0
- package/docs/reference/authoring-surface/openbody.md +86 -0
- package/docs/reference/authoring-surface/paramsof.md +125 -0
- package/docs/reference/authoring-surface/pool.md +186 -0
- package/docs/reference/authoring-surface/push.md +112 -0
- package/docs/reference/authoring-surface/secret.md +118 -0
- package/docs/reference/authoring-surface/sentby.md +83 -0
- package/docs/reference/authoring-surface/source.md +51 -0
- package/docs/reference/authoring-surface/text.md +62 -0
- package/docs/reference/authoring-surface/type-agentdeclaration.md +27 -0
- package/docs/reference/authoring-surface/type-agentdefinition.md +80 -0
- package/docs/reference/authoring-surface/type-agentlogic.md +15 -0
- package/docs/reference/authoring-surface/type-agentslots.md +12 -0
- package/docs/reference/authoring-surface/type-answeraction.md +12 -0
- package/docs/reference/authoring-surface/type-arg.md +19 -0
- package/docs/reference/authoring-surface/type-argnames.md +12 -0
- package/docs/reference/authoring-surface/type-binding.md +62 -0
- package/docs/reference/authoring-surface/type-bindingof.md +12 -0
- package/docs/reference/authoring-surface/type-bodyacceptsdoor.md +15 -0
- package/docs/reference/authoring-surface/type-bodyacceptsslots.md +17 -0
- package/docs/reference/authoring-surface/type-ceilings.md +41 -0
- package/docs/reference/authoring-surface/type-chainlink.md +19 -0
- package/docs/reference/authoring-surface/type-chartaction.md +46 -0
- package/docs/reference/authoring-surface/type-chartagent.md +28 -0
- package/docs/reference/authoring-surface/type-chartevent.md +20 -0
- package/docs/reference/authoring-surface/type-chartguard.md +20 -0
- package/docs/reference/authoring-surface/type-chartinvoke.md +28 -0
- package/docs/reference/authoring-surface/type-chartjson.md +14 -0
- package/docs/reference/authoring-surface/type-chartstate.md +46 -0
- package/docs/reference/authoring-surface/type-charttext.md +40 -0
- package/docs/reference/authoring-surface/type-charttransition.md +22 -0
- package/docs/reference/authoring-surface/type-charttransitions.md +14 -0
- package/docs/reference/authoring-surface/type-chartvalue.md +15 -0
- package/docs/reference/authoring-surface/type-childat.md +12 -0
- package/docs/reference/authoring-surface/type-childslots.md +12 -0
- package/docs/reference/authoring-surface/type-commandenv.md +15 -0
- package/docs/reference/authoring-surface/type-commandinput.md +19 -0
- package/docs/reference/authoring-surface/type-commandoptions.md +78 -0
- package/docs/reference/authoring-surface/type-commandoutput.md +104 -0
- package/docs/reference/authoring-surface/type-customize.md +109 -0
- package/docs/reference/authoring-surface/type-dispatchdefinition.md +39 -0
- package/docs/reference/authoring-surface/type-dispatchinput.md +14 -0
- package/docs/reference/authoring-surface/type-dispatchopenparts.md +14 -0
- package/docs/reference/authoring-surface/type-dispatchoutput.md +65 -0
- package/docs/reference/authoring-surface/type-duration.md +15 -0
- package/docs/reference/authoring-surface/type-effectbinding.md +93 -0
- package/docs/reference/authoring-surface/type-effectlogic.md +12 -0
- package/docs/reference/authoring-surface/type-envopenparts.md +14 -0
- package/docs/reference/authoring-surface/type-eventaudience.md +27 -0
- package/docs/reference/authoring-surface/type-eventdef.md +45 -0
- package/docs/reference/authoring-surface/type-eventfrom.md +16 -0
- package/docs/reference/authoring-surface/type-eventsemantics.md +26 -0
- package/docs/reference/authoring-surface/type-execoutcome.md +34 -0
- package/docs/reference/authoring-surface/type-failslot.md +14 -0
- package/docs/reference/authoring-surface/type-failure.md +19 -0
- package/docs/reference/authoring-surface/type-failureinput.md +20 -0
- package/docs/reference/authoring-surface/type-filebody.md +41 -0
- package/docs/reference/authoring-surface/type-frominput.md +14 -0
- package/docs/reference/authoring-surface/type-hostinjectedinput.md +58 -0
- package/docs/reference/authoring-surface/type-httpdefinition.md +101 -0
- package/docs/reference/authoring-surface/type-httpinput.md +12 -0
- package/docs/reference/authoring-surface/type-httpmethod.md +14 -0
- package/docs/reference/authoring-surface/type-httpopenparts.md +12 -0
- package/docs/reference/authoring-surface/type-httpoutput.md +89 -0
- package/docs/reference/authoring-surface/type-httprequestparts.md +33 -0
- package/docs/reference/authoring-surface/type-jr2config.md +126 -0
- package/docs/reference/authoring-surface/type-lends.md +38 -0
- package/docs/reference/authoring-surface/type-logicat.md +12 -0
- package/docs/reference/authoring-surface/type-markedif.md +12 -0
- package/docs/reference/authoring-surface/type-mergedactors.md +12 -0
- package/docs/reference/authoring-surface/type-namedsecret.md +25 -0
- package/docs/reference/authoring-surface/type-noslotspec.md +26 -0
- package/docs/reference/authoring-surface/type-noslotworkspaceoptions.md +32 -0
- package/docs/reference/authoring-surface/type-openbodydeclaration.md +40 -0
- package/docs/reference/authoring-surface/type-openbodylogic.md +14 -0
- package/docs/reference/authoring-surface/type-openbodyoutput.md +42 -0
- package/docs/reference/authoring-surface/type-openbodyslot.md +18 -0
- package/docs/reference/authoring-surface/type-opencommandinput.md +17 -0
- package/docs/reference/authoring-surface/type-openeffect.md +12 -0
- package/docs/reference/authoring-surface/type-openeffectslots.md +12 -0
- package/docs/reference/authoring-surface/type-openof.md +12 -0
- package/docs/reference/authoring-surface/type-opensecret.md +23 -0
- package/docs/reference/authoring-surface/type-opensecretmark.md +12 -0
- package/docs/reference/authoring-surface/type-permissivenoslotworkspaceoptions.md +31 -0
- package/docs/reference/authoring-surface/type-permissiveworkspaceoptions.md +32 -0
- package/docs/reference/authoring-surface/type-poolmachine.md +28 -0
- package/docs/reference/authoring-surface/type-poolspec.md +60 -0
- package/docs/reference/authoring-surface/type-pushinput.md +15 -0
- package/docs/reference/authoring-surface/type-pushoptions.md +79 -0
- package/docs/reference/authoring-surface/type-pushoutput.md +124 -0
- package/docs/reference/authoring-surface/type-pushwireoutput.md +12 -0
- package/docs/reference/authoring-surface/type-quantity.md +14 -0
- package/docs/reference/authoring-surface/type-reached.md +12 -0
- package/docs/reference/authoring-surface/type-reposlot.md +70 -0
- package/docs/reference/authoring-surface/type-reposlotsof.md +16 -0
- package/docs/reference/authoring-surface/type-sandboxoptions.md +77 -0
- package/docs/reference/authoring-surface/type-secret.md +25 -0
- package/docs/reference/authoring-surface/type-sender.md +19 -0
- package/docs/reference/authoring-surface/type-sentbyguards.md +12 -0
- package/docs/reference/authoring-surface/type-size.md +85 -0
- package/docs/reference/authoring-surface/type-slothandles.md +32 -0
- package/docs/reference/authoring-surface/type-sourcenextresult.md +17 -0
- package/docs/reference/authoring-surface/type-sourcespec.md +44 -0
- package/docs/reference/authoring-surface/type-syncstate.md +12 -0
- package/docs/reference/authoring-surface/type-text.md +19 -0
- package/docs/reference/authoring-surface/type-textpart.md +24 -0
- package/docs/reference/authoring-surface/type-thinkinglevel.md +39 -0
- package/docs/reference/authoring-surface/type-toparameterizedobject.md +14 -0
- package/docs/reference/authoring-surface/type-toprovidedactor.md +14 -0
- package/docs/reference/authoring-surface/type-unknown.md +21 -0
- package/docs/reference/authoring-surface/type-usercontainer.md +77 -0
- package/docs/reference/authoring-surface/type-withoutemptyindex.md +20 -0
- package/docs/reference/authoring-surface/type-workflowevent.md +46 -0
- package/docs/reference/authoring-surface/type-workspaceaccess.md +16 -0
- package/docs/reference/authoring-surface/type-workspaced.md +94 -0
- package/docs/reference/authoring-surface/type-workspacehandles.md +23 -0
- package/docs/reference/authoring-surface/type-workspacemachine.md +29 -0
- package/docs/reference/authoring-surface/type-workspaceof.md +13 -0
- package/docs/reference/authoring-surface/type-workspaceoptions.md +39 -0
- package/docs/reference/authoring-surface/type-workspacespec.md +37 -0
- package/docs/reference/authoring-surface/workspace.md +259 -0
- package/docs/reference/authoring-surface.md +197 -0
- package/docs/reference/cli.md +433 -0
- package/docs/reference/config.md +756 -0
- package/docs/reference/decisions/0001-operator-owned-generic-sandbox.md +113 -0
- package/docs/reference/decisions/0002-duplex-streaming-actor.md +110 -0
- package/docs/reference/decisions/0004-worktree-provisioning-model.md +124 -0
- package/docs/reference/decisions/0005-sandbox-pod-composition.md +230 -0
- package/docs/reference/decisions/0006-agent-control-surface.md +47 -0
- package/docs/reference/decisions/0007-durable-machine-state.md +109 -0
- package/docs/reference/decisions/0008-orchestrator-as-deployed-app.md +60 -0
- package/docs/reference/decisions/0009-cli-and-instance-interface.md +275 -0
- package/docs/reference/decisions/0010-bdd-acceptance-tests.md +160 -0
- package/docs/reference/decisions/0011-workflow-defined-events.md +141 -0
- package/docs/reference/decisions/0012-workspace-wrapper-machine.md +103 -0
- package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +157 -0
- package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +95 -0
- package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +265 -0
- package/docs/reference/decisions/0016-agent-turn-mechanics-are-internal.md +124 -0
- package/docs/reference/decisions/0017-pool-over-a-source-port.md +69 -0
- package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +111 -0
- package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +275 -0
- package/docs/reference/decisions/0020-private-ca-trust-is-a-named-concept.md +60 -0
- package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +100 -0
- package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +103 -0
- package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +176 -0
- package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +439 -0
- package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +65 -0
- package/docs/reference/decisions/0026-a-turn-that-is-over-is-never-prompted.md +62 -0
- package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +237 -0
- package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +89 -0
- package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +154 -0
- package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +100 -0
- package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +190 -0
- package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +61 -0
- package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +127 -0
- package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +57 -0
- package/docs/reference/decisions/0035-a-runaway-turn-is-ended-rerolled-once-then-a-fault.md +92 -0
- package/docs/reference/decisions/0036-a-turn-compacts-its-own-context-mid-flight.md +138 -0
- package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +196 -0
- package/docs/reference/decisions/0038-jr2-up-builds-every-image-it-deploys.md +170 -0
- package/docs/reference/decisions/0039-image-garbage-collects-by-reachability.md +115 -0
- package/docs/reference/decisions/0041-a-build-the-host-already-holds-is-not-spent-again.md +64 -0
- package/docs/reference/decisions/0042-ready-is-not-routable-an-admission-retries-its-connection.md +142 -0
- package/docs/reference/decisions/0043-the-kit-is-tested-as-installed-a-local-registry-stands-in-for-npm.md +170 -0
- package/docs/reference/decisions/0044-kit-images-live-at-a-canonical-home-a-self-host-mirrors-it.md +85 -0
- package/docs/reference/decisions/0045-the-platform-joins-the-image-address-and-the-cluster-chooses-it.md +82 -0
- package/docs/reference/decisions/0046-a-converge-failure-carries-its-diagnosis.md +34 -0
- package/docs/reference/decisions/0047-the-git-ssh-key-source-is-the-users-choice.md +47 -0
- package/docs/reference/decisions/0048-the-orchestrator-boots-without-its-repos.md +36 -0
- package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +126 -0
- package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +73 -0
- package/docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md +227 -0
- package/docs/reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md +81 -0
- package/docs/reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md +111 -0
- package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +126 -0
- package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +107 -0
- package/docs/reference/decisions/0056-a-global-jr2-hands-off-to-the-instances-own-and-an-instance-has-one-kit-version.md +62 -0
- package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +152 -0
- package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +106 -0
- package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +384 -0
- package/docs/reference/decisions/0060-a-workspace-states-its-size-and-jr2-reserves-all-of-it.md +111 -0
- package/docs/reference/decisions/0061-a-memory-kill-ends-the-agents-processes-not-the-harness.md +83 -0
- package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +212 -0
- package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +83 -0
- package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +79 -0
- package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +65 -0
- package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +550 -0
- package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +430 -0
- package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +464 -0
- package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +180 -0
- package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +323 -0
- package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +183 -0
- package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +144 -0
- package/docs/reference/decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md +122 -0
- package/docs/reference/decisions/0074-an-unrouted-mechanism-event-is-refused-at-load-and-faults-the-run.md +76 -0
- package/docs/reference/decisions.md +83 -0
- package/docs/reference/glossary.md +648 -0
- package/docs/reference/http-api.md +1348 -0
- package/docs/reference/machines.md +190 -0
- package/docs/reference/mechanism-events.md +72 -0
- package/docs/why.md +206 -0
- package/package.json +5 -3
- package/src/actor.ts +541 -79
- package/src/agent.ts +114 -38
- package/src/ambient.ts +2 -1
- package/src/assembly-checks.ts +189 -7
- package/src/cause.ts +234 -0
- package/src/chart.ts +169 -37
- package/src/charts.ts +34 -6
- package/src/config.ts +430 -178
- package/src/custodian.ts +74 -22
- package/src/customize.ts +188 -46
- package/src/dispatch-effect.ts +945 -0
- package/src/door-compat.ts +217 -0
- package/src/durability.ts +11 -4
- package/src/effect.ts +341 -44
- package/src/effector-wire.ts +160 -11
- package/src/fail.ts +209 -0
- package/src/harness-client.ts +541 -47
- package/src/http-effect.ts +495 -53
- package/src/http.ts +427 -16
- package/src/index.ts +60 -82
- package/src/instance.ts +68 -8
- package/src/internal.ts +84 -0
- package/src/machine-doc.ts +21 -3
- package/src/mechanism-routes.ts +168 -0
- package/src/model-keys.generated.ts +53 -0
- package/src/model-keys.ts +18 -58
- package/src/notices.ts +66 -13
- package/src/open-body.ts +159 -23
- package/src/open-effect.ts +81 -8
- package/src/open.ts +59 -6
- package/src/parts.ts +184 -13
- package/src/party.ts +68 -2
- package/src/pick.ts +463 -11
- package/src/pool.ts +247 -36
- package/src/registration.ts +83 -4
- package/src/repos.ts +2 -1
- package/src/run-host.ts +565 -31
- package/src/run-output.ts +38 -0
- package/src/sandbox-effect.ts +273 -38
- package/src/sandbox-kube.ts +3 -1
- package/src/secret-placement.ts +52 -17
- package/src/server.ts +3 -0
- package/src/setup.ts +239 -56
- package/src/size.ts +121 -9
- package/src/snapshot-store.ts +54 -10
- package/src/stub-harness.ts +44 -16
- package/src/timers.ts +14 -1
- package/src/vocabulary.ts +69 -14
- package/src/wire.ts +90 -16
- package/src/workspace.ts +697 -175
package/src/parts.ts
CHANGED
|
@@ -51,10 +51,13 @@ import type { AnyActorRef, AnyStateMachine, StateNode, UnknownActorLogic } from
|
|
|
51
51
|
import { isAgent, isOpenAgent, type AgentDeclaration } from "./agent.ts";
|
|
52
52
|
import { argvText, isEffect, placementOf, type EffectParts, type Placement } from "./effect.ts";
|
|
53
53
|
import { effectBindingLine, openPartsOf, type OpenEffectPart } from "./open-effect.ts";
|
|
54
|
+
import { isFailSlot } from "./fail.ts";
|
|
54
55
|
import { isImageContext } from "./images.ts";
|
|
55
56
|
import { isOpenBody, openBodyDeclarationOf, type OpenBodyDeclaration } from "./open-body.ts";
|
|
56
57
|
import { open } from "./open.ts";
|
|
57
58
|
import { repoIdentity } from "./repo-identity.ts";
|
|
59
|
+
import { refuseUnroutedAgentFault } from "./mechanism-routes.ts";
|
|
60
|
+
import { refuseLostOutput } from "./run-output.ts";
|
|
58
61
|
import { userSeatOf, type Size, type UserContainer } from "./size.ts";
|
|
59
62
|
|
|
60
63
|
// --- Repo Slots (ADR-0051) ---------------------------------------------------------------------
|
|
@@ -71,15 +74,103 @@ import { userSeatOf, type Size, type UserContainer } from "./size.ts";
|
|
|
71
74
|
// meets it first, and `import { open } from "@jr2/orchestrator"` is the only spelling anyone writes.
|
|
72
75
|
export { open } from "./open.ts";
|
|
73
76
|
|
|
74
|
-
/**
|
|
75
|
-
*
|
|
76
|
-
|
|
77
|
+
/**
|
|
78
|
+
* The repository of a Repo Slot: `{ url, ref }`. `url` is the Repo's git url. `ref` is the branch
|
|
79
|
+
* or commit that the branch Worktree starts from; absent, the Repo's default branch. Where only a
|
|
80
|
+
* url is needed, a string is enough.
|
|
81
|
+
*
|
|
82
|
+
* `workspace()` and `customize()` refuse:
|
|
83
|
+
* - an empty `url`: ``<where>: Repo Slot "<slot>" is bound to an empty url (got <value>) — a slot
|
|
84
|
+
* is `open`, a url, `{ url, ref? }`, or a mapper `({ input }) => url | { url, ref? }` over the
|
|
85
|
+
* door (ADR-0051).``
|
|
86
|
+
* - an empty `ref`: the same text, with `bound with an empty ref` in place of `bound to an empty
|
|
87
|
+
* url`.
|
|
88
|
+
* - a url that names no Repo, such as a relative path: ``<where>: Repo Slot "<slot>" binds
|
|
89
|
+
* "<url>", which names no Repo — <reason> (ADR-0051).``
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* import { jr2Setup, workspace, type Binding } from "@jr2/orchestrator";
|
|
94
|
+
*
|
|
95
|
+
* const app: Binding = { url: "https://github.com/you/app.git", ref: "release-2" };
|
|
96
|
+
*
|
|
97
|
+
* const body = jr2Setup().createMachine({
|
|
98
|
+
* id: "body",
|
|
99
|
+
* initial: "done",
|
|
100
|
+
* states: { done: { type: "final" } },
|
|
101
|
+
* });
|
|
102
|
+
*
|
|
103
|
+
* export const machine = workspace(body, {
|
|
104
|
+
* repos: { app },
|
|
105
|
+
* spec: () => ({ branch: "jr2/hotfix" }),
|
|
106
|
+
* });
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @see docs/concepts/workspaces.md
|
|
110
|
+
* @see docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md
|
|
111
|
+
*/
|
|
112
|
+
// What a Repo Slot resolves to (GLOSSARY.md "Binding").
|
|
113
|
+
export type Binding = {
|
|
114
|
+
/** The Repo's git url. */
|
|
115
|
+
url: string;
|
|
116
|
+
/** The branch or commit that the branch Worktree starts from. Default: the Repo's default
|
|
117
|
+
* branch. */
|
|
118
|
+
ref?: string;
|
|
119
|
+
};
|
|
77
120
|
|
|
121
|
+
// Bound and open are what `jr2 up` can see; per-run is the run's business, fenced at attach by
|
|
122
|
+
// `git.credentials` (ADR-0051).
|
|
78
123
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
124
|
+
* The value of one Repo Slot in `workspace({ repos })`. One of:
|
|
125
|
+
* - a url, or a {@link Binding} `{ url, ref }`: the Machine names the Repo.
|
|
126
|
+
* - {@link open}: the Instance that registers the Machine binds it with `customize()`. `jr2 up`
|
|
127
|
+
* refuses a Workflow that leaves it open: ``refusing: workflow "<name>" leaves Repo Slot
|
|
128
|
+
* "<slot>" open — bind it where the Machine is registered: export const machine =
|
|
129
|
+
* customize(<import>, …) (ADR-0051)``, with the whole `customize` line to paste.
|
|
130
|
+
* - a function of the run input, `({ input }) => url` or a {@link Binding}: each run chooses. The
|
|
131
|
+
* url must match an entry of `git.credentials` in `jr2.config.ts`, or the run cannot use it.
|
|
132
|
+
*
|
|
133
|
+
* The key of the slot is a directory name under `/work`. It starts with a letter, and
|
|
134
|
+
* `workspace()` and `customize()` refuse a key that does not: ``<where>: Repo Slot key "<key>" is
|
|
135
|
+
* not a directory name — a slot becomes `/work/<slot>` and its order matters, so it starts with a
|
|
136
|
+
* letter and matches /^[A-Za-z][A-Za-z0-9._-]*$/ (ADR-0051).`` They refuse a value of another
|
|
137
|
+
* shape: ``<where>: Repo Slot "<slot>" is <what> — a slot is `open`, a url, `{ url, ref? }`, or a
|
|
138
|
+
* mapper `({ input }) => url | { url, ref? }` over the door (ADR-0051).``
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* import { z } from "zod";
|
|
143
|
+
* import { jr2Setup, open, workspace, type RepoSlot, type Workspaced } from "@jr2/orchestrator";
|
|
144
|
+
*
|
|
145
|
+
* const runInput = z.object({ service: z.string() });
|
|
146
|
+
* type RunInput = z.infer<typeof runInput>;
|
|
147
|
+
*
|
|
148
|
+
* const service: RepoSlot<RunInput> = ({ input }) => `https://github.com/you/${input.service}.git`;
|
|
149
|
+
*
|
|
150
|
+
* const body = jr2Setup({
|
|
151
|
+
* types: {} as { input: Workspaced<RunInput, "service" | "docs" | "config"> },
|
|
152
|
+
* }).createMachine({
|
|
153
|
+
* id: "body",
|
|
154
|
+
* initial: "done",
|
|
155
|
+
* states: { done: { type: "final" } },
|
|
156
|
+
* });
|
|
157
|
+
*
|
|
158
|
+
* // A Machine for a package: the Instance that registers it binds `config`.
|
|
159
|
+
* export const deploy = workspace(body, {
|
|
160
|
+
* input: runInput,
|
|
161
|
+
* repos: {
|
|
162
|
+
* service,
|
|
163
|
+
* docs: "https://github.com/you/docs.git",
|
|
164
|
+
* config: open,
|
|
165
|
+
* },
|
|
166
|
+
* spec: ({ input }) => ({ branch: `deploy/${input.service}` }),
|
|
167
|
+
* });
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @see docs/concepts/workspaces.md
|
|
171
|
+
* @see docs/guides/bind-open-parts.md
|
|
172
|
+
* @see docs/guides/give-the-cluster-git-credentials.md
|
|
173
|
+
* @see docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md
|
|
83
174
|
*/
|
|
84
175
|
export type RepoSlot<TInput = unknown> =
|
|
85
176
|
| typeof open
|
|
@@ -199,8 +290,8 @@ export function sandboxPartsOf(machine: AnyStateMachine | undefined): SandboxPar
|
|
|
199
290
|
|
|
200
291
|
/** Does this Machine COMPOSE a Sandbox — i.e. is it a `workspace()` wrapper? Distinct from
|
|
201
292
|
* `sandboxPartsOf(m)` naming no image: a wrapper that names neither image still owns the two
|
|
202
|
-
* seats, which is what `customize({ image })` retunes (ADR-0049) — and it
|
|
203
|
-
*
|
|
293
|
+
* seats, which is what `customize({ image })` retunes (ADR-0049) — and it may carry no Repo Slot
|
|
294
|
+
* at all (ADR-0051). Also the data-plane switch, read off the walk: an Instance needs
|
|
204
295
|
* Sandboxes exactly when a registered Machine composes one. A logic with no `config` (an Effect's,
|
|
205
296
|
* ADR-0067) composes none. */
|
|
206
297
|
export function composesSandbox(machine: AnyStateMachine): boolean {
|
|
@@ -492,11 +583,34 @@ export type CarriedEffect = {
|
|
|
492
583
|
/** A push (ADR-0067, ADR-0051): the Workspace's branch to its Repo Slot's Binding. It names no
|
|
493
584
|
* secret: `jr2 up` resolves its credential through `git.credentials`. */
|
|
494
585
|
| { kind: "push"; slot?: string; sign: boolean; squash: boolean; force: boolean; pin: boolean; secrets: string[] }
|
|
586
|
+
/** A dispatch (ADR-0071): the Workflow it starts a run of, as `jr2 run` names it, whether it
|
|
587
|
+
* waits, and — toward another Orchestrator — the target's origin as an http target and its
|
|
588
|
+
* token as the one secret (placed in the Instance Effector beside the http Effects). No target:
|
|
589
|
+
* it runs in the Orchestrator's own process and names no secret. `input`: the slot's input
|
|
590
|
+
* schema as JSON Schema, what the walk compares with the callee's door; absent, the door alone
|
|
591
|
+
* checks. An Open target has no target and no secret yet. */
|
|
592
|
+
| {
|
|
593
|
+
kind: "dispatch";
|
|
594
|
+
workflow: string;
|
|
595
|
+
wait: boolean;
|
|
596
|
+
target?: { scheme: "http" | "https"; host: string; port: number };
|
|
597
|
+
secrets: string[];
|
|
598
|
+
input?: Record<string, unknown>;
|
|
599
|
+
open?: Array<"target">;
|
|
600
|
+
}
|
|
495
601
|
);
|
|
496
602
|
|
|
603
|
+
/** One state that can fail the run (ADR-0073): it invokes a `fail()` slot. `state` is the state's
|
|
604
|
+
* id, `machine` the id of its Machine, `slot` the slot key it invokes, and `path` the `customize()`
|
|
605
|
+
* route to its Machine, as an {@link OpenSlot}'s. Static, as a Gate or an Effect is: the walk reads
|
|
606
|
+
* it, and `jr2 up`, `jr2 check` and the Machine doc list it. */
|
|
607
|
+
export type CarriedFailure = { machine: string; state: string; slot: string; path: OpenSlot["path"] };
|
|
608
|
+
|
|
497
609
|
/** Everything the registered Machines carry that a converge or a boot must act on. */
|
|
498
610
|
export type CarriedParts = {
|
|
499
611
|
agents: CarriedAgent[];
|
|
612
|
+
/** Every state that invokes a `fail()` slot (ADR-0073), in walk order, nested Machines too. */
|
|
613
|
+
failures: CarriedFailure[];
|
|
500
614
|
/** Every Effect slot, in walk order — one per Machine and slot key, at the first route the walk
|
|
501
615
|
* reached its Machine by. The placement reads {@link placedEffectsOf}: one per route. */
|
|
502
616
|
effects: CarriedEffect[];
|
|
@@ -556,17 +670,18 @@ function inlineMachines(node: StateNode<any, any>): Array<{ machine: AnyStateMac
|
|
|
556
670
|
}
|
|
557
671
|
|
|
558
672
|
/**
|
|
559
|
-
* Refuse a Part written inline on an `invoke.src` — an `agent()`, an Effect or a `workspace()` that
|
|
673
|
+
* Refuse a Part written inline on an `invoke.src` — an `agent()`, an Effect, a `fail()` or a `workspace()` that
|
|
560
674
|
* is no key of the Machine's `actors` (see the module comment). Thrown at build by
|
|
561
675
|
* `jr2Setup.createMachine` and at load by {@link partsOf}, so a Machine built with xstate's own
|
|
562
|
-
* `createMachine` is refused where `jr2 up` and the Orchestrator read it. A plain
|
|
563
|
-
* written inline is not a Part: it stays walked, with no `customize()` route (its
|
|
564
|
-
* `undefined`).
|
|
676
|
+
* `createMachine` is refused where `jr2 check`, `jr2 up` and the Orchestrator read it. A plain
|
|
677
|
+
* child Machine written inline is not a Part: it stays walked, with no `customize()` route (its
|
|
678
|
+
* `path` is `undefined`).
|
|
565
679
|
*/
|
|
566
680
|
export function refuseInlineParts(machine: AnyStateMachine): void {
|
|
567
681
|
const partOf = (src: unknown): { part: string; written: string } | undefined => {
|
|
568
682
|
if (isAgent(src)) return { part: "an Agent", written: "agent(...)" };
|
|
569
683
|
if (isEffect(src)) return { part: "an Effect", written: `${src.effect.kind}(...)` };
|
|
684
|
+
if (isFailSlot(src)) return { part: "a fail() Part", written: "fail()" };
|
|
570
685
|
const child = asMachine(src);
|
|
571
686
|
if (child && composesSandbox(child)) return { part: "a Workspace", written: "workspace(...)" };
|
|
572
687
|
return undefined;
|
|
@@ -615,6 +730,7 @@ function canonical(value: unknown): string {
|
|
|
615
730
|
*/
|
|
616
731
|
export function partsOf(machines: Iterable<AnyStateMachine>): CarriedParts {
|
|
617
732
|
const agents: CarriedAgent[] = [];
|
|
733
|
+
const failures: CarriedFailure[] = [];
|
|
618
734
|
const effects: CarriedEffect[] = [];
|
|
619
735
|
const images: CarriedImage[] = [];
|
|
620
736
|
const repos: CarriedRepo[] = [];
|
|
@@ -690,6 +806,8 @@ export function partsOf(machines: Iterable<AnyStateMachine>): CarriedParts {
|
|
|
690
806
|
if (walked.has(machine)) return;
|
|
691
807
|
walked.add(machine);
|
|
692
808
|
refuseInlineParts(machine);
|
|
809
|
+
refuseLostOutput(machine);
|
|
810
|
+
refuseUnroutedAgentFault(machine);
|
|
693
811
|
const parts = sandboxPartsOf(machine);
|
|
694
812
|
const user = userSeatOf(parts.user);
|
|
695
813
|
collectImage(parts.image);
|
|
@@ -706,6 +824,7 @@ export function partsOf(machines: Iterable<AnyStateMachine>): CarriedParts {
|
|
|
706
824
|
});
|
|
707
825
|
}
|
|
708
826
|
const body = wrapperBodyOf(machine);
|
|
827
|
+
for (const { state, slot } of failingStatesOf(machine)) failures.push({ machine: machine.id, state, slot, path });
|
|
709
828
|
for (const [name, logic] of Object.entries(machine.implementations.actors as Record<string, unknown>)) {
|
|
710
829
|
if (isAgent(logic)) collectAgent(path, name, logic.definition);
|
|
711
830
|
else if (isOpenBody(logic)) {
|
|
@@ -735,6 +854,7 @@ export function partsOf(machines: Iterable<AnyStateMachine>): CarriedParts {
|
|
|
735
854
|
for (const body of noneBodies) for (const m of body.declaration.allows.models) harnessModels.add(m);
|
|
736
855
|
return {
|
|
737
856
|
agents,
|
|
857
|
+
failures,
|
|
738
858
|
effects,
|
|
739
859
|
images,
|
|
740
860
|
repos,
|
|
@@ -817,6 +937,23 @@ export function carriedEffectOf(
|
|
|
817
937
|
): CarriedEffect {
|
|
818
938
|
const placement = placementOf(parts);
|
|
819
939
|
const openParts = openPartsOf(parts);
|
|
940
|
+
if (parts.kind === "dispatch") {
|
|
941
|
+
const input = (parts as { [DISPATCH_INPUT]?: Record<string, unknown> })[DISPATCH_INPUT];
|
|
942
|
+
return {
|
|
943
|
+
name,
|
|
944
|
+
path,
|
|
945
|
+
route,
|
|
946
|
+
kind: "dispatch",
|
|
947
|
+
placement,
|
|
948
|
+
workflow: parts.workflow,
|
|
949
|
+
wait: parts.wait,
|
|
950
|
+
timeoutMs: parts.timeoutMs,
|
|
951
|
+
...(parts.target === undefined || parts.target === open ? {} : { target: originTarget(parts.target.url) }),
|
|
952
|
+
secrets: [...parts.secrets],
|
|
953
|
+
...(input !== undefined ? { input } : {}),
|
|
954
|
+
...(openParts.length ? { open: openParts as Array<"target"> } : {}),
|
|
955
|
+
};
|
|
956
|
+
}
|
|
820
957
|
if (parts.kind === "http") {
|
|
821
958
|
return {
|
|
822
959
|
name,
|
|
@@ -867,6 +1004,20 @@ export function carriedEffectOf(
|
|
|
867
1004
|
};
|
|
868
1005
|
}
|
|
869
1006
|
|
|
1007
|
+
/** The key a dispatch's slot schema rides its parts under (dispatch-effect.ts): `Symbol.for`, so this
|
|
1008
|
+
* walk reads it off a Machine built by another copy of the module (ADR-0071). */
|
|
1009
|
+
const DISPATCH_INPUT = Symbol.for("jr2.dispatch.input");
|
|
1010
|
+
|
|
1011
|
+
/** A dispatch target's origin as the Effector's fence reads an http target: scheme, host, port. The
|
|
1012
|
+
* origin was checked when the slot was built, so it parses. */
|
|
1013
|
+
function originTarget(url: string): { scheme: "http" | "https"; host: string; port: number } {
|
|
1014
|
+
const u = new URL(url);
|
|
1015
|
+
const scheme = u.protocol === "http:" ? "http" : "https";
|
|
1016
|
+
// As an http target's: brackets off an IPv6 literal, lower case (http-effect.ts `targetOf`).
|
|
1017
|
+
const host = u.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
1018
|
+
return { scheme, host, port: u.port ? Number(u.port) : scheme === "http" ? 80 : 443 };
|
|
1019
|
+
}
|
|
1020
|
+
|
|
870
1021
|
/**
|
|
871
1022
|
* One Workspace a Machine composes, as its pod's Held secrets are placed (ADR-0059): what the pod
|
|
872
1023
|
* names. Located like a {@link CarriedSize} — `path` is the `customize()` route to its
|
|
@@ -896,6 +1047,9 @@ export type WorkspacePod = {
|
|
|
896
1047
|
/** Each Repo Slot's Binding url as the Machine binds it, by slot, in order; undefined for an open
|
|
897
1048
|
* or per-run slot, whose url `jr2 up` cannot read. A push resolves its credential through it. */
|
|
898
1049
|
bindings: Record<string, string | undefined>;
|
|
1050
|
+
/** The `workspace()` declares no Repo Slot (ADR-0051): it has only `/work`, which its steps
|
|
1051
|
+
* share. Absent for one with slots, and for an Open map, whose slots the composer names. */
|
|
1052
|
+
noSlot?: true;
|
|
899
1053
|
};
|
|
900
1054
|
|
|
901
1055
|
/**
|
|
@@ -976,6 +1130,7 @@ export function workspacePodsOf(root: AnyStateMachine): WorkspacePod[] {
|
|
|
976
1130
|
...(parts.effector ? { effector: { ...parts.effector } } : {}),
|
|
977
1131
|
...(parts.image !== undefined ? { image: parts.image } : {}),
|
|
978
1132
|
bindings,
|
|
1133
|
+
...(parts.repos !== open && Object.keys(parts.repos).length === 0 ? { noSlot: true as const } : {}),
|
|
979
1134
|
});
|
|
980
1135
|
}
|
|
981
1136
|
const body = wrapperBodyOf(machine);
|
|
@@ -990,6 +1145,22 @@ export function workspacePodsOf(root: AnyStateMachine): WorkspacePod[] {
|
|
|
990
1145
|
return pods;
|
|
991
1146
|
}
|
|
992
1147
|
|
|
1148
|
+
/** Every state of `machine`'s own tree that invokes a `fail()` slot (ADR-0073), in document order,
|
|
1149
|
+
* with the slot key: a state that can fail the run. A child Machine's states are its own walk's. */
|
|
1150
|
+
export function failingStatesOf(machine: AnyStateMachine): Array<{ state: string; slot: string }> {
|
|
1151
|
+
const actors = machine.implementations.actors as Record<string, unknown>;
|
|
1152
|
+
const out: Array<{ state: string; slot: string }> = [];
|
|
1153
|
+
const visit = (node: StateNode<any, any>): void => {
|
|
1154
|
+
for (const inv of node.invoke) {
|
|
1155
|
+
if (typeof inv.src === "string" && isFailSlot(actors[inv.src])) out.push({ state: node.id, slot: inv.src });
|
|
1156
|
+
}
|
|
1157
|
+
const children = Object.values(node.states as Record<string, StateNode<any, any>>);
|
|
1158
|
+
for (const child of children.sort((a, b) => a.order - b.order)) visit(child);
|
|
1159
|
+
};
|
|
1160
|
+
visit(machine.root);
|
|
1161
|
+
return out;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
993
1164
|
/** Every machine object written inline below `node`, at any depth of its state tree, with its hop. */
|
|
994
1165
|
function walkStates(node: StateNode<any, any>, visit: (machine: AnyStateMachine, hop: RouteHop) => void): void {
|
|
995
1166
|
for (const { machine, hop } of inlineMachines(node)) visit(machine, hop);
|
package/src/party.ts
CHANGED
|
@@ -24,9 +24,75 @@ import { vocabularyOf } from "./vocabulary.ts";
|
|
|
24
24
|
/** The guard type `sentBy` names: dotted, so no author guard can take the name. */
|
|
25
25
|
export const SENT_BY = "jr2.sentBy";
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
27
|
+
/**
|
|
28
|
+
* A guard that is true for an event that one party sent, and false for an event that another party
|
|
29
|
+
* sent: `guard: sentBy("coder")`. Use it where two parties may send the same event to one state,
|
|
30
|
+
* and the transition must run for one of them only. It is also true for an event that the Machine
|
|
31
|
+
* sends itself, which has no sender.
|
|
32
|
+
*
|
|
33
|
+
* It can only make a transition decline the events of other parties. It never lets a party send
|
|
34
|
+
* an event that the party may not send at that state: the position of the `on` key decides that.
|
|
35
|
+
* When the guard is false, xstate tries the next transition for the event, as for any guard. Use
|
|
36
|
+
* it alone, or inside `and([…])`.
|
|
37
|
+
*
|
|
38
|
+
* `createMachine` refuses an id that is not a party of the Machine: ``machine "<id>":
|
|
39
|
+
* sentBy("<party>") on "<event>" at "<state>" names no party of this Machine (Agent slots:
|
|
40
|
+
* <slots>; Gate invoke ids: <ids>)``
|
|
41
|
+
*
|
|
42
|
+
* @param id - The party: the slot key of an Agent of this Machine, or the invoke `id` of one of its
|
|
43
|
+
* Gates.
|
|
44
|
+
* @returns A named guard object, for a transition's `guard`.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { z } from "zod";
|
|
49
|
+
* import { agent, defineEvent, fail, jr2Setup, sentBy } from "@jr2/orchestrator";
|
|
50
|
+
*
|
|
51
|
+
* const done = defineEvent({
|
|
52
|
+
* name: "done",
|
|
53
|
+
* description: "Call this when the draft is ready for review.",
|
|
54
|
+
* input: z.object({}),
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* export const machine = jr2Setup({
|
|
58
|
+
* events: [done],
|
|
59
|
+
* actors: {
|
|
60
|
+
* writer: agent({
|
|
61
|
+
* model: "anthropic/claude-haiku-5-5",
|
|
62
|
+
* instructions: "You write release notes.",
|
|
63
|
+
* workspace: "none",
|
|
64
|
+
* }),
|
|
65
|
+
* fail: fail(),
|
|
66
|
+
* },
|
|
67
|
+
* }).createMachine({
|
|
68
|
+
* id: "notes",
|
|
69
|
+
* on: { "agent.fault": ".failed" },
|
|
70
|
+
* initial: "drafting",
|
|
71
|
+
* states: {
|
|
72
|
+
* drafting: {
|
|
73
|
+
* invoke: [
|
|
74
|
+
* { src: "writer", input: { prompt: "Draft the release notes." } },
|
|
75
|
+
* { src: "gate", id: "editor" },
|
|
76
|
+
* ],
|
|
77
|
+
* on: {
|
|
78
|
+
* // The writer's `done` goes to review; the editor's `done` skips it.
|
|
79
|
+
* done: [{ guard: sentBy("writer"), target: "review" }, { target: "published" }],
|
|
80
|
+
* },
|
|
81
|
+
* },
|
|
82
|
+
* review: { invoke: { src: "gate" }, on: { done: "published" } },
|
|
83
|
+
* published: { type: "final" },
|
|
84
|
+
* failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
|
|
85
|
+
* },
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @see docs/concepts/the-menu.md
|
|
90
|
+
* @see docs/concepts/gates.md
|
|
91
|
+
* @see docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md
|
|
92
|
+
*/
|
|
29
93
|
export function sentBy<const Id extends string>(id: Id): { type: typeof SENT_BY; params: { id: Id } } {
|
|
94
|
+
// A NAMED guard with params, so the load walk can read it (see the module header). The id is
|
|
95
|
+
// refused at load by `refuseUnknownSentBy` when no Agent slot or Gate invoke id has it.
|
|
30
96
|
return { type: SENT_BY, params: { id } };
|
|
31
97
|
}
|
|
32
98
|
|