@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,217 @@
|
|
|
1
|
+
// A dispatch's slot schema against its callee's door (ADR-0071): the comparison `jr2 up` and the
|
|
2
|
+
// publish door make before any run starts. A match is COMPATIBILITY, one direction: every field the
|
|
3
|
+
// door requires is one the slot's schema always sends, with a compatible type, values and bounds,
|
|
4
|
+
// and every field of the slot's schema is in the door, since a plain zod door strips the rest
|
|
5
|
+
// silently. Equality is not asked: a slot may narrow what the door takes, never widen it.
|
|
6
|
+
//
|
|
7
|
+
// It compares within the JSON Schema subset ADR-0070 names (`PAYLOAD_KEYWORDS`, chart.ts). A schema
|
|
8
|
+
// that uses anything outside it (`oneOf`, `$ref`, `pattern`, `format`) is "not compared", never
|
|
9
|
+
// guessed at: a guess that says "ok" hides the mismatch it was asked for, and one that says
|
|
10
|
+
// "mismatch" refuses a publish that would run.
|
|
11
|
+
//
|
|
12
|
+
// Pure, and over two JSON Schemas only: the slot's is `z.toJSONSchema(input, { io: "output" })`
|
|
13
|
+
// (what the driver sends, its defaults filled), the door's is what `GET /workflows/<name>` serves (run-host.ts `inputSchema`), so a foreign door
|
|
14
|
+
// at another Kit version is compared by the same rules as this Assembly's own.
|
|
15
|
+
|
|
16
|
+
import { doorSchemaFaults } from "./chart.ts";
|
|
17
|
+
|
|
18
|
+
/** The comparison's answer: compatible; the faults that make it not, each naming the field; or not
|
|
19
|
+
* compared, with why. */
|
|
20
|
+
export type DoorCompat = { ok: true } | { ok: false; faults: string[] } | { ok: "not-compared"; why: string };
|
|
21
|
+
|
|
22
|
+
type Schema = Record<string, unknown>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Is a slot's input schema compatible with a door (ADR-0071)? `door` null is a door that declares
|
|
26
|
+
* no input (a run of it starts with anything): every slot is compatible with it.
|
|
27
|
+
*/
|
|
28
|
+
export function doorCompat(slot: unknown, door: unknown): DoorCompat {
|
|
29
|
+
if (door === null) return { ok: true };
|
|
30
|
+
slot = withoutDefaults(slot);
|
|
31
|
+
door = withoutDefaults(door);
|
|
32
|
+
for (const [whose, schema] of [
|
|
33
|
+
["the slot's input schema", slot],
|
|
34
|
+
["the door", door],
|
|
35
|
+
] as const) {
|
|
36
|
+
const fault = doorSchemaFaults(schema)[0];
|
|
37
|
+
if (fault) {
|
|
38
|
+
const at = fault.path.length ? `${fault.path.map(String).join(".")}: ` : "";
|
|
39
|
+
return { ok: "not-compared", why: `${whose} is outside the subset jr2 compares — ${at}${fault.message}` };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const faults: string[] = [];
|
|
43
|
+
compareValue(slot as Schema, door as Schema, "", faults);
|
|
44
|
+
return faults.length ? { ok: false, faults } : { ok: true };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Compare two object schemas at `at` (a field path, "" at the root), one direction. */
|
|
48
|
+
function compareObject(slot: Schema, door: Schema, at: string, faults: string[]): void {
|
|
49
|
+
const slotProps = propsOf(slot);
|
|
50
|
+
const doorProps = propsOf(door);
|
|
51
|
+
const required = Array.isArray(door.required) ? (door.required as unknown[]).map(String) : [];
|
|
52
|
+
const sent = new Set(Array.isArray(slot.required) ? (slot.required as unknown[]).map(String) : []);
|
|
53
|
+
for (const field of required) {
|
|
54
|
+
if (slotProps[field] === undefined) {
|
|
55
|
+
faults.push(`the door requires "${join(at, field)}", which the slot's input schema does not have`);
|
|
56
|
+
} else if (!sent.has(field)) {
|
|
57
|
+
// The slot's schema is what the driver sends after its parse (`io: "output"`), so a
|
|
58
|
+
// defaulted field is required there: optional means a body may leave it out.
|
|
59
|
+
faults.push(`the door requires "${join(at, field)}", which the slot's input schema leaves optional`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Every field both have is compared, the door's required ones among them.
|
|
63
|
+
const extra = door.additionalProperties;
|
|
64
|
+
for (const [field, sub] of Object.entries(slotProps)) {
|
|
65
|
+
const name = join(at, field);
|
|
66
|
+
const theirs = doorProps[field];
|
|
67
|
+
if (theirs !== undefined) {
|
|
68
|
+
compareValue(sub, theirs, name, faults);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
// A door that takes any field (`additionalProperties: {}` or `true`) keeps the slot's extra one;
|
|
72
|
+
// a catchall door (`additionalProperties: <schema>`) keeps it when its value fits.
|
|
73
|
+
if (isOpen(extra)) continue;
|
|
74
|
+
if (isSchema(extra)) {
|
|
75
|
+
compareValue(sub, extra, name, faults);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
faults.push(
|
|
79
|
+
extra === false
|
|
80
|
+
? `the slot's field "${name}" is not in the door, which refuses it`
|
|
81
|
+
: `the slot's field "${name}" is not in the door, which strips it silently`,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Compare one field's schemas: the type, the values an `enum` or a `const` allows, the bounds,
|
|
87
|
+
* then `items` and nested `properties`, by the same rules. A door node that states none of these
|
|
88
|
+
* takes any value (`z.unknown()`, `z.any()`), and every slot is compatible with it. */
|
|
89
|
+
function compareValue(slot: Schema, door: Schema, at: string, faults: string[]): void {
|
|
90
|
+
const theirs = typesOf(door);
|
|
91
|
+
const ours = typesOf(slot);
|
|
92
|
+
if (theirs !== undefined) {
|
|
93
|
+
if (ours === undefined) {
|
|
94
|
+
faults.push(`${label(at)}: the door takes ${theirs.join(" or ")}, and the slot's input schema takes any value`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const outside = ours.filter((t) => !theirs.includes(t) && !(t === "integer" && theirs.includes("number")));
|
|
98
|
+
if (outside.length) {
|
|
99
|
+
faults.push(`${label(at)}: the slot sends ${ours.join(" or ")}, and the door takes ${theirs.join(" or ")}`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const allowed = valuesOf(door);
|
|
104
|
+
const sent = valuesOf(slot);
|
|
105
|
+
if (allowed !== undefined) {
|
|
106
|
+
const list = allowed.map((v) => JSON.stringify(v)).join(", ");
|
|
107
|
+
if (sent === undefined) {
|
|
108
|
+
faults.push(`${label(at)}: the door takes only ${list}, and the slot's input schema does not narrow to them`);
|
|
109
|
+
} else {
|
|
110
|
+
const extra = sent.filter((v) => !allowed.some((a) => same(a, v)));
|
|
111
|
+
if (extra.length) {
|
|
112
|
+
faults.push(
|
|
113
|
+
`${label(at)}: the slot may send ${extra.map((v) => JSON.stringify(v)).join(", ")}, which the door does ` +
|
|
114
|
+
`not take (it takes ${list})`,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
compareBounds(slot, door, at, faults);
|
|
120
|
+
const may = (type: string): boolean => ours === undefined || ours.includes(type);
|
|
121
|
+
if (isSchema(door.items) && !isOpen(door.items) && may("array")) {
|
|
122
|
+
compareValue(isSchema(slot.items) ? slot.items : {}, door.items, `${at}[]`, faults);
|
|
123
|
+
}
|
|
124
|
+
const objectDoor =
|
|
125
|
+
isSchema(door.properties) || (theirs?.includes("object") ?? false) || door.additionalProperties !== undefined;
|
|
126
|
+
if (objectDoor && may("object")) compareObject(slot, door, at, faults);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** The bounds, one direction: the slot's range lies inside the door's, so a bound the door sets
|
|
130
|
+
* and the slot does not is a fault, as is a slot bound wider than the door's. */
|
|
131
|
+
function compareBounds(slot: Schema, door: Schema, at: string, faults: string[]): void {
|
|
132
|
+
const pairs: Array<[string, string | undefined, "lower" | "upper"]> = [
|
|
133
|
+
["minimum", "exclusiveMinimum", "lower"],
|
|
134
|
+
["maximum", "exclusiveMaximum", "upper"],
|
|
135
|
+
["minLength", undefined, "lower"],
|
|
136
|
+
["maxLength", undefined, "upper"],
|
|
137
|
+
["minItems", undefined, "lower"],
|
|
138
|
+
["maxItems", undefined, "upper"],
|
|
139
|
+
];
|
|
140
|
+
for (const [inclusive, exclusive, side] of pairs) {
|
|
141
|
+
const theirs = boundOf(door, inclusive, exclusive);
|
|
142
|
+
if (theirs === undefined) continue;
|
|
143
|
+
const ours = boundOf(slot, inclusive, exclusive);
|
|
144
|
+
const fits =
|
|
145
|
+
ours !== undefined &&
|
|
146
|
+
(side === "lower"
|
|
147
|
+
? ours.value > theirs.value || (ours.value === theirs.value && (ours.exclusive || !theirs.exclusive))
|
|
148
|
+
: ours.value < theirs.value || (ours.value === theirs.value && (ours.exclusive || !theirs.exclusive)));
|
|
149
|
+
if (fits) continue;
|
|
150
|
+
faults.push(
|
|
151
|
+
`${label(at)}: the door takes ${theirs.keyword} ${theirs.value}, and the slot's input schema ` +
|
|
152
|
+
(ours === undefined ? "sets no such bound" : `allows ${ours.keyword} ${ours.value}`),
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
type Bound = { value: number; exclusive: boolean; keyword: string };
|
|
158
|
+
|
|
159
|
+
/** A schema's bound on one side: the tighter of its inclusive and exclusive keyword, if any. */
|
|
160
|
+
function boundOf(schema: Schema, inclusive: string, exclusive: string | undefined): Bound | undefined {
|
|
161
|
+
const inc = typeof schema[inclusive] === "number" ? (schema[inclusive] as number) : undefined;
|
|
162
|
+
const exc =
|
|
163
|
+
exclusive !== undefined && typeof schema[exclusive] === "number" ? (schema[exclusive] as number) : undefined;
|
|
164
|
+
if (inc === undefined && exc === undefined) return undefined;
|
|
165
|
+
if (exc === undefined) return { value: inc!, exclusive: false, keyword: inclusive };
|
|
166
|
+
if (inc === undefined) return { value: exc, exclusive: true, keyword: exclusive! };
|
|
167
|
+
const lowerSide = inclusive.startsWith("min");
|
|
168
|
+
const excTighter = lowerSide ? exc >= inc : exc <= inc;
|
|
169
|
+
return excTighter
|
|
170
|
+
? { value: exc, exclusive: true, keyword: exclusive! }
|
|
171
|
+
: { value: inc, exclusive: false, keyword: inclusive };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function propsOf(schema: Schema): Record<string, Schema> {
|
|
175
|
+
const props = schema.properties;
|
|
176
|
+
if (!isSchema(props)) return {};
|
|
177
|
+
return Object.fromEntries(Object.entries(props).filter(([, v]) => isSchema(v))) as Record<string, Schema>;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** A schema's types, as a list; undefined when it states none (any value). */
|
|
181
|
+
function typesOf(schema: Schema): string[] | undefined {
|
|
182
|
+
const t = schema.type;
|
|
183
|
+
if (typeof t === "string") return [t];
|
|
184
|
+
if (Array.isArray(t)) return t.map(String);
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** The values a schema allows by `enum` or `const`; undefined when it lists none. */
|
|
189
|
+
function valuesOf(schema: Schema): unknown[] | undefined {
|
|
190
|
+
if (Array.isArray(schema.enum)) return schema.enum as unknown[];
|
|
191
|
+
if (Object.hasOwn(schema, "const")) return [schema.const];
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The schema without its `default`s, at every depth. A default is an annotation: it changes no
|
|
197
|
+
* value a schema takes (a defaulted field is already optional in `io: "input"`), so leaving it out
|
|
198
|
+
* guesses nothing, and a door with a defaulted field — common — is compared, not skipped.
|
|
199
|
+
*/
|
|
200
|
+
function withoutDefaults(schema: unknown): unknown {
|
|
201
|
+
if (!isSchema(schema)) return schema;
|
|
202
|
+
const { default: _default, ...rest } = schema;
|
|
203
|
+
const out: Schema = { ...rest };
|
|
204
|
+
// Schema nodes only: a field NAMED "default" under `properties` stays.
|
|
205
|
+
if (isSchema(rest.properties)) {
|
|
206
|
+
out.properties = Object.fromEntries(Object.entries(rest.properties).map(([k, v]) => [k, withoutDefaults(v)]));
|
|
207
|
+
}
|
|
208
|
+
if (rest.items !== undefined) out.items = withoutDefaults(rest.items);
|
|
209
|
+
if (rest.additionalProperties !== undefined) out.additionalProperties = withoutDefaults(rest.additionalProperties);
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const isSchema = (v: unknown): v is Schema => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
214
|
+
const isOpen = (v: unknown): boolean => v === true || (isSchema(v) && Object.keys(v).length === 0);
|
|
215
|
+
const same = (a: unknown, b: unknown): boolean => JSON.stringify(a) === JSON.stringify(b);
|
|
216
|
+
const join = (at: string, field: string): string => (at ? `${at}.${field}` : field);
|
|
217
|
+
const label = (at: string): string => (at ? `"${at}"` : "the body");
|
package/src/durability.ts
CHANGED
|
@@ -84,13 +84,13 @@ export function hydrateSnapshot(
|
|
|
84
84
|
* twin of `AgentAdmission` — kept import-free so this codec module stays a pure leaf.
|
|
85
85
|
* `instanceId` is the actor's live-conversation stamp (a runaway reroll advances it past the
|
|
86
86
|
* ledger key — ADR-0035); it rides the rewrite verbatim so the restored actor re-addresses the
|
|
87
|
-
* live conversation. */
|
|
88
|
-
type Admission = { streamUrl: string; offset: string; submissionId: string; instanceId?: string };
|
|
87
|
+
* live conversation. `turnId` is the Turn that ledgered it (see `reattachAgentRuns`). */
|
|
88
|
+
type Admission = { streamUrl: string; offset: string; submissionId: string; instanceId?: string; turnId?: string };
|
|
89
89
|
|
|
90
90
|
/** A persisted Agent child input: `instanceId` (the durable handle) beside `agentName` —
|
|
91
91
|
* both strings by construction (machine children carry neither at top level; `endpoint` can no
|
|
92
92
|
* longer identify it, being ambient-optional since ADR-0016). */
|
|
93
|
-
function isAgentRunInput(input: unknown): input is { instanceId: string; agentName: string } {
|
|
93
|
+
function isAgentRunInput(input: unknown): input is { instanceId: string; agentName: string; turnId?: string } {
|
|
94
94
|
return (
|
|
95
95
|
!!input &&
|
|
96
96
|
typeof input === "object" &&
|
|
@@ -107,6 +107,12 @@ function isAgentRunInput(input: unknown): input is { instanceId: string; agentNa
|
|
|
107
107
|
* context leg). An instanceId with no recorded admission re-admits its prompt — a run that
|
|
108
108
|
* crashed before its admission was ledgered is the same first-turn at-most-once edge as before
|
|
109
109
|
* (ADR-0007), narrowed to the send→record window.
|
|
110
|
+
*
|
|
111
|
+
* The key is not the Turn: two Turns that continue one conversation share the iid, and nothing
|
|
112
|
+
* removes a Turn's entry when it ends. So an admission re-attaches only the Turn that ledgered it —
|
|
113
|
+
* its `turnId` equals the input's. A crash after the next Turn's state was saved, and before its
|
|
114
|
+
* admission was ledgered, finds the earlier Turn's admission under the key; that Turn is not this
|
|
115
|
+
* one, so the input keeps its prompt and the restore admits it.
|
|
110
116
|
*/
|
|
111
117
|
export function reattachAgentRuns(snapshot: unknown, admissions: Record<string, Admission>): unknown {
|
|
112
118
|
const walk = (node: unknown): unknown => {
|
|
@@ -114,7 +120,8 @@ export function reattachAgentRuns(snapshot: unknown, admissions: Record<string,
|
|
|
114
120
|
const src = node as AnySnapshot & { input?: unknown };
|
|
115
121
|
const out: typeof src = { ...src };
|
|
116
122
|
|
|
117
|
-
const
|
|
123
|
+
const ledgered = isAgentRunInput(src.input) ? admissions[src.input.instanceId] : undefined;
|
|
124
|
+
const admission = isAgentRunInput(src.input) && ledgered?.turnId === src.input.turnId ? ledgered : undefined;
|
|
118
125
|
if (isAgentRunInput(src.input) && admission !== undefined) {
|
|
119
126
|
out.input = { ...src.input, prompt: undefined, attach: admission };
|
|
120
127
|
}
|