@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
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Run one worker per item
|
|
3
|
+
description: Make a Pool that runs one worker Machine for each item that a Source gives, and run it.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Run one worker per item
|
|
7
|
+
|
|
8
|
+
Make a [Workflow](../reference/glossary.md#workflow) that runs one worker [Machine](../reference/glossary.md#machine)
|
|
9
|
+
for each item of work, with [`pool()`](../reference/authoring-surface/pool.md) and
|
|
10
|
+
[`source()`](../reference/authoring-surface/source.md).
|
|
11
|
+
|
|
12
|
+
In this example, the items are the open issues of a GitHub [Repo](../reference/glossary.md#repo) that have the label
|
|
13
|
+
`jr2`. The worker is the shipped Machine [`task`](../reference/machines.md#task). Each worker works on one issue in its
|
|
14
|
+
own [Sandbox](../reference/glossary.md#sandbox). Then it waits at a [Gate](../reference/glossary.md#gate) until a person
|
|
15
|
+
approves its work.
|
|
16
|
+
|
|
17
|
+
## The Workflow
|
|
18
|
+
|
|
19
|
+
The example uses `@jr2/machines`. Add it to the [Instance](../reference/glossary.md#instance) at the
|
|
20
|
+
[Kit version](../reference/glossary.md#kit-version). `<version>` is the version of `@jr2/orchestrator` in your
|
|
21
|
+
`package.json`:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm install --save-exact @jr2/machines@<version>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Save this file as `workflows/issues.ts`. Replace `you/app` with your Repo, in the two places where it occurs.
|
|
28
|
+
|
|
29
|
+
The imports:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { fromPromise } from "xstate";
|
|
33
|
+
import { z } from "zod";
|
|
34
|
+
import { customize, defineEvent, pool, source } from "@jr2/orchestrator";
|
|
35
|
+
import { task } from "@jr2/machines";
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The model of the tab:
|
|
39
|
+
|
|
40
|
+
**Anthropic**
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
const model = "anthropic/claude-haiku-5-5";
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Local**
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
const model = "local/qwen3.6-35b-a3b";
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The [Source](../reference/glossary.md#source), the worker and the [Pool](../reference/glossary.md#pool):
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
// One work item: an open issue of the Repo.
|
|
56
|
+
type Issue = { number: number; title: string; body: string };
|
|
57
|
+
|
|
58
|
+
// The open issues with the label `jr2`: the first page only, at most 100. The Repo must be public,
|
|
59
|
+
// because the request has no token.
|
|
60
|
+
const ISSUES = "https://api.github.com/repos/you/app/issues?labels=jr2&state=open&per_page=100";
|
|
61
|
+
|
|
62
|
+
// The issues that this Source gave to a worker. A worker has each one now, or it finished it.
|
|
63
|
+
// The set is in the memory of the Orchestrator, and a restart empties it.
|
|
64
|
+
const claimed = new Set<number>();
|
|
65
|
+
|
|
66
|
+
// The Source: give the next open issue that no worker has had.
|
|
67
|
+
const issues = source<Issue>({
|
|
68
|
+
next: fromPromise<Issue | null, { active: string[] }>(async ({ input }) => {
|
|
69
|
+
const res = await fetch(ISSUES, { headers: { accept: "application/vnd.github+json" } }).catch(() => undefined);
|
|
70
|
+
if (!res?.ok) {
|
|
71
|
+
// While workers run, look again later. With no worker, stop the run with the error.
|
|
72
|
+
if (input.active.length > 0) return null;
|
|
73
|
+
throw new Error(`GET ${ISSUES} failed: ${res ? res.status : "no answer"}`);
|
|
74
|
+
}
|
|
75
|
+
const open = (await res.json()) as Array<{
|
|
76
|
+
number: number;
|
|
77
|
+
title: string;
|
|
78
|
+
body: string | null;
|
|
79
|
+
pull_request?: unknown;
|
|
80
|
+
}>;
|
|
81
|
+
// The issues API also lists pull requests. Skip them, and skip each issue that a worker has now.
|
|
82
|
+
const issue = open.find(
|
|
83
|
+
(i) => i.pull_request === undefined && !claimed.has(i.number) && !input.active.includes(`issue-${i.number}`),
|
|
84
|
+
);
|
|
85
|
+
if (!issue) return null;
|
|
86
|
+
claimed.add(issue.number);
|
|
87
|
+
return { number: issue.number, title: issue.title, body: issue.body ?? "" };
|
|
88
|
+
}),
|
|
89
|
+
// Send this event to the `source` Gate when you add the label to an issue.
|
|
90
|
+
wake: defineEvent({
|
|
91
|
+
name: "issues_changed",
|
|
92
|
+
description: "An issue got the label jr2. Look for work again.",
|
|
93
|
+
audience: "external",
|
|
94
|
+
input: z.object({}),
|
|
95
|
+
}),
|
|
96
|
+
// While workers run and no issue is ready, look again every 5 minutes.
|
|
97
|
+
pollEvery: 300_000,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// The worker: `task`, with its two Open parts bound.
|
|
101
|
+
const fixer = customize(task, {
|
|
102
|
+
repos: { app: { url: "https://github.com/you/app.git" } },
|
|
103
|
+
agents: { coder: { model } },
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// The run input of the Pool. A worker does not get it.
|
|
107
|
+
const door = z.object({
|
|
108
|
+
workers: z.number().int().min(1).max(4).default(2).describe("How many issues to work on at once."),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// The Pool: one `fixer` for each issue, at most `workers` at once.
|
|
112
|
+
export const machine = pool(fixer, {
|
|
113
|
+
id: "issues",
|
|
114
|
+
input: door,
|
|
115
|
+
source: issues,
|
|
116
|
+
itemId: (issue: Issue) => `issue-${issue.number}`,
|
|
117
|
+
cap: ({ input }) => input.workers,
|
|
118
|
+
// A `task` inside a Pool needs a branch. Make one from the issue number.
|
|
119
|
+
itemInput: (issue: Issue) => ({
|
|
120
|
+
prompt: `Fix issue #${issue.number} of this Repo: ${issue.title}\n\n${issue.body}`,
|
|
121
|
+
branch: `jr2/issue-${issue.number}`,
|
|
122
|
+
}),
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The file has five parts:
|
|
127
|
+
|
|
128
|
+
- **The Source.** `next` gets the open issues from the GitHub REST API. It gives the first issue that no worker has had.
|
|
129
|
+
When no issue is ready, it gives `null`. The request has no token, so the Repo must be public. Without a token, GitHub
|
|
130
|
+
allows 60 requests in each hour. The example reads only the first page of issues: at most 100. When the request fails
|
|
131
|
+
while workers run, `next` gives `null` in place of the error, so that the failure does not stop the run.
|
|
132
|
+
- **The record of the Source.** `next` keeps each issue that it gives in the `Set` `claimed`, and skips the issues in
|
|
133
|
+
`active`. The `Set` is in the memory of the [Orchestrator](../reference/glossary.md#orchestrator), and each run of the
|
|
134
|
+
Workflow uses the same `Set`. A restart of the Orchestrator empties it. Then `next` can give a finished issue again,
|
|
135
|
+
but never an issue that a worker of this run has now.
|
|
136
|
+
- **The worker.** `fixer` is `task` with its two [Open](../reference/glossary.md#open) parts bound: the Repo and the
|
|
137
|
+
model of the coder. [Bind a shipped Machine's Open parts](bind-open-parts.md) tells more.
|
|
138
|
+
- **The run input.** `door` is the run input of the Pool. `cap` reads `workers` from it. A worker never gets it.
|
|
139
|
+
- **The Pool.** `itemId` gives the id of each item. `itemInput` makes the input of the worker from the item: the prompt
|
|
140
|
+
and the branch.
|
|
141
|
+
|
|
142
|
+
Run [`jr2 up`](../reference/cli.md#up) to converge the Instance with the new Workflow:
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
jr2 up
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
…
|
|
150
|
+
jr2 up — instance "my-instance" → context kind-jr2 / namespace my-instance
|
|
151
|
+
typecheck: tsc --noEmit (the instance's own compiler)
|
|
152
|
+
failures: workflow "issues" — the states that fail the run (ADR-0073)
|
|
153
|
+
issues.failing: invokes fail
|
|
154
|
+
task.lost: invokes fail
|
|
155
|
+
…
|
|
156
|
+
seats: workflow "issues" — who may send what, per state (ADR-0015)
|
|
157
|
+
task.working agent:coder: [finish]
|
|
158
|
+
task.review gate: [approve, request_changes]
|
|
159
|
+
…
|
|
160
|
+
agents: coder, triager (carried by 4 workflow machine(s))
|
|
161
|
+
…
|
|
162
|
+
sandbox nodes: jr2-control-plane
|
|
163
|
+
…
|
|
164
|
+
converged — `jr2 run <workflow>` when ready
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The first line, `…`, is the line `→ .env:`, with the keys that the CLI took from `.env`. Each `jr2` command prints it
|
|
168
|
+
first. The output on this page shows `…` in its place.
|
|
169
|
+
|
|
170
|
+
## Start the run
|
|
171
|
+
|
|
172
|
+
Give the label `jr2` to one open issue or more of your Repo. With no such issue, the run ends at once, as `drained`.
|
|
173
|
+
|
|
174
|
+
Start a run in one terminal. `workers` is the largest number of issues that the run works on at the same time:
|
|
175
|
+
|
|
176
|
+
```sh
|
|
177
|
+
jr2 run issues --input '{"workers":2}'
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
```text
|
|
181
|
+
…
|
|
182
|
+
→ context kind-jr2 / namespace my-instance
|
|
183
|
+
run e1effd33-9bf6-4137-ae70-3aa504910784 (issues) — attached
|
|
184
|
+
→ active "discovering"
|
|
185
|
+
→ active "discovering"
|
|
186
|
+
→ active "discovering"
|
|
187
|
+
…
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The examples on this page use the Instance `my-instance` in the kubectl context `kind-jr2`. Your run id, instance id and
|
|
191
|
+
`assembly` hash are different. Give each `jr2` command in the Instance folder. Give the commands in the next steps in a
|
|
192
|
+
second terminal. In them, `<run id>` is the run id, or a unique prefix of it, 4 characters or more.
|
|
193
|
+
|
|
194
|
+
[`jr2 run`](../reference/cli.md#run) stays attached until the run ends. The run ends when no issue is ready and no
|
|
195
|
+
worker runs.
|
|
196
|
+
|
|
197
|
+
## Find the Gates of the workers
|
|
198
|
+
|
|
199
|
+
Run [`jr2 status`](../reference/cli.md#status):
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
jr2 status <run id>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
…
|
|
207
|
+
→ context kind-jr2 / namespace my-instance
|
|
208
|
+
{"runId":"e1effd33-9bf6-4137-ae70-3aa504910784","workflow":"issues",…,"gates":[{"gate":"source",…},{"gate":"issue-3.body.review",…},{"gate":"issue-2.body.review",…}]}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
In the JSON that it prints, `gates` holds each open Gate of the run:
|
|
212
|
+
|
|
213
|
+
- `source`: the Gate of the `wake` event of the Source. It is open for the whole run.
|
|
214
|
+
- `issue-<number>.body.review`: the `review` Gate of the worker for that issue. It opens when the coder finishes, or
|
|
215
|
+
when its [Turn](../reference/glossary.md#turn) fails. The id starts with the item id. `body` is the slot of the
|
|
216
|
+
Machine that `task` wraps.
|
|
217
|
+
|
|
218
|
+
The `meta` of a `review` Gate gives the `branch` and the `worktree` of the worker. The name of the Sandbox of a worker
|
|
219
|
+
holds its item id: `ws-<first 8 characters of the run id>-<item id>-<hash>`.
|
|
220
|
+
[Look inside a Sandbox](look-inside-a-sandbox.md) tells how to read the work before you approve it.
|
|
221
|
+
|
|
222
|
+
## Approve the work of one worker
|
|
223
|
+
|
|
224
|
+
Push the branch before you approve. `approve` ends that worker and removes its Sandbox, and the commits that you did not
|
|
225
|
+
push are lost. [Look inside a Sandbox](look-inside-a-sandbox.md#push-the-branch) tells how to push.
|
|
226
|
+
|
|
227
|
+
Then send `approve` to the Gate of the worker. This example approves issue 2:
|
|
228
|
+
|
|
229
|
+
```sh
|
|
230
|
+
jr2 send <run id> --gate issue-2.body.review --event approve
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```text
|
|
234
|
+
…
|
|
235
|
+
→ context kind-jr2 / namespace my-instance
|
|
236
|
+
delivered approve to gate "issue-2.body.review" on e1effd33-9bf6-4137-ae70-3aa504910784
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The Pool then calls `next` again, and starts a worker for the next issue.
|
|
240
|
+
|
|
241
|
+
The `review` Gate also takes `request_changes`, with `--input '{"notes":"<text>"}'`. Then the coder continues with the
|
|
242
|
+
notes, and the Gate opens again when it finishes. [Answer a Gate](answer-a-gate.md) gives the other ways to answer a
|
|
243
|
+
Gate.
|
|
244
|
+
|
|
245
|
+
## Tell the Pool about new work
|
|
246
|
+
|
|
247
|
+
While workers run and no issue is ready, the Pool waits. When you add the label to an issue, send the `wake` event to
|
|
248
|
+
the `source` Gate. The Pool then calls `next` at once:
|
|
249
|
+
|
|
250
|
+
```sh
|
|
251
|
+
jr2 send <run id> --gate source --event issues_changed
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
```text
|
|
255
|
+
…
|
|
256
|
+
→ context kind-jr2 / namespace my-instance
|
|
257
|
+
delivered issues_changed to gate "source" on e1effd33-9bf6-4137-ae70-3aa504910784
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Without the event, the Pool calls `next` again when a worker finishes, or after `pollEvery`. A webhook can send the same
|
|
261
|
+
event with [`POST /runs/:runId/gates/:gate/events`](../reference/http-api.md#post-runs-runid-gates-gate-events).
|
|
262
|
+
|
|
263
|
+
## The end of the run
|
|
264
|
+
|
|
265
|
+
When the last worker finishes and no issue is ready, the run ends. In the first terminal, `jr2 run` prints the last
|
|
266
|
+
state of the Pool, then the status of the run as JSON:
|
|
267
|
+
|
|
268
|
+
```text
|
|
269
|
+
…
|
|
270
|
+
→ active "discovering"
|
|
271
|
+
→ done "drained"
|
|
272
|
+
{"runId":"e1effd33-9bf6-4137-ae70-3aa504910784","workflow":"issues","instanceId":"db9712c8-7c19-4d18-8fb1-8c01d326808f","status":"done","value":"drained","context":{"runInput":{"workers":2,"instanceId":"db9712c8-7c19-4d18-8fb1-8c01d326808f"},"cap":2,"active":[],"items":{"issue-2":{"branch":"jr2/issue-2"},"issue-3":{"branch":"jr2/issue-3"},"issue-1":{"branch":"jr2/issue-1"}},"failures":{},"status":"drained"},"children":[],"waiting":[],"held":[],"assembly":"ca3b0e760c85","output":{"status":"drained","items":{"issue-2":{"branch":"jr2/issue-2"},"issue-3":{"branch":"jr2/issue-3"},"issue-1":{"branch":"jr2/issue-1"}},"failures":{}}}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
In the JSON, `context.items` holds the output of each worker that finished, by item id. `context.failures` holds the
|
|
276
|
+
[Failure](../reference/glossary.md#failure) of each worker that failed, by item id: here, none. For this Source,
|
|
277
|
+
`context.status` is always `drained`, because `next` never gives `open`.
|
|
278
|
+
[Pools and Sources](../concepts/pools-and-sources.md#how-the-run-ends) tells what each status means.
|
|
279
|
+
|
|
280
|
+
## Rules
|
|
281
|
+
|
|
282
|
+
- `itemId` must give each item an id of its own, and the same id each time. It is the id of the worker, the key in
|
|
283
|
+
`items`, and the start of the id of each Gate of the worker.
|
|
284
|
+
- `next` must not give an item that a worker has now. jr2 does not refuse the item when `next` gives it. A second worker
|
|
285
|
+
starts in the same Sandbox and the same [Worktree](../reference/glossary.md#worktree) as the first. When the two
|
|
286
|
+
workers register the same Gate or [Agent](../reference/glossary.md#agent), the run stops with the status `error`, and
|
|
287
|
+
its `fault` is `registration address "<address>" is already live (two concurrent registrations share an id)`. For
|
|
288
|
+
`task`, `<address>` is `gate/<run id>/<item id>.body.review` or `agent/<run id>/<item id>.body/coder`.
|
|
289
|
+
- `next` gets only `active`: the ids of the items that workers have now. To not give a finished item again, the Source
|
|
290
|
+
must keep the items that it gave.
|
|
291
|
+
- When a worker fails, for example when the Sandbox of a `task` is lost, the Pool keeps the Failure in `failures` and
|
|
292
|
+
goes on. Only the Sandbox of that worker is deleted. The other workers, and the work in their Sandboxes, stay. A
|
|
293
|
+
defect in a worker is different: the run stops with the status `error`.
|
|
294
|
+
- When the Pool ends with one or more failures, `drained` or `deadlocked`, the run ends `failed`, with the reason
|
|
295
|
+
`<n> of <m> items failed`, and `jr2 run` exits 1. The detail of the Failure is `{ status, items, failures }`. With the
|
|
296
|
+
option `failures: "report"`, the run ends `done`, and the failures are in its output.
|
|
297
|
+
- When `next` rejects, the run stops. Its status is `error`, and its `fault` is the message of the error.
|
|
298
|
+
- `pool()` does not carry the item type of the Source to `itemId` and `itemInput`. Write the type on their parameter, as
|
|
299
|
+
in `(issue: Issue)`.
|
|
300
|
+
- A worker gets its item, or what `itemInput` makes of it. It never gets the run input. `cap` and `itemInput` get the
|
|
301
|
+
run input as `{ input }`, typed by the `input` schema of the Pool.
|
|
302
|
+
- The Orchestrator refuses a run input that does not match the `input` schema of the Pool. `jr2 run` prints
|
|
303
|
+
`error: invalid input for workflow "<workflow>": <reason>`.
|
|
304
|
+
- A `task` inside a Pool needs `branch` in its input. Without it, the run stops with the status `error`, and its `fault`
|
|
305
|
+
starts with ``task: no `branch` on the door and no Instance ID to derive one from``.
|
|
306
|
+
- Without `cap`, one worker runs at a time. Each `task` worker has its own
|
|
307
|
+
[Workspace](../reference/glossary.md#workspace). Thus the run has `cap` Sandboxes or fewer at one time.
|
|
308
|
+
- The Pool takes the `wake` event only while it waits: workers run, and no item is ready. At other times,
|
|
309
|
+
[`jr2 send`](../reference/cli.md#send) refuses it:
|
|
310
|
+
`error: gate "source" is open, and the run does not take "<event>" now: no writing of it would move the run with this payload — not delivered (takes now: nothing)`.
|
|
311
|
+
- `onDrained` takes only `"final"`: the run ends.
|
|
312
|
+
|
|
313
|
+
## Read next
|
|
314
|
+
|
|
315
|
+
- [Pools and Sources](../concepts/pools-and-sources.md)
|
|
316
|
+
- [Composition](../concepts/composition.md)
|
|
317
|
+
- [Gates](../concepts/gates.md)
|
|
318
|
+
- Reference: [`pool()`](../reference/authoring-surface/pool.md), [`source()`](../reference/authoring-surface/source.md),
|
|
319
|
+
[`PoolSpec`](../reference/authoring-surface/type-poolspec.md),
|
|
320
|
+
[`SourceSpec`](../reference/authoring-surface/type-sourcespec.md), [`task`](../reference/machines.md#task)
|
|
321
|
+
- [ADR-0017](../reference/decisions/0017-pool-over-a-source-port.md): the run loop is a Pool over a Source
|