@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,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: file
|
|
3
|
+
description: "Make a Worktree file the body of an `http` Effect: `body: file(\"dist/report.pdf\")`."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `file`
|
|
7
|
+
|
|
8
|
+
Function, in `@jr2/orchestrator/src/http-effect.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Effects.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
function file<S extends z.ZodType | undefined = undefined>(path: FromInput<S, string>, options: {
|
|
12
|
+
slot?: string;
|
|
13
|
+
segments?: FromInput<S, readonly string[]>;
|
|
14
|
+
contentType?: string;
|
|
15
|
+
} = {}): FileBody<S>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Make a Worktree file the body of an `http` Effect: `body: file("dist/report.pdf")`. The Effect
|
|
19
|
+
then runs in the Sandbox Effector of the Workspace whose body invokes it. That Effector opens the
|
|
20
|
+
file in the Worktree and sends it. In a Workspace with no Repo Slot, the path is relative to
|
|
21
|
+
`/work`, the folder that its steps share. Use it with `PUT`, `POST` or `PATCH`. `path` and
|
|
22
|
+
`segments` can be functions of the input of the Effect.
|
|
23
|
+
|
|
24
|
+
Some paths and files give the output `refused`, and then nothing is sent. The path has a symlink
|
|
25
|
+
in it, has `..`, or is absolute. Or the file is a FIFO, a directory, or a file with more than one
|
|
26
|
+
link.
|
|
27
|
+
|
|
28
|
+
It refuses, when you call it:
|
|
29
|
+
- a path that is not a string or a function: `file(path): the path is a string, or a function of
|
|
30
|
+
the Effect's input that returns one`
|
|
31
|
+
|
|
32
|
+
And when `http` takes the definition:
|
|
33
|
+
- a method other than `PUT`, `POST` and `PATCH`: `http({ method: "<method>", body: file(...) }):
|
|
34
|
+
a file body is sent with PUT, POST, PATCH (ADR-0068)`
|
|
35
|
+
- a `request` beside it: ``http({ body: file(...), request }): with a file body the run's part
|
|
36
|
+
is file()'s — its path, from the input if it must be, and its `segments` — so write no
|
|
37
|
+
`request` (ADR-0068)``
|
|
38
|
+
- a `content-type` header and `contentType`: `http({ headers, body: file(path, { contentType })
|
|
39
|
+
}): "content-type" is set by file()'s contentType — write one of them (ADR-0067)`
|
|
40
|
+
|
|
41
|
+
And at `jr2 up`, an Effect that no `workspace()` invokes: `workflow "<workflow>": the http Effect
|
|
42
|
+
"<slot>" sends a Worktree file as its body, and no workspace() invokes it — outside a Workspace
|
|
43
|
+
there is no Worktree to read; invoke it from a workspace()'s body, or send a json or text body
|
|
44
|
+
(ADR-0068)`.
|
|
45
|
+
|
|
46
|
+
**Parameters**
|
|
47
|
+
|
|
48
|
+
- `path` ([`FromInput`](type-frominput.md)): The file, relative to the Worktree of the Repo Slot, or to `/work` in a Workspace
|
|
49
|
+
with no Repo Slot: a string, or a function of the input of the Effect that gives one.
|
|
50
|
+
- `options`: Optional. Each field says what it does.
|
|
51
|
+
|
|
52
|
+
- `slot` (optional): `string`
|
|
53
|
+
|
|
54
|
+
The Repo Slot whose Worktree holds the file. Write it only when the Workspace has more than
|
|
55
|
+
one.
|
|
56
|
+
- `segments` (optional): `FromInput<S, readonly string[]>`
|
|
57
|
+
|
|
58
|
+
Path segments that jr2 adds to the end of the url, as `path` does in `request` for a json or
|
|
59
|
+
text body. A list of strings, or a function of the input of the Effect that gives one.
|
|
60
|
+
- `contentType` (optional): `string`
|
|
61
|
+
|
|
62
|
+
The content type of the body. Default `application/octet-stream`. Do not write it beside a
|
|
63
|
+
`content-type` header.
|
|
64
|
+
|
|
65
|
+
**Returns**: The `body` of an `http` Effect.
|
|
66
|
+
|
|
67
|
+
**Example**
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import {
|
|
71
|
+
bearer,
|
|
72
|
+
command,
|
|
73
|
+
fail,
|
|
74
|
+
file,
|
|
75
|
+
http,
|
|
76
|
+
jr2Setup,
|
|
77
|
+
secret,
|
|
78
|
+
workspace,
|
|
79
|
+
type Workspaced,
|
|
80
|
+
} from "@jr2/orchestrator";
|
|
81
|
+
|
|
82
|
+
type Input = Workspaced<{}, "app">;
|
|
83
|
+
|
|
84
|
+
const body = jr2Setup({
|
|
85
|
+
types: {} as { context: Input; input: Input },
|
|
86
|
+
actors: {
|
|
87
|
+
build: command(["npm", "run", "report"]),
|
|
88
|
+
upload: http({
|
|
89
|
+
method: "PUT",
|
|
90
|
+
url: "https://files.example.com/reports",
|
|
91
|
+
auth: bearer(secret("files")),
|
|
92
|
+
body: file("dist/report.pdf", {
|
|
93
|
+
segments: ["report.pdf"],
|
|
94
|
+
contentType: "application/pdf",
|
|
95
|
+
}),
|
|
96
|
+
}),
|
|
97
|
+
fail: fail(),
|
|
98
|
+
},
|
|
99
|
+
}).createMachine({
|
|
100
|
+
id: "report",
|
|
101
|
+
context: ({ input }) => input,
|
|
102
|
+
on: { "workspace.lost": ".lost" },
|
|
103
|
+
initial: "building",
|
|
104
|
+
states: {
|
|
105
|
+
building: { invoke: { src: "build", onDone: "uploading" } },
|
|
106
|
+
uploading: { invoke: { src: "upload", onDone: "done" } },
|
|
107
|
+
done: { type: "final" },
|
|
108
|
+
lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export const machine = workspace(body, {
|
|
113
|
+
repos: { app: { url: "https://github.com/you/app.git" } },
|
|
114
|
+
spec: () => ({ branch: "report" }),
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**See also**
|
|
119
|
+
|
|
120
|
+
- [Run a command or call a URL with an Effect](../../guides/run-a-command-or-call-a-url.md)
|
|
121
|
+
- [Effects](../../concepts/effects.md)
|
|
122
|
+
- [ADR-0067: An Effect is an actor slot, and runs at most once unless marked idempotent](../decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md)
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: fromPick
|
|
3
|
+
description: "Make the `input` of the invoke of a state that a pick enters: the params of the pick go to the input of the invoked actor by name."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `fromPick`
|
|
7
|
+
|
|
8
|
+
Function, in `@jr2/orchestrator/src/pick.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Effects.
|
|
9
|
+
|
|
10
|
+
## Overload 1
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
function fromPick<
|
|
14
|
+
N extends string,
|
|
15
|
+
I extends z.ZodObject,
|
|
16
|
+
C,
|
|
17
|
+
E extends EventObject,
|
|
18
|
+
>(
|
|
19
|
+
def: EventDef<N, I>,
|
|
20
|
+
): (args: { context: C; event: E; self: AnyActorRef }) => z.infer<I>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Make the `input` of the invoke of a state that a pick enters: the params of the pick go to the
|
|
24
|
+
input of the invoked actor by name. With `fill`, the Machine adds the keys that the Agent must
|
|
25
|
+
not choose. So one expression shows the security boundary: the pick is what the Agent gives, and
|
|
26
|
+
`fill` is what the Machine adds.
|
|
27
|
+
|
|
28
|
+
TypeScript checks the params and the keys of `fill` together against the input type of the
|
|
29
|
+
invoked actor. It finds a missing key or a key of the wrong type, but it accepts an extra key.
|
|
30
|
+
|
|
31
|
+
So `createMachine` refuses:
|
|
32
|
+
- a param that is no key of the input of the Effect, and that nothing else reads: ``machine
|
|
33
|
+
"<id>": pick "<pick>" enters state "<state>" (Effect "<slot>") with fromPick: "<param>" is no
|
|
34
|
+
key of the Effect's input (<keys>), and nothing else reads it — the Agent supplies it and it
|
|
35
|
+
reaches nothing; name an argv slot for it, read it in `fill`, store it with assign, or drop it
|
|
36
|
+
from the def``
|
|
37
|
+
- a key that `fill` sets and that is also a param: ``machine "<id>": pick "<pick>" enters state
|
|
38
|
+
"<state>" (Effect "<slot>"): `fill` sets "<param>", which is also a param of the pick — the
|
|
39
|
+
Machine's value wins and the Agent's is dropped; rename one, or drop it from the def``
|
|
40
|
+
- a `fromPick` in a state that another event enters: `machine "<id>": state "<state>" (Effect
|
|
41
|
+
"<slot>") reads the params of pick "<pick>" but is entered on "<event>" — that event does not
|
|
42
|
+
carry them`
|
|
43
|
+
|
|
44
|
+
The input of an Open argv is one string for each key, so TypeScript checks no key for it. A key
|
|
45
|
+
that the bound argv names and the input does not give stops the Effect when it starts.
|
|
46
|
+
|
|
47
|
+
The state that the pick enters has one of two places:
|
|
48
|
+
- A child state of the Agent's state, as in the first example. The Turn stays open, and the
|
|
49
|
+
pick is outstanding until the Effect ends. Use this shape when the Agent must see the result.
|
|
50
|
+
The Agent reads the Effect's output as the answer only when the route after the Effect stays
|
|
51
|
+
in the Agent's state, as `onDone: "ready"` does. Then the Agent can pick again. A route that
|
|
52
|
+
leaves the Agent's state ends the Turn when the Effect ends, and no Agent reads the output.
|
|
53
|
+
- A sibling state of the Agent's state, as in the second example. The pick leaves the Agent's
|
|
54
|
+
state, so the Turn ends before the Effect runs, and the Agent does not see the output. Use
|
|
55
|
+
this shape for a pick that ends the work of the Agent.
|
|
56
|
+
|
|
57
|
+
**Parameters**
|
|
58
|
+
|
|
59
|
+
- `def` ([`EventDef`](type-eventdef.md)): The pick, as `defineEvent` made it.
|
|
60
|
+
|
|
61
|
+
**Returns**: An `input` mapper for the `invoke` of the state.
|
|
62
|
+
|
|
63
|
+
**Example**
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { z } from "zod";
|
|
67
|
+
import { agent, defineEvent, fail, fromPick, http, jr2Setup } from "@jr2/orchestrator";
|
|
68
|
+
|
|
69
|
+
const postNote = defineEvent({
|
|
70
|
+
name: "post_note",
|
|
71
|
+
description: "Post a note to the team channel.",
|
|
72
|
+
input: z.object({ text: z.string() }),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const finish = defineEvent({
|
|
76
|
+
name: "finish",
|
|
77
|
+
description: "The note is posted. This ends your work.",
|
|
78
|
+
input: z.object({}),
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export const machine = jr2Setup({
|
|
82
|
+
types: {} as { context: {}; input: {} },
|
|
83
|
+
events: [postNote, finish],
|
|
84
|
+
actors: {
|
|
85
|
+
writer: agent({
|
|
86
|
+
model: "anthropic/claude-haiku-5-5",
|
|
87
|
+
instructions: "You write one short note for the team.",
|
|
88
|
+
workspace: "none",
|
|
89
|
+
}),
|
|
90
|
+
note: http({
|
|
91
|
+
method: "POST",
|
|
92
|
+
url: "https://hooks.example.com/notes",
|
|
93
|
+
input: z.object({ text: z.string() }),
|
|
94
|
+
request: ({ text }) => ({ json: { text } }),
|
|
95
|
+
}),
|
|
96
|
+
fail: fail(),
|
|
97
|
+
},
|
|
98
|
+
}).createMachine({
|
|
99
|
+
id: "note",
|
|
100
|
+
on: { "agent.fault": ".failed" },
|
|
101
|
+
initial: "writing",
|
|
102
|
+
states: {
|
|
103
|
+
writing: {
|
|
104
|
+
invoke: {
|
|
105
|
+
src: "writer",
|
|
106
|
+
input: {
|
|
107
|
+
prompt: "Write a note that says the release is out, post it, and check the reply.",
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
initial: "ready",
|
|
111
|
+
states: {
|
|
112
|
+
ready: { on: { post_note: "posting", finish: "#done" } },
|
|
113
|
+
posting: {
|
|
114
|
+
// The `text` of the pick goes to the input of `note` as it is. The route goes back
|
|
115
|
+
// to `ready`, in `writing`: the writer reads the output and picks again.
|
|
116
|
+
invoke: { src: "note", input: fromPick(postNote), onDone: "ready" },
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
done: { id: "done", type: "final" },
|
|
121
|
+
failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Example**
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { z } from "zod";
|
|
130
|
+
import { agent, defineEvent, fail, fromPick, http, jr2Setup } from "@jr2/orchestrator";
|
|
131
|
+
|
|
132
|
+
const postNote = defineEvent({
|
|
133
|
+
name: "post_note",
|
|
134
|
+
description: "Post the note to the team channel. This ends your work.",
|
|
135
|
+
input: z.object({ text: z.string() }),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
export const machine = jr2Setup({
|
|
139
|
+
types: {} as { context: {}; input: {} },
|
|
140
|
+
events: [postNote],
|
|
141
|
+
actors: {
|
|
142
|
+
writer: agent({
|
|
143
|
+
model: "anthropic/claude-haiku-5-5",
|
|
144
|
+
instructions: "You write one short note for the team.",
|
|
145
|
+
workspace: "none",
|
|
146
|
+
}),
|
|
147
|
+
note: http({
|
|
148
|
+
method: "POST",
|
|
149
|
+
url: "https://hooks.example.com/notes",
|
|
150
|
+
input: z.object({ text: z.string() }),
|
|
151
|
+
request: ({ text }) => ({ json: { text } }),
|
|
152
|
+
}),
|
|
153
|
+
fail: fail(),
|
|
154
|
+
},
|
|
155
|
+
}).createMachine({
|
|
156
|
+
id: "note",
|
|
157
|
+
on: { "agent.fault": ".failed" },
|
|
158
|
+
initial: "writing",
|
|
159
|
+
states: {
|
|
160
|
+
// The pick leaves this state, so it ends the Turn of the writer.
|
|
161
|
+
writing: {
|
|
162
|
+
invoke: {
|
|
163
|
+
src: "writer",
|
|
164
|
+
input: { prompt: "Write a note that says the release is out, and post it." },
|
|
165
|
+
},
|
|
166
|
+
on: { post_note: "posting" },
|
|
167
|
+
},
|
|
168
|
+
// A sibling of `writing`: the Effect runs after the Turn, and no Agent reads its output.
|
|
169
|
+
posting: {
|
|
170
|
+
invoke: { src: "note", input: fromPick(postNote), onDone: "done" },
|
|
171
|
+
},
|
|
172
|
+
done: { type: "final" },
|
|
173
|
+
failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**See also**
|
|
179
|
+
|
|
180
|
+
- [Effects](../../concepts/effects.md)
|
|
181
|
+
- [Run a command or call a URL with an Effect](../../guides/run-a-command-or-call-a-url.md)
|
|
182
|
+
- [ADR-0067: An Effect is an actor slot, and runs at most once unless marked idempotent](../decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md)
|
|
183
|
+
|
|
184
|
+
## Overload 2
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
function fromPick<
|
|
188
|
+
N extends string,
|
|
189
|
+
I extends z.ZodObject,
|
|
190
|
+
C,
|
|
191
|
+
E extends EventObject,
|
|
192
|
+
R extends object,
|
|
193
|
+
>(
|
|
194
|
+
def: EventDef<N, I>,
|
|
195
|
+
fill: (args: { context: C; params: z.infer<I> }) => R,
|
|
196
|
+
): (args: { context: C; event: E; self: AnyActorRef }) => z.infer<I> & R
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Make the `input` from the params of the pick and the keys that `fill` adds. `fromPick`
|
|
200
|
+
tells the rest, and what `createMachine` refuses.
|
|
201
|
+
|
|
202
|
+
**Parameters**
|
|
203
|
+
|
|
204
|
+
- `def` ([`EventDef`](type-eventdef.md)): The pick, as `defineEvent` made it.
|
|
205
|
+
- `fill`: Gets `{ context, params }` and gives back only the keys that the Machine adds. Do
|
|
206
|
+
not set a key that is also a param.
|
|
207
|
+
|
|
208
|
+
**Returns**: An `input` mapper for the `invoke` of the state.
|
|
209
|
+
|
|
210
|
+
**Example**
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
import { z } from "zod";
|
|
214
|
+
import { agent, bearer, defineEvent, fail, fromPick, http, jr2Setup, secret } from "@jr2/orchestrator";
|
|
215
|
+
|
|
216
|
+
const postComment = defineEvent({
|
|
217
|
+
name: "post_comment",
|
|
218
|
+
description: "Post a comment on the ticket.",
|
|
219
|
+
input: z.object({ body: z.string() }),
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
export const machine = jr2Setup({
|
|
223
|
+
types: {} as { context: { ticket: string }; input: { ticket: string } },
|
|
224
|
+
events: [postComment],
|
|
225
|
+
actors: {
|
|
226
|
+
triager: agent({
|
|
227
|
+
model: "anthropic/claude-haiku-5-5",
|
|
228
|
+
instructions: "You triage tickets.",
|
|
229
|
+
workspace: "none",
|
|
230
|
+
}),
|
|
231
|
+
comment: http({
|
|
232
|
+
method: "POST",
|
|
233
|
+
url: "https://jira.example.com/rest/api/2/issue",
|
|
234
|
+
auth: bearer(secret("jira")),
|
|
235
|
+
input: z.object({ ticket: z.string(), body: z.string() }),
|
|
236
|
+
request: ({ ticket, body }) => ({ path: [ticket, "comment"], json: { body } }),
|
|
237
|
+
}),
|
|
238
|
+
fail: fail(),
|
|
239
|
+
},
|
|
240
|
+
}).createMachine({
|
|
241
|
+
id: "triage",
|
|
242
|
+
context: ({ input }) => input,
|
|
243
|
+
on: { "agent.fault": ".failed" },
|
|
244
|
+
initial: "triaging",
|
|
245
|
+
states: {
|
|
246
|
+
triaging: {
|
|
247
|
+
invoke: {
|
|
248
|
+
src: "triager",
|
|
249
|
+
input: ({ context }) => ({
|
|
250
|
+
prompt: `Read ticket ${context.ticket}, then post one comment on it.`,
|
|
251
|
+
}),
|
|
252
|
+
},
|
|
253
|
+
initial: "ready",
|
|
254
|
+
states: {
|
|
255
|
+
ready: { on: { post_comment: "posting" } },
|
|
256
|
+
posting: {
|
|
257
|
+
invoke: {
|
|
258
|
+
src: "comment",
|
|
259
|
+
// The Agent gives `body`. The Machine gives `ticket`, so the Agent cannot post on
|
|
260
|
+
// another ticket.
|
|
261
|
+
input: fromPick(postComment, ({ context }) => ({ ticket: context.ticket })),
|
|
262
|
+
onDone: "#done",
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
done: { id: "done", type: "final" },
|
|
268
|
+
failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**See also**
|
|
274
|
+
|
|
275
|
+
- [Effects](../../concepts/effects.md)
|
|
276
|
+
- [Run a command or call a URL with an Effect](../../guides/run-a-command-or-call-a-url.md)
|
|
277
|
+
- [ADR-0067: An Effect is an actor slot, and runs at most once unless marked idempotent](../decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: http
|
|
3
|
+
description: "Make an `http` Effect: a call to a URL, with Effect secrets that the Agent never reads."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `http`
|
|
7
|
+
|
|
8
|
+
Function, in `@jr2/orchestrator/src/http-effect.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Effects.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
function http<
|
|
12
|
+
S extends z.ZodType | undefined = undefined,
|
|
13
|
+
const U extends HttpDefinition<S>["url"] = string,
|
|
14
|
+
const A extends HttpDefinition<S>["auth"] = undefined,
|
|
15
|
+
const H extends HttpDefinition<S>["headers"] = undefined,
|
|
16
|
+
>(
|
|
17
|
+
def: HttpDefinition<S> & { url: U; auth?: A; headers?: H },
|
|
18
|
+
): EffectLogic<HttpInput<S>, HttpOutput> & OpenOf<HttpOpenParts<U, A, H>>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Make an `http` Effect: a call to a URL, with Effect secrets that the Agent never reads. Put it
|
|
22
|
+
in `actors`, and invoke it by its key: `actors: { comment: http({ ... }) }`, then `invoke: {
|
|
23
|
+
src: "comment" }`.
|
|
24
|
+
|
|
25
|
+
It runs in the Instance Effector, which `jr2 up` deploys when a Machine has an `http` Effect.
|
|
26
|
+
With `body: file(...)`, it runs in the Sandbox Effector of the Workspace whose body invokes it.
|
|
27
|
+
The Effector makes the call. The Orchestrator holds no secret.
|
|
28
|
+
|
|
29
|
+
Every outcome is output (`HttpOutput`): `response`, `unreachable`, `refused` or `unknown`. A 4xx
|
|
30
|
+
or 5xx status is output too. jr2 sends the call at most one time, unless you mark it
|
|
31
|
+
`idempotent`. When its state exits while the call runs, jr2 stops waiting for it. The Effector
|
|
32
|
+
can still send it.
|
|
33
|
+
|
|
34
|
+
Each field of [`HttpDefinition`](type-httpdefinition.md) tells what it refuses. `createMachine` also refuses an
|
|
35
|
+
Effect written directly in an `invoke`: `machine "<id>": state "<state>" invokes an Effect
|
|
36
|
+
inline — a Part is a key of actors, so it has a name that the ledger, the report and
|
|
37
|
+
customize() share: actors: { <name>: http(...) }, then invoke: { src: "<name>" }`.
|
|
38
|
+
|
|
39
|
+
**Parameters**
|
|
40
|
+
|
|
41
|
+
- `def`: The definition. Each field tells what it does.
|
|
42
|
+
|
|
43
|
+
- `method`: [`HttpMethod`](type-httpmethod.md)
|
|
44
|
+
|
|
45
|
+
The HTTP method: `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE` or `OPTIONS`. It refuses
|
|
46
|
+
another: `http({ method: "<method>" }): the method is one of GET, HEAD, POST, PUT, PATCH,
|
|
47
|
+
DELETE, OPTIONS`.
|
|
48
|
+
- `url`: `string | Text | typeof open`
|
|
49
|
+
|
|
50
|
+
The url: `http://` or `https://`, then a literal host. No input, param or Effect secret can
|
|
51
|
+
change where the call goes. An Effect secret can be only in the path:
|
|
52
|
+
`` text`https://api.telegram.org/bot${secret("tg")}/sendMessage` ``.
|
|
53
|
+
|
|
54
|
+
Or `open`: a packaged Machine that cannot know the host leaves the url Open, and the composer
|
|
55
|
+
binds it one time with `customize(machine, { effects: { <slot>: { url } } })`.
|
|
56
|
+
|
|
57
|
+
It refuses:
|
|
58
|
+
- a scheme or host that is not literal: `` http({ url }): the url is an http:// or https:// url
|
|
59
|
+
whose scheme and host are literal — a secret may sit only in its path, after a "/":
|
|
60
|
+
text`https://api.example.com/bot${secret("tg")}/send` (ADR-0068) ``
|
|
61
|
+
- an Effect secret after `?` or `#`: `` http({ url }): secret("<name>") sits in the url's query
|
|
62
|
+
or fragment — a secret may sit only in its path; send it in `auth` or a header instead:
|
|
63
|
+
headers: { "x-api-key": text`${secret("...")}` } (ADR-0068) ``
|
|
64
|
+
- a host that is not a host: `http({ url }): "<scheme>://<host>" is not a host`
|
|
65
|
+
- a user name or password in the url: ``http({ url }): the url carries userinfo — use `auth` ``
|
|
66
|
+
- `headers` (optional): `Readonly<Record<string, string | Text>>`
|
|
67
|
+
|
|
68
|
+
Headers that are the same for each run. Each name is lowercase. A value is a string, or a
|
|
69
|
+
`text` with an Effect secret.
|
|
70
|
+
|
|
71
|
+
It refuses:
|
|
72
|
+
- a name that is not lowercase, or that frames or routes the request (`host`,
|
|
73
|
+
`content-length`, `transfer-encoding`, `connection`, `upgrade`, `te`, `trailer`,
|
|
74
|
+
`keep-alive`, `proxy-*`): `http({ headers }): "<name>" is not a header an Effect sets — a
|
|
75
|
+
lowercase name that does not frame or route the request (ADR-0068)`
|
|
76
|
+
- an `authorization` header beside `auth`: ``http({ headers }): "authorization" is set by
|
|
77
|
+
`auth` — write one of them``
|
|
78
|
+
- `auth` (optional): `{ readonly bearer: Secret; } | { readonly basic: { user: Text; password: Text; }; } | Text`
|
|
79
|
+
|
|
80
|
+
The `Authorization` header: `bearer(secret("x"))`, `basic(user, password)`, or a `text` that
|
|
81
|
+
is the whole value.
|
|
82
|
+
- `input` (optional): `S`
|
|
83
|
+
|
|
84
|
+
The zod schema of the input of the Effect: what the `input` of the `invoke`, or `fromPick`,
|
|
85
|
+
gives it. jr2 parses the input with it before the call. When it starts, input that does not
|
|
86
|
+
agree with it makes the Effect fail (its `onError` route): `http "<slot>": its input does not
|
|
87
|
+
match the definition's input schema — <path>: <message>`, one `<path>: <message>` for each
|
|
88
|
+
problem, joined by `; `.
|
|
89
|
+
- `request` (optional): `(input: S extends z.ZodType ? z.infer<S> : void) => HttpRequestParts`
|
|
90
|
+
|
|
91
|
+
A function that makes the part of the request that changes for each run, from the input:
|
|
92
|
+
`path` segments, and a `json` or `text` body. It cannot change the host, a header or an
|
|
93
|
+
Effect secret. Do not write it beside `body`.
|
|
94
|
+
- `body` (optional): `FileBody<S>`
|
|
95
|
+
|
|
96
|
+
A Worktree file as the body: `file(path, { slot?, segments?, contentType? })`. The Effect then
|
|
97
|
+
runs in the Sandbox Effector of its Workspace. Do not write `request` beside it: the `segments`
|
|
98
|
+
of `file` are the path. It refuses another body: ``http({ body }): a body is file(path, {
|
|
99
|
+
slot?, segments?, contentType? }) — json and text come from `request` ``.
|
|
100
|
+
- `timeout` (optional): [`Duration`](type-duration.md)
|
|
101
|
+
|
|
102
|
+
How long jr2 waits for the answer: a number and a unit, such as `"30s"` or `"2m"`. Default
|
|
103
|
+
`"30s"`. With no answer in that time, the output is `unknown`. It refuses a value that is not
|
|
104
|
+
a positive duration: `http: timeout "<timeout>" is not a positive duration (like "30s",
|
|
105
|
+
"2m")`.
|
|
106
|
+
- `maxBody` (optional): `number`
|
|
107
|
+
|
|
108
|
+
The largest number of bytes of a text response body that the output keeps. Default 65536.
|
|
109
|
+
When jr2 cuts the body, `truncated` is `true`. It refuses a value that is not a positive whole
|
|
110
|
+
number: `http({ maxBody }): a positive number of bytes`.
|
|
111
|
+
- `idempotent` (optional): `boolean`
|
|
112
|
+
|
|
113
|
+
`true` when it is safe to send the call two times: it has its own idempotency key, or it only
|
|
114
|
+
reads. Default `false`. After an Orchestrator restart, jr2 cannot always tell if the call went
|
|
115
|
+
out. Then it sends an idempotent call again, and gives any other call the output `unknown`.
|
|
116
|
+
|
|
117
|
+
**Returns**: An Effect, for `actors`.
|
|
118
|
+
|
|
119
|
+
**Example**
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { z } from "zod";
|
|
123
|
+
import { bearer, http, jr2Setup, secret } from "@jr2/orchestrator";
|
|
124
|
+
|
|
125
|
+
const comment = http({
|
|
126
|
+
method: "POST",
|
|
127
|
+
url: "https://jira.example.com/rest/api/2/issue",
|
|
128
|
+
auth: bearer(secret("jira")),
|
|
129
|
+
input: z.object({ key: z.string(), body: z.string() }),
|
|
130
|
+
request: ({ key, body }) => ({ path: [key, "comment"], json: { body } }),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
export const machine = jr2Setup({
|
|
134
|
+
types: {} as { context: { key: string }; input: { key: string } },
|
|
135
|
+
actors: { comment },
|
|
136
|
+
}).createMachine({
|
|
137
|
+
id: "comment",
|
|
138
|
+
context: ({ input }) => input,
|
|
139
|
+
initial: "commenting",
|
|
140
|
+
states: {
|
|
141
|
+
commenting: {
|
|
142
|
+
invoke: {
|
|
143
|
+
src: "comment",
|
|
144
|
+
input: ({ context }) => ({ key: context.key, body: "The build passed." }),
|
|
145
|
+
onDone: "done",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
done: { type: "final" },
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**See also**
|
|
154
|
+
|
|
155
|
+
- [Effects](../../concepts/effects.md)
|
|
156
|
+
- [Run a command or call a URL with an Effect](../../guides/run-a-command-or-call-a-url.md)
|
|
157
|
+
- [Secrets and trust](../../concepts/secrets-and-trust.md)
|
|
158
|
+
- [ADR-0068: An Effector holds an Effect's secrets and signs its wire](../decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md)
|
|
159
|
+
- [ADR-0067: An Effect is an actor slot, and runs at most once unless marked idempotent](../decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: isFailure
|
|
3
|
+
description: Is this error a Failure, which a state invoked `fail` to make?
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `isFailure`
|
|
7
|
+
|
|
8
|
+
Function, in `@jr2/orchestrator/src/fail.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Failure.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
function isFailure(error: unknown): error is Failure
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Is this error a Failure, which a state invoked `fail` to make? A defect — any other error — is
|
|
15
|
+
not. Use it in the guard of an `onError` to catch a Failure and let a defect go up, and read the
|
|
16
|
+
Failure's `reason` and `detail` from the error it narrows.
|
|
17
|
+
|
|
18
|
+
**Parameters**
|
|
19
|
+
|
|
20
|
+
- `error`: The error of an error event: `event.error` in an `onError`.
|
|
21
|
+
|
|
22
|
+
**Returns**: True for a Failure, with `error` narrowed to `{ reason, detail? }`.
|
|
23
|
+
|
|
24
|
+
**Example**
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { z } from "zod";
|
|
28
|
+
import { defineEvent, fail, isFailure, jr2Setup } from "@jr2/orchestrator";
|
|
29
|
+
|
|
30
|
+
const retry = defineEvent({ name: "retry", description: "Try the plan again.", input: z.object({}) });
|
|
31
|
+
|
|
32
|
+
const attempt = jr2Setup({ actors: { fail: fail() } }).createMachine({
|
|
33
|
+
id: "attempt",
|
|
34
|
+
initial: "stuck",
|
|
35
|
+
states: { stuck: { invoke: { src: "fail", input: { reason: "no plan fits the ticket" } } } },
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const machine = jr2Setup({ events: [retry], actors: { attempt } }).createMachine({
|
|
39
|
+
id: "planner",
|
|
40
|
+
initial: "planning",
|
|
41
|
+
states: {
|
|
42
|
+
planning: {
|
|
43
|
+
invoke: {
|
|
44
|
+
src: "attempt",
|
|
45
|
+
onDone: "planned",
|
|
46
|
+
// A Failure waits for a person; a defect has no route, so it goes up and the run ends `error`.
|
|
47
|
+
onError: { guard: ({ event }) => isFailure(event.error), target: "asking" },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
asking: { invoke: { src: "gate" }, on: { retry: "planning" } },
|
|
51
|
+
planned: { type: "final" },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**See also**
|
|
57
|
+
|
|
58
|
+
- [ADR-0073: A Machine fails a run with `fail()`, and an uncaught Failure ends it `failed`](../decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md)
|