@jr2/orchestrator 0.3.0 → 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/bin/server.ts +7 -4
- package/console/canvas.ts +27 -14
- package/console/components/app.ts +12 -1
- package/console/components/fleet.ts +52 -6
- package/console/components/machine-pane.ts +128 -2
- package/console/components/nav.ts +1 -1
- package/console/components/schema-form.ts +12 -4
- package/console/json-field.ts +23 -0
- package/console/main.ts +122 -39
- package/console/store.ts +321 -21
- package/console/style.css +111 -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 +6 -4
- package/src/actor.ts +976 -61
- package/src/agent.ts +114 -38
- package/src/ambient.ts +4 -1
- package/src/assembly-checks.ts +347 -0
- package/src/assembly-tar.ts +494 -0
- package/src/assembly.ts +721 -0
- package/src/cause.ts +234 -0
- package/src/chart.ts +2182 -0
- package/src/charts.ts +748 -0
- package/src/config.ts +520 -162
- package/src/content-hash.ts +105 -0
- package/src/custodian.lua +6 -5
- package/src/custodian.ts +143 -39
- package/src/customize.ts +388 -55
- package/src/dispatch-effect.ts +945 -0
- package/src/door-compat.ts +217 -0
- package/src/durability.ts +11 -4
- package/src/effect-checks.ts +557 -0
- package/src/effect.ts +1202 -0
- package/src/effector-wire.ts +674 -0
- package/src/fail.ts +209 -0
- package/src/fingerprint.ts +4 -3
- package/src/gate.ts +8 -0
- package/src/git-clone.ts +65 -0
- package/src/git-push.ts +336 -0
- package/src/harness-client.ts +764 -48
- package/src/held-secrets.ts +82 -26
- package/src/holds.ts +156 -0
- package/src/http-effect.ts +1423 -0
- package/src/http.ts +916 -113
- package/src/images.ts +47 -21
- package/src/index.ts +62 -43
- package/src/instance.ts +505 -59
- package/src/internal.ts +84 -0
- package/src/kube-client.ts +333 -0
- package/src/machine-doc.ts +106 -6
- package/src/mechanism-routes.ts +168 -0
- package/src/model-keys.generated.ts +53 -0
- package/src/model-keys.ts +18 -58
- package/src/mount-digest.ts +53 -0
- package/src/names.ts +66 -8
- package/src/notices.ts +141 -0
- package/src/open-body.ts +1580 -0
- package/src/open-effect.ts +217 -0
- package/src/open.ts +59 -6
- package/src/parts.ts +709 -41
- package/src/party.ts +534 -0
- package/src/pick.ts +761 -0
- package/src/pool.ts +248 -37
- package/src/registration.ts +382 -19
- package/src/repo-fetch.ts +60 -85
- package/src/repos.ts +65 -75
- package/src/rest.ts +133 -0
- package/src/run-host.ts +2383 -115
- package/src/run-output.ts +38 -0
- package/src/sandbox-effect.ts +1126 -0
- package/src/sandbox-effector.ts +111 -0
- package/src/sandbox-kube.ts +1721 -0
- package/src/sandbox-watch.ts +260 -0
- package/src/secret-placement.ts +529 -0
- package/src/server.ts +284 -84
- package/src/setup.ts +819 -117
- package/src/size.ts +454 -0
- package/src/snapshot-store.ts +115 -20
- package/src/stub-harness.ts +49 -16
- package/src/sync-client.ts +54 -0
- package/src/timers.ts +191 -0
- package/src/tokens.ts +35 -4
- package/src/vocabulary.ts +135 -15
- package/src/wire.ts +238 -10
- package/src/workspace.ts +1195 -338
- package/src/sandbox-kubectl.ts +0 -1108
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "@jr2/machines"
|
|
3
|
+
description: "The Machines that @jr2/machines ships: their input, their output, and their Open parts."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @jr2/machines
|
|
7
|
+
|
|
8
|
+
`@jr2/machines` ships Machines, not Workflows. A Machine becomes a Workflow when a file in the Instance's `workflows/` folder exports it, with each [Open](glossary.md#open) part bound by [`customize`](authoring-surface/customize.md). Install it beside `@jr2/orchestrator`, at the same version: it is a peer of the kit, never a copy of it.
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- [`TaskInput`](#type-taskinput), [`TaskOutput`](#type-taskoutput), [`body`](#body), [`task`](#task)
|
|
13
|
+
|
|
14
|
+
<a id="type-taskinput"></a>
|
|
15
|
+
|
|
16
|
+
### `TaskInput`
|
|
17
|
+
|
|
18
|
+
Type, in `@jr2/machines/src/task.ts`.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
type TaskInput = {
|
|
22
|
+
prompt: string;
|
|
23
|
+
branch?: string | undefined;
|
|
24
|
+
model?: string | undefined;
|
|
25
|
+
thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined;
|
|
26
|
+
};
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The run input of `task`: what a caller sends to start a run, for example with
|
|
30
|
+
`jr2 run <workflow> --input '{"prompt":"…"}'`.
|
|
31
|
+
|
|
32
|
+
`prompt` is required. `branch`, `model` and `thinkingLevel` are optional. Each field has its own
|
|
33
|
+
doc.
|
|
34
|
+
|
|
35
|
+
**Fields**
|
|
36
|
+
|
|
37
|
+
- `prompt`: `string`
|
|
38
|
+
|
|
39
|
+
What to do, in prose. Required. The coder's first Turn is this prompt, with the Worktree it
|
|
40
|
+
works in.
|
|
41
|
+
- `branch` (optional): `string`
|
|
42
|
+
|
|
43
|
+
The branch to cut and commit on. Default: `jr2/task-<instance id>`, where `<instance id>` is
|
|
44
|
+
the seed Instance ID of the run (`instanceId` in `jr2 status`). It is not the run id. Two runs
|
|
45
|
+
never use the same branch. Required when `task` runs inside another Machine, such as a
|
|
46
|
+
`pool()`: there is no Instance ID to name the branch after.
|
|
47
|
+
- `model` (optional): `string`
|
|
48
|
+
|
|
49
|
+
The coder's model for this run only, as `"<provider>/<modelId>"`. Default: the model of the
|
|
50
|
+
coder Agent.
|
|
51
|
+
- `thinkingLevel` (optional): `"off" | "minimal" | "low" | "medium" | "high" | "xhigh"`
|
|
52
|
+
|
|
53
|
+
The coder's thinking level for this run only: `off`, `minimal`, `low`, `medium`, `high` or
|
|
54
|
+
`xhigh`. Default: the thinking level of the coder Agent.
|
|
55
|
+
|
|
56
|
+
**Example**
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import type { TaskInput } from "@jr2/machines";
|
|
60
|
+
|
|
61
|
+
export const input: TaskInput = {
|
|
62
|
+
prompt: "Make the failing test in test/greet.test.ts pass.",
|
|
63
|
+
branch: "fix/greet",
|
|
64
|
+
thinkingLevel: "high",
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
<a id="type-taskoutput"></a>
|
|
69
|
+
|
|
70
|
+
### `TaskOutput`
|
|
71
|
+
|
|
72
|
+
Type, in `@jr2/machines/src/task.ts`.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
type TaskOutput = { branch: string };
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The output of a run of `task` that ends `done`: `{ branch }`, the branch of the work that the
|
|
79
|
+
human approved. A run whose Workspace is lost has no output of this type: it fails, and the run
|
|
80
|
+
ends `failed` with the reason `the Workspace was lost` ([ADR-0073](decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md)).
|
|
81
|
+
|
|
82
|
+
**Fields**
|
|
83
|
+
|
|
84
|
+
- `branch`: `string`
|
|
85
|
+
|
|
86
|
+
**Example**
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import type { TaskOutput } from "@jr2/machines";
|
|
90
|
+
|
|
91
|
+
export function describe(output: TaskOutput): string {
|
|
92
|
+
return `approved on ${output.branch}`;
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
<a id="body"></a>
|
|
97
|
+
|
|
98
|
+
### `body`
|
|
99
|
+
|
|
100
|
+
Constant, in `@jr2/machines/src/task.ts`.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const body: StateMachine<…>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Type: `StateMachine`, from `xstate`.
|
|
107
|
+
|
|
108
|
+
The Machine inside `task`: the coder's loop and the `review` Gate, with no `workspace()` around
|
|
109
|
+
it. Use `task` to run it. Use `body` only to put the same loop in a `workspace()` of your own.
|
|
110
|
+
For example, your `workspace()` can have Repo Slots or a run input that differ from those of
|
|
111
|
+
`task`. Its input is the run input plus the `workspace` handles, and it works in the first Repo
|
|
112
|
+
Slot of those handles.
|
|
113
|
+
|
|
114
|
+
**Example**
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { customize, workspace } from "@jr2/orchestrator";
|
|
118
|
+
import { body, type TaskInput } from "@jr2/machines";
|
|
119
|
+
|
|
120
|
+
const fixed = workspace(body, {
|
|
121
|
+
repos: { app: { url: "https://github.com/you/app.git" } },
|
|
122
|
+
spec: ({ input }: { input: TaskInput }) => ({ branch: input.branch ?? "jr2/fix" }),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
export const machine = customize(fixed, {
|
|
126
|
+
agents: { coder: { model: "anthropic/claude-haiku-5-5" } },
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**See also**
|
|
131
|
+
|
|
132
|
+
- [Workspaces](../concepts/workspaces.md)
|
|
133
|
+
|
|
134
|
+
<a id="task"></a>
|
|
135
|
+
|
|
136
|
+
### `task`
|
|
137
|
+
|
|
138
|
+
Constant, in `@jr2/machines/src/task.ts`.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
const task: WorkspaceMachine<…>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Type: [`WorkspaceMachine`](authoring-surface/type-workspacemachine.md).
|
|
145
|
+
|
|
146
|
+
A Machine in which a coder Agent works on one prompt in a Workspace until a human approves the
|
|
147
|
+
work. The coder works in a Sandbox and commits on a branch. Then the run waits at the `review`
|
|
148
|
+
Gate. The human answers `request_changes` with `notes`, and the coder continues the same
|
|
149
|
+
conversation, or `approve`, and the run ends. A run has no limit on the number of rounds.
|
|
150
|
+
|
|
151
|
+
`task` does not push. While the run waits at the Gate, the Sandbox stays. You can exec into it
|
|
152
|
+
and read the branch. To keep the work, push it yourself. `approve` removes the Sandbox, and
|
|
153
|
+
every commit that was not pushed goes with it. If the Sandbox is lost, `task` fails: the run
|
|
154
|
+
ends `failed` with the reason `the Workspace was lost`. A parent Machine catches that Failure
|
|
155
|
+
with an `onError` that `isFailure` guards.
|
|
156
|
+
|
|
157
|
+
`task` leaves two parts Open, so you bind them with `customize()` where you register it:
|
|
158
|
+
|
|
159
|
+
- `repos`: the whole Repo Slot map. Name every slot, and at least one. The first slot is the
|
|
160
|
+
Repo that the coder works in. The coder can read the others.
|
|
161
|
+
- `agents.coder.model`: the coder's model, as `"<provider>/<modelId>"`. You can also change the
|
|
162
|
+
coder's other fields, such as `instructions` or `thinkingLevel`.
|
|
163
|
+
|
|
164
|
+
`jr2 up` refuses a Workflow that leaves either part Open, and prints the `customize()` line
|
|
165
|
+
that binds it. You can also give `task` an `image`, a `user` or a Size (`resources`). Without an
|
|
166
|
+
image, it uses the Instance's `images/default`, or jr2's Harness image when there is none.
|
|
167
|
+
Without a Size, it uses the Instance's `sandbox.resources`, or the kit's Size when it has none.
|
|
168
|
+
Inside another Machine, `task` needs `branch` in its input, or it refuses:
|
|
169
|
+
``task: no `branch` on the door and no Instance ID to derive one from``.
|
|
170
|
+
|
|
171
|
+
**Example**
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { customize } from "@jr2/orchestrator";
|
|
175
|
+
import { task } from "@jr2/machines";
|
|
176
|
+
|
|
177
|
+
export const machine = customize(task, {
|
|
178
|
+
repos: {
|
|
179
|
+
app: { url: "https://github.com/you/app.git" },
|
|
180
|
+
lib: { url: "https://github.com/you/lib.git" },
|
|
181
|
+
},
|
|
182
|
+
agents: { coder: { model: "anthropic/claude-haiku-5-5" } },
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**See also**
|
|
187
|
+
|
|
188
|
+
- [An Agent in a Sandbox](../get-started/an-agent-in-a-sandbox.md)
|
|
189
|
+
- [Bind a shipped Machine's Open parts](../guides/bind-open-parts.md)
|
|
190
|
+
- [ADR-0054: The kit ships Machines, and a shipped Machine leaves its parts Open](decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Mechanism events
|
|
3
|
+
description: The events that jr2 itself sends into every jr2Setup Machine, and their payloads.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mechanism events
|
|
7
|
+
|
|
8
|
+
jr2's own mechanism delivers these events into every Machine that `jr2Setup` makes, beside the workflow events its `defineEvent` defs declare. Handle one with an `on` key, as any event: `on: { "agent.fault": "failed" }`. A Mechanism event's name has a dot, and a workflow event's name cannot, so the two never collide. The Machine's event type, `WorkflowEvent`, holds them already.
|
|
9
|
+
|
|
10
|
+
Each Mechanism event must have a route. `jr2 check` and `jr2 up` refuse a state that invokes an Agent, or an Open body that lends an Agent or allows a model, when that state and each state above it have no `agent.fault` route, and `workspace()` refuses a body with a state that is not final and has no `workspace.lost` route on itself or on a state above. One route on the root satisfies each rule. A route with actions only is a route. When the event comes and no transition takes it, because the guard of its route is false, the run ends `error`, and its fault names the event, the state and the reason. In a [Chart](../concepts/charts.md), the `agent.fault` route is optional: when no transition of the Chart takes it, the Open body sends it, unchanged, to the Machine that invoked the body, and that Machine's own route takes it.
|
|
11
|
+
|
|
12
|
+
To end the run as a Failure when a Mechanism event comes, route it to a state that invokes [`fail`](authoring-surface/fail.md): `lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } }`. The run then ends `failed`, not `done`, because a final state means that the work succeeded.
|
|
13
|
+
|
|
14
|
+
<a id="type-mechanismevent"></a>`MechanismEvent` is one of these events: [`agent.fault`](#agent-fault), [`workspace.lost`](#workspace-lost).
|
|
15
|
+
|
|
16
|
+
<a id="agent-fault"></a>
|
|
17
|
+
|
|
18
|
+
## `agent.fault`
|
|
19
|
+
|
|
20
|
+
- Type: `FaultTelemetry`
|
|
21
|
+
- Sent by: The Agent slot (`agent()`) that the state invoked, to the Machine that invoked it.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
type FaultTelemetry = {
|
|
25
|
+
type: "agent.fault";
|
|
26
|
+
instanceId: string;
|
|
27
|
+
reason: string;
|
|
28
|
+
};
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
jr2 sends `agent.fault` to the Machine when an Agent's Turn cannot go on: the Harness failed
|
|
32
|
+
the Turn, or the Agent ended its Turns with no pick after every nudge. The Machine decides what
|
|
33
|
+
to do next. Route it in the state that invokes the Agent, or in a state above it, with
|
|
34
|
+
`on: { "agent.fault": … }`; one route on the root is a route for each state. `jr2 check` and
|
|
35
|
+
`jr2 up` refuse a state that invokes an Agent, or an Open body that can run one, with no route for
|
|
36
|
+
it. When the event comes and no transition takes it (the route's guard is false), the run ends
|
|
37
|
+
`error`, with the event, the state and the reason in its fault. In a Chart the route is optional:
|
|
38
|
+
when no transition of the Chart takes the event, the Open body sends it, unchanged, to the Machine
|
|
39
|
+
that invoked the body, whose route takes it.
|
|
40
|
+
|
|
41
|
+
**Payload**
|
|
42
|
+
|
|
43
|
+
- `instanceId`, `string`: The Instance ID of the Agent's conversation that failed: the same id on each Turn that continues it.
|
|
44
|
+
- `reason`, `string`: Why the Turn failed, as text for a person or a log: the Harness's error, or that the Agent ended its Turns without a pick after every nudge. Route on the event, not on this text.
|
|
45
|
+
|
|
46
|
+
<a id="workspace-lost"></a>
|
|
47
|
+
|
|
48
|
+
## `workspace.lost`
|
|
49
|
+
|
|
50
|
+
- Type: `WorkspaceLost`
|
|
51
|
+
- Sent by: `workspace()`, to its body Machine, when the Workspace's Sandbox is gone.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
type WorkspaceLost = {
|
|
55
|
+
type: "workspace.lost";
|
|
56
|
+
reason?: string;
|
|
57
|
+
message?: string;
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
jr2 sends `workspace.lost` to the body of a `workspace()` when its Sandbox is gone: its pod was
|
|
62
|
+
evicted or deleted, or its node went. jr2 does not make the Sandbox again, and the commits that
|
|
63
|
+
were not pushed go with it. The body decides what to do next: route the event with
|
|
64
|
+
`on: { "workspace.lost": … }`, usually once, on the body's root. `workspace()` refuses a body
|
|
65
|
+
with a state that is not final and has no route for it on itself or on a state above. When the
|
|
66
|
+
event comes and no transition takes it (the route's guard is false), the run ends `error`, with
|
|
67
|
+
the event, the state and the reason in its fault.
|
|
68
|
+
|
|
69
|
+
**Payload**
|
|
70
|
+
|
|
71
|
+
- `reason` (optional), `string`: Why the Sandbox is gone, for a person or a log: the pod's reason (`Evicted`, `NodeShutdown`), the operator's (`PodDeleted`, `NodeLost`), or `Deleted`. A body can act without it.
|
|
72
|
+
- `message` (optional), `string`: More text about the loss, when jr2 has it.
|
package/docs/why.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Why jr2
|
|
3
|
+
description: The parts of jr2, the problems of agentic workflows that each part solves, and one run through them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Why jr2
|
|
7
|
+
|
|
8
|
+
jr2 runs an agentic workflow as a [Machine](reference/glossary.md#machine): a graph of states that you write. In a
|
|
9
|
+
state, an [Agent](reference/glossary.md#agent) or an [Effect](reference/glossary.md#effect) does the work, or a
|
|
10
|
+
[Gate](reference/glossary.md#gate) waits for an answer. The Machine decides which state comes next. The diagram shows
|
|
11
|
+
the parts of jr2, from you to the world outside your cluster.
|
|
12
|
+
|
|
13
|
+
**The parts of jr2, from you to the world outside your cluster**
|
|
14
|
+
|
|
15
|
+
- **You**: start runs, and answer them
|
|
16
|
+
- jr2 CLI
|
|
17
|
+
- Console
|
|
18
|
+
- your own app
|
|
19
|
+
- ↓ you start a run · ↑ approval → You: a Gate asks you · ↓ You → approval: you answer
|
|
20
|
+
- **your cluster**: `jr2 up` sets it up
|
|
21
|
+
- **Orchestrator**: runs your Machine, and keeps each run
|
|
22
|
+
- ● → code → **review** → approval → ◉ done
|
|
23
|
+
- review → approval: `approved`
|
|
24
|
+
- review → code: `changes`
|
|
25
|
+
- approval → code: `changes`
|
|
26
|
+
- ↓ `review` gives the reviewer a Turn and its Menu · ↑ the reviewer picks `approved`
|
|
27
|
+
- **Sandbox**: one pod for each Workspace
|
|
28
|
+
- **Harness**: runs each Turn, with a shell
|
|
29
|
+
- **coder** (Agent): edits and commits
|
|
30
|
+
- **reviewer** (Agent): its Menu: `approved` `changes`
|
|
31
|
+
- **Worktree**: your code
|
|
32
|
+
- **Custodian**: keys that the Agents can use but not read, such as the model key
|
|
33
|
+
- **Effector**: keys that only your Effects use, such as a git credential
|
|
34
|
+
- ↓ Custodian → Outside · Effector → Outside
|
|
35
|
+
- **Outside**: what the work uses
|
|
36
|
+
- model provider
|
|
37
|
+
- your APIs
|
|
38
|
+
- git host
|
|
39
|
+
|
|
40
|
+
Each section below gives one problem of agentic workflows, and the part of the diagram that solves it. The sections go
|
|
41
|
+
from the top of the diagram to the bottom.
|
|
42
|
+
|
|
43
|
+
## Headless
|
|
44
|
+
|
|
45
|
+
A workflow must connect to the systems that you use, such as a code review, a chat or a CI job. One user interface
|
|
46
|
+
cannot be the right one for each of them.
|
|
47
|
+
|
|
48
|
+
The You band of the diagram holds the clients of jr2. The [Orchestrator](reference/glossary.md#orchestrator) is an HTTP
|
|
49
|
+
API. The [jr2 CLI](reference/glossary.md#jr2-cli) and the [Console](reference/glossary.md#console) are its clients, and
|
|
50
|
+
your own app, such as a webhook, can be one too. For example, a client can start a run with
|
|
51
|
+
[`POST /workflows/:name/runs`](reference/http-api.md#post-workflows-name-runs). In the diagram, a
|
|
52
|
+
[Gate](reference/glossary.md#gate) in the state `approval` asks you, and you answer from any of these clients, with
|
|
53
|
+
[`POST /runs/:runId/gates/:gate/events`](reference/http-api.md#post-runs-runid-gates-gate-events).
|
|
54
|
+
|
|
55
|
+
Read [Architecture](concepts/architecture.md) and [Gates](concepts/gates.md).
|
|
56
|
+
|
|
57
|
+
## Determinism
|
|
58
|
+
|
|
59
|
+
A workflow must do the steps that it sets, in the order that it sets. But a model does not do the same thing two times.
|
|
60
|
+
When the steps of a workflow are text in a prompt, the model can skip a step or change the order. "You must" and "never"
|
|
61
|
+
are requests to the model, not rules that it must obey. You can review the code that an agentic workflow makes, but you
|
|
62
|
+
cannot easily review how it made that code.
|
|
63
|
+
|
|
64
|
+
In jr2, a workflow is a Machine: an [xstate](https://xstate.js.org) state machine in TypeScript. The Orchestrator band
|
|
65
|
+
of the diagram holds an example Machine, with the states `code`, `review` and `approval`, and the final state `done`.
|
|
66
|
+
Its states and its transitions are a graph that you can read before a run starts. The Console draws that graph, and
|
|
67
|
+
while a run runs, it shows the state that the run is in. A Machine can have loops: in the diagram, `changes` sends the
|
|
68
|
+
run back to `code`.
|
|
69
|
+
|
|
70
|
+
An Agent does not move the Machine itself. A [Turn](reference/glossary.md#turn) is one piece of work for one Agent. The
|
|
71
|
+
state that the run is in gives the Agent a prompt and a [Menu](reference/glossary.md#menu): the events that go out of
|
|
72
|
+
that state. In the diagram, the run is in `review`, so the Menu of the reviewer is `approved` and `changes`. The Agent
|
|
73
|
+
ends its Turn with one pick from its Menu, and the Machine refuses a pick that is not one of its
|
|
74
|
+
[Allowed picks](reference/glossary.md#allowed-picks) now. Thus the model makes the decision in each state, and the
|
|
75
|
+
Machine sets the transition that each decision causes. You review how the work happens, not only the code that comes out
|
|
76
|
+
of it. The model is not deterministic, but the Machine is: in one state, one pick always causes the same transition.
|
|
77
|
+
|
|
78
|
+
The Agent can also decide the order of the work. A pick whose target is inside the Agent's state does not end the Turn.
|
|
79
|
+
The Machine runs the work of the pick, such as an Effect or a Gate, and answers the pick with the result. A
|
|
80
|
+
[mode](reference/glossary.md#mode) or a guard sets which picks the Agent can make next. Thus the Agent decides when each
|
|
81
|
+
step runs, and the Machine decides what each step does. An Agent can also write a [Chart](reference/glossary.md#chart):
|
|
82
|
+
a Machine as data, which jr2 checks before it runs.
|
|
83
|
+
|
|
84
|
+
Read [Machines and Workflows](concepts/machines-and-workflows.md),
|
|
85
|
+
[The Menu](concepts/the-menu.md#keep-the-turn-or-end-it) and [Charts](concepts/charts.md).
|
|
86
|
+
|
|
87
|
+
## Composition
|
|
88
|
+
|
|
89
|
+
An Agent does one thing well. When you give it many things at the same time, it loses its focus. The infrastructure of a
|
|
90
|
+
workflow, such as a Sandbox or a set of work items, also must not get into the task of the Agent.
|
|
91
|
+
|
|
92
|
+
The diagram shows one Machine, but the infrastructure around it is xstate too. A
|
|
93
|
+
[Workspace](reference/glossary.md#workspace) wraps a body Machine that does not know about the Sandbox. A
|
|
94
|
+
[Pool](reference/glossary.md#pool) runs one worker Machine for each item that a [Source](reference/glossary.md#source)
|
|
95
|
+
gives. A Gate is an actor that a state invokes to wait for an outside input, such as the Gate in `approval`. Each state
|
|
96
|
+
sets the [Frame](reference/glossary.md#frame) of one Turn, so an Agent does one thing at a time.
|
|
97
|
+
|
|
98
|
+
A Machine can invoke a different Machine. A Machine can also leave a part [Open](reference/glossary.md#open), such as
|
|
99
|
+
the URL of a Repo or the model of an Agent. You bind that part with
|
|
100
|
+
[`customize()`](reference/authoring-surface/customize.md). Thus a Machine can come from an npm package, such as the
|
|
101
|
+
[`task`](reference/machines.md#task) Machine in `@jr2/machines`.
|
|
102
|
+
|
|
103
|
+
Read [Composition](concepts/composition.md) and [Pools and Sources](concepts/pools-and-sources.md).
|
|
104
|
+
|
|
105
|
+
## Isolation
|
|
106
|
+
|
|
107
|
+
A filesystem sandbox is not isolation. Agents on one computer share its ports, its processes and its credentials. Two
|
|
108
|
+
Agents can need the same port, or the same file in your home folder. An Agent can also leave a process or a server that
|
|
109
|
+
runs after the work stops.
|
|
110
|
+
|
|
111
|
+
The Sandbox band of the diagram is one pod. An Agent that works on a [Repo](reference/glossary.md#repo) works in a
|
|
112
|
+
[Sandbox](reference/glossary.md#sandbox): a pod with its own filesystem, network and processes. There is one Sandbox for
|
|
113
|
+
each Workspace, and the Agents of one Workspace share it. The [Harness](reference/glossary.md#harness) runs each Turn.
|
|
114
|
+
It talks to the model, and it runs the tools of the Agent. The Agent can run each command in the Harness container. An
|
|
115
|
+
Agent that needs only its Menu has no Sandbox. Its Turns run on the
|
|
116
|
+
[Instance Harness](reference/glossary.md#instance-harness).
|
|
117
|
+
|
|
118
|
+
The Harness container holds no credential, so a command that an Agent runs cannot read one. jr2 keeps each credential in
|
|
119
|
+
one of the two containers beside it:
|
|
120
|
+
|
|
121
|
+
- The [Custodian](reference/glossary.md#custodian) holds each [Held secret](reference/glossary.md#held-secret): a key
|
|
122
|
+
that the Agents can use, but cannot read. The Harness holds only a [Stand-in](reference/glossary.md#stand-in) for it.
|
|
123
|
+
The Custodian puts the real key in place of the Stand-in, in each request to the host of that key. A Stand-in has no
|
|
124
|
+
value outside its pod. The model key is a Held secret. A token for an API that the Agents call can be one too.
|
|
125
|
+
- The [Effector](reference/glossary.md#effector) holds each [Effect secret](reference/glossary.md#effect-secret): a key
|
|
126
|
+
that only an [Effect](reference/glossary.md#effect) of your Machine uses, such as a push or a call to an API. The
|
|
127
|
+
Agents cannot use it.
|
|
128
|
+
|
|
129
|
+
Put a key in the Custodian when the Agents can use it as they decide. Put it in the Effector when only your Machine
|
|
130
|
+
decides when to use it. One key can be in both containers.
|
|
131
|
+
|
|
132
|
+
When the Workspace ends, its Sandbox ends too. When a [Lease](reference/glossary.md#lease) lapses, the operator removes
|
|
133
|
+
what the Agents left behind.
|
|
134
|
+
|
|
135
|
+
Read [Workspaces](concepts/workspaces.md) and [Secrets and trust](concepts/secrets-and-trust.md).
|
|
136
|
+
|
|
137
|
+
## Model agnostic
|
|
138
|
+
|
|
139
|
+
A workflow must not depend on one model or one provider. You can change the model of one Agent, and keep the Machine.
|
|
140
|
+
|
|
141
|
+
In the diagram, the line from the Custodian goes to a model provider outside your cluster. jr2 has one Harness, and it
|
|
142
|
+
is jr2's own. An Agent is a model and its instructions. The model is a name such as `<provider>/<model>`. The provider
|
|
143
|
+
is one from the model catalog of the Harness, or an endpoint that you run and set in
|
|
144
|
+
[`harness.provider`](reference/config.md#harness-provider). The same Harness runs the Turns of each Agent, with each
|
|
145
|
+
provider. A state can set the model of one Turn.
|
|
146
|
+
|
|
147
|
+
Read [Agents and Turns](concepts/agents-and-turns.md).
|
|
148
|
+
|
|
149
|
+
## Distribution
|
|
150
|
+
|
|
151
|
+
One computer has a limit. One build can use all of its CPU, and the other Agents then wait. A run on a laptop also stops
|
|
152
|
+
when the laptop stops.
|
|
153
|
+
|
|
154
|
+
In the diagram, the bracket is your cluster, and the compute is in it. For each Agent, the Orchestrator holds only an
|
|
155
|
+
[Actor](reference/glossary.md#actor): a local handle. The Harness that runs the Turns of the Agent runs where the
|
|
156
|
+
cluster puts it. A Sandbox can go on each node that can run an ordinary pod. The Orchestrator keeps a snapshot of each
|
|
157
|
+
run on its volume, so a run continues after a restart of the Orchestrator. On a shared cluster, a run continues when
|
|
158
|
+
your computer is off.
|
|
159
|
+
|
|
160
|
+
Read [Architecture](concepts/architecture.md).
|
|
161
|
+
|
|
162
|
+
## One converging command
|
|
163
|
+
|
|
164
|
+
A workflow that runs on a laptop must also run on a shared cluster, without a second set of steps.
|
|
165
|
+
|
|
166
|
+
The bracket of the diagram has the label `jr2 up`. [`jr2 up`](reference/cli.md#up) converges an
|
|
167
|
+
[Instance](reference/glossary.md#instance) folder into the cluster of the current kubectl context. It builds the images
|
|
168
|
+
that the folder needs, and it puts the Orchestrator and the operator in the cluster. It does not start a Sandbox: during
|
|
169
|
+
a run, the operator makes one Sandbox for each Workspace. The same folder converges into kind on a laptop or into a
|
|
170
|
+
shared cluster. You select the cluster with the kubectl context. A shared cluster also needs a container registry, which
|
|
171
|
+
`.env` gives to [`registry`](reference/config.md#registry). You can run `jr2 up` again at any time.
|
|
172
|
+
|
|
173
|
+
Read [Converge](concepts/converge.md).
|
|
174
|
+
|
|
175
|
+
## A typed Instance
|
|
176
|
+
|
|
177
|
+
An error in a workflow or in its config can show only when a run gets to it. A run can take many minutes to get there.
|
|
178
|
+
|
|
179
|
+
In jr2, a Machine names its Agents, its [Repo Slots](reference/glossary.md#repo-slot) and the Machines that it invokes,
|
|
180
|
+
and TypeScript checks each name. `jr2.config.ts` uses [`defineConfig()`](reference/authoring-surface/defineconfig.md),
|
|
181
|
+
so TypeScript checks the config too. `jr2 up` runs the typecheck first. When the typecheck fails, `jr2 up` builds
|
|
182
|
+
nothing and changes nothing on the cluster. Next, it refuses an Open part that no `customize()` binds. Thus you find
|
|
183
|
+
these errors before a run starts.
|
|
184
|
+
|
|
185
|
+
Read [Converge](concepts/converge.md) and [Machines and Workflows](concepts/machines-and-workflows.md).
|
|
186
|
+
|
|
187
|
+
## One run
|
|
188
|
+
|
|
189
|
+
These steps follow one run of the example Machine in the diagram. You write a Machine like it in TypeScript, or your
|
|
190
|
+
[Assistant](reference/glossary.md#assistant) writes it for you.
|
|
191
|
+
|
|
192
|
+
1. **You start a run.** You run `jr2 run feature`, with the ticket as the input of the run. The Machine starts in its
|
|
193
|
+
first state, `code`.
|
|
194
|
+
2. **The coder works in a Sandbox.** The state `code` is in a Workspace, so jr2 makes a Sandbox for it. The Sandbox
|
|
195
|
+
holds a [Worktree](reference/glossary.md#worktree) of your Repo, on the branch of the run. The coder edits the files,
|
|
196
|
+
runs the tests and commits. Then it picks `finish`, and the Machine moves to `review`.
|
|
197
|
+
3. **The reviewer gets a Turn.** The state `review` gives the reviewer a prompt and its Menu: `approved` and `changes`.
|
|
198
|
+
The reviewer reads the change in the same Sandbox.
|
|
199
|
+
4. **The reviewer picks.** If it picks `approved`, the Machine moves to `approval`. If it picks `changes`, the Machine
|
|
200
|
+
goes back to `code`, and the coder continues its work.
|
|
201
|
+
5. **The run waits for you.** In `approval`, a Gate holds the run until you answer. You approve the work, or you ask for
|
|
202
|
+
changes. You answer in the Console, with `jr2 send`, or from your own app.
|
|
203
|
+
6. **The run ends.** The Machine gets to `done`. The Workspace ends, and its Sandbox pod stops with it.
|
|
204
|
+
|
|
205
|
+
The [`task`](reference/machines.md#task) Machine in `@jr2/machines` is a smaller Machine of this kind: a coder in a
|
|
206
|
+
Sandbox, and a Gate that you answer. The [Get started](get-started/install.md) tutorial runs it.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jr2/orchestrator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "The jr2 Orchestrator: xstate runtime, HTTP API and Console, and the kit pieces a Workflow imports.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"type": "module",
|
|
31
31
|
"exports": {
|
|
32
32
|
".": "./src/index.ts",
|
|
33
|
+
"./internal": "./src/internal.ts",
|
|
33
34
|
"./tsconfig.instance.json": "./tsconfig.instance.json"
|
|
34
35
|
},
|
|
35
36
|
"types": "./src/index.ts",
|
|
@@ -41,20 +42,21 @@
|
|
|
41
42
|
"ts-blank-space": "^0.9.0",
|
|
42
43
|
"xstate": "^5.18.0",
|
|
43
44
|
"zod": "^4.4.3",
|
|
44
|
-
"@jr2/agent-protocol": "0.
|
|
45
|
+
"@jr2/agent-protocol": "0.5.1"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@types/node": "^26.0.1",
|
|
48
|
-
"@jr2/harness": "0.
|
|
49
|
+
"@jr2/harness": "0.5.1"
|
|
49
50
|
},
|
|
50
51
|
"files": [
|
|
51
52
|
"bin",
|
|
52
53
|
"console",
|
|
54
|
+
"docs",
|
|
53
55
|
"src",
|
|
54
56
|
"tsconfig.instance.json"
|
|
55
57
|
],
|
|
56
58
|
"scripts": {
|
|
57
59
|
"typecheck": "tsc --noEmit && tsc -p console --noEmit",
|
|
58
|
-
"test": "node --test"
|
|
60
|
+
"test": "node --test --test-global-setup=../../scripts/test-tmpdir.ts"
|
|
59
61
|
}
|
|
60
62
|
}
|