@jr2/orchestrator 0.6.0 → 0.7.0
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/console/components/app.ts +55 -15
- package/console/components/bottom-drawer.ts +259 -0
- package/console/components/drawer.ts +14 -6
- package/console/components/fleet.ts +36 -13
- package/console/components/machine-pane.ts +61 -5
- package/console/components/nav.ts +54 -8
- package/console/conversation.ts +161 -0
- package/console/login.ts +123 -0
- package/console/main.ts +600 -60
- package/console/store.ts +611 -64
- package/console/style.css +231 -0
- package/docs/agents-block.md +2 -2
- package/docs/concepts/agents-and-turns.md +86 -9
- package/docs/concepts/architecture.md +41 -28
- package/docs/concepts/callers-and-hooks.md +205 -0
- package/docs/concepts/charts.md +7 -5
- package/docs/concepts/composition.md +10 -1
- package/docs/concepts/converge.md +4 -2
- package/docs/concepts/durable-runs.md +43 -16
- package/docs/concepts/effects.md +50 -22
- package/docs/concepts/gates.md +95 -25
- package/docs/concepts/machines-and-workflows.md +5 -4
- package/docs/concepts/pools-and-sources.md +187 -11
- package/docs/concepts/secrets-and-trust.md +73 -33
- package/docs/concepts/the-menu.md +11 -0
- package/docs/concepts/workspaces.md +6 -5
- package/docs/get-started/a-model-decides.md +14 -13
- package/docs/get-started/an-agent-in-a-sandbox.md +43 -34
- package/docs/get-started/connect-a-model.md +1 -1
- package/docs/get-started/create-an-instance.md +17 -14
- package/docs/guides/add-tools-to-the-sandbox.md +55 -11
- package/docs/guides/answer-a-gate-from-a-forge.md +304 -0
- package/docs/guides/answer-a-gate.md +74 -37
- package/docs/guides/bind-open-parts.md +24 -8
- package/docs/guides/call-an-mcp-tool-from-a-machine.md +572 -0
- package/docs/guides/cancel-a-run.md +26 -16
- package/docs/guides/fix-a-failed-converge.md +18 -6
- package/docs/guides/give-a-caller-a-scope.md +203 -0
- package/docs/guides/give-an-agent-mcp-tools.md +422 -0
- package/docs/guides/iterate-on-a-machine-on-kind.md +10 -9
- package/docs/guides/let-an-agent-write-a-chart.md +9 -6
- package/docs/guides/look-inside-a-sandbox.md +101 -31
- package/docs/guides/open-the-console.md +63 -14
- package/docs/guides/read-a-conversation.md +225 -0
- package/docs/guides/run-a-chart-by-name.md +17 -16
- package/docs/guides/run-one-worker-per-item.md +15 -9
- package/docs/guides/set-an-agents-access-and-dials.md +2 -0
- package/docs/guides/start-a-run-for-each-alert.md +290 -0
- package/docs/guides/start-a-run-from-a-run.md +18 -16
- package/docs/guides/start-a-run.md +24 -18
- package/docs/guides/steer-an-agent.md +332 -0
- package/docs/guides/use-a-hosted-provider.md +1 -1
- package/docs/guides/watch-a-run.md +127 -121
- package/docs/guides/write-a-hook-kind.md +238 -0
- package/docs/guides/write-a-tool-as-an-mcp-server.md +351 -0
- package/docs/guides/write-a-workflow.md +17 -7
- package/docs/llms.txt +81 -15
- package/docs/reference/authoring-surface/agent.md +1 -1
- package/docs/reference/authoring-surface/answer.md +1 -1
- package/docs/reference/authoring-surface/arg.md +1 -1
- package/docs/reference/authoring-surface/basic.md +1 -1
- package/docs/reference/authoring-surface/bearer.md +1 -1
- package/docs/reference/authoring-surface/branchname.md +1 -1
- package/docs/reference/authoring-surface/carry.md +23 -0
- package/docs/reference/authoring-surface/chartschema.md +1 -1
- package/docs/reference/authoring-surface/chartschemafor.md +1 -1
- package/docs/reference/authoring-surface/command.md +1 -1
- package/docs/reference/authoring-surface/customize.md +4 -1
- package/docs/reference/authoring-surface/defineconfig.md +1 -1
- package/docs/reference/authoring-surface/defineevent.md +1 -1
- package/docs/reference/authoring-surface/dispatch.md +5 -4
- package/docs/reference/authoring-surface/fail.md +1 -1
- package/docs/reference/authoring-surface/file.md +1 -1
- package/docs/reference/authoring-surface/frompick.md +1 -1
- package/docs/reference/authoring-surface/gate.md +118 -0
- package/docs/reference/authoring-surface/group-agents.md +15 -0
- package/docs/reference/authoring-surface/group-charts.md +16 -0
- package/docs/reference/authoring-surface/group-composition.md +25 -0
- package/docs/reference/authoring-surface/group-config.md +17 -0
- package/docs/reference/authoring-surface/group-effects.md +48 -0
- package/docs/reference/authoring-surface/group-failure.md +13 -0
- package/docs/reference/authoring-surface/group-gates.md +16 -0
- package/docs/reference/authoring-surface/group-machine-and-events.md +15 -0
- package/docs/reference/authoring-surface/group-steering.md +12 -0
- package/docs/reference/authoring-surface/group-types-these-signatures-name.md +137 -0
- package/docs/reference/authoring-surface/group-workspaces-and-repos.md +15 -0
- package/docs/reference/authoring-surface/http.md +1 -1
- package/docs/reference/authoring-surface/isfailure.md +1 -1
- package/docs/reference/authoring-surface/isready.md +1 -1
- package/docs/reference/authoring-surface/jr2setup.md +13 -3
- package/docs/reference/authoring-surface/mcp.md +107 -0
- package/docs/reference/authoring-surface/open.md +5 -3
- package/docs/reference/authoring-surface/openbody.md +1 -1
- package/docs/reference/authoring-surface/paramsof.md +1 -1
- package/docs/reference/authoring-surface/pool.md +77 -9
- package/docs/reference/authoring-surface/push.md +1 -1
- package/docs/reference/authoring-surface/readyof.md +1 -1
- package/docs/reference/authoring-surface/reread.md +19 -0
- package/docs/reference/authoring-surface/secret.md +1 -1
- package/docs/reference/authoring-surface/sentby.md +1 -1
- package/docs/reference/authoring-surface/skip.md +22 -0
- package/docs/reference/authoring-surface/source.md +56 -1
- package/docs/reference/authoring-surface/steer.md +93 -0
- package/docs/reference/authoring-surface/text.md +1 -1
- package/docs/reference/authoring-surface/type-agentdefinition.md +14 -1
- package/docs/reference/authoring-surface/type-agentmcpserver.md +54 -0
- package/docs/reference/authoring-surface/type-anyframepath.md +1 -1
- package/docs/reference/authoring-surface/type-anyworktreepath.md +1 -1
- package/docs/reference/authoring-surface/type-binding.md +1 -1
- package/docs/reference/authoring-surface/type-caller.md +40 -0
- package/docs/reference/authoring-surface/type-callerrecord.md +32 -0
- package/docs/reference/authoring-surface/type-carry.md +19 -0
- package/docs/reference/authoring-surface/type-chainlink.md +3 -3
- package/docs/reference/authoring-surface/type-commandoutput.md +1 -1
- package/docs/reference/authoring-surface/type-customize.md +16 -1
- package/docs/reference/authoring-surface/type-delivered.md +17 -0
- package/docs/reference/authoring-surface/type-deliveredevent.md +18 -0
- package/docs/reference/authoring-surface/type-dispatchdefinition.md +4 -3
- package/docs/reference/authoring-surface/type-dispatchoutput.md +1 -1
- package/docs/reference/authoring-surface/type-effectbinding.md +12 -2
- package/docs/reference/authoring-surface/type-framepath.md +1 -1
- package/docs/reference/authoring-surface/type-gatebinding.md +15 -0
- package/docs/reference/authoring-surface/type-gatehooks.md +12 -0
- package/docs/reference/authoring-surface/type-gatelook.md +37 -0
- package/docs/reference/authoring-surface/type-gateoutcome.md +32 -0
- package/docs/reference/authoring-surface/type-gatereply.md +19 -0
- package/docs/reference/authoring-surface/type-gateslot.md +21 -0
- package/docs/reference/authoring-surface/type-gateslotinput.md +13 -0
- package/docs/reference/authoring-surface/type-gateslotparts.md +18 -0
- package/docs/reference/authoring-surface/type-gateslots.md +12 -0
- package/docs/reference/authoring-surface/type-gatetypesat.md +13 -0
- package/docs/reference/authoring-surface/type-hostinjectedinput.md +1 -1
- package/docs/reference/authoring-surface/type-httpoutput.md +1 -1
- package/docs/reference/authoring-surface/type-jr2config.md +37 -2
- package/docs/reference/authoring-surface/type-lateroutcome.md +1 -1
- package/docs/reference/authoring-surface/type-lends.md +5 -1
- package/docs/reference/authoring-surface/type-lookoutput.md +14 -0
- package/docs/reference/authoring-surface/type-mcpcalloutput.md +78 -0
- package/docs/reference/authoring-surface/type-mcpnotreturned.md +42 -0
- package/docs/reference/authoring-surface/type-mcpoptions.md +47 -0
- package/docs/reference/authoring-surface/type-mcpoutput.md +50 -0
- package/docs/reference/authoring-surface/type-mcpreadoutput.md +53 -0
- package/docs/reference/authoring-surface/type-mcpremoteserver.md +50 -0
- package/docs/reference/authoring-surface/type-mcpserver.md +41 -0
- package/docs/reference/authoring-surface/type-mcpstdioserver.md +42 -0
- package/docs/reference/authoring-surface/type-namedsecret.md +4 -4
- package/docs/reference/authoring-surface/type-openbodydeclaration.md +1 -1
- package/docs/reference/authoring-surface/type-openbodyoutput.md +1 -1
- package/docs/reference/authoring-surface/type-poolnextinput.md +1 -1
- package/docs/reference/authoring-surface/type-poolspec.md +11 -6
- package/docs/reference/authoring-surface/type-pushoutput.md +1 -1
- package/docs/reference/authoring-surface/type-pushsourcespec.md +38 -0
- package/docs/reference/authoring-surface/type-readsourcespec.md +47 -0
- package/docs/reference/authoring-surface/type-reposlot.md +1 -1
- package/docs/reference/authoring-surface/type-reread.md +18 -0
- package/docs/reference/authoring-surface/type-runsconfig.md +41 -0
- package/docs/reference/authoring-surface/type-sender.md +26 -1
- package/docs/reference/authoring-surface/type-sendercallerfield.md +14 -0
- package/docs/reference/authoring-surface/type-size.md +1 -1
- package/docs/reference/authoring-surface/type-skip.md +19 -0
- package/docs/reference/authoring-surface/type-sourcehooks.md +23 -0
- package/docs/reference/authoring-surface/type-sourcein.md +25 -0
- package/docs/reference/authoring-surface/type-sourcereply.md +18 -0
- package/docs/reference/authoring-surface/type-sourcespec.md +16 -7
- package/docs/reference/authoring-surface/type-sourceverdict.md +49 -0
- package/docs/reference/authoring-surface/type-standingpoolmachine.md +12 -0
- package/docs/reference/authoring-surface/type-standingpoolspec.md +51 -0
- package/docs/reference/authoring-surface/type-steerargs.md +20 -0
- package/docs/reference/authoring-surface/type-thinkinglevel.md +1 -1
- package/docs/reference/authoring-surface/type-usercontainer.md +1 -1
- package/docs/reference/authoring-surface/type-workspaced.md +1 -1
- package/docs/reference/authoring-surface/type-worktreefound.md +3 -3
- package/docs/reference/authoring-surface/type-worktreeinput.md +1 -1
- package/docs/reference/authoring-surface/type-worktreeoptions.md +1 -1
- package/docs/reference/authoring-surface/type-worktreeoutput.md +1 -1
- package/docs/reference/authoring-surface/type-worktreepath.md +1 -1
- package/docs/reference/authoring-surface/type-worktreeready.md +1 -1
- package/docs/reference/authoring-surface/type-worktreerefused.md +4 -4
- package/docs/reference/authoring-surface/workspace.md +1 -1
- package/docs/reference/authoring-surface/worktree.md +1 -1
- package/docs/reference/authoring-surface.md +88 -167
- package/docs/reference/cli.md +413 -74
- package/docs/reference/config.md +235 -2
- package/docs/reference/decisions/0002-duplex-streaming-actor.md +71 -11
- package/docs/reference/decisions/0005-sandbox-pod-composition.md +14 -10
- package/docs/reference/decisions/0006-agent-control-surface.md +4 -4
- package/docs/reference/decisions/0007-durable-machine-state.md +1 -1
- package/docs/reference/decisions/0009-cli-and-instance-interface.md +150 -49
- package/docs/reference/decisions/0010-bdd-acceptance-tests.md +5 -3
- package/docs/reference/decisions/0011-workflow-defined-events.md +256 -12
- package/docs/reference/decisions/0012-workspace-wrapper-machine.md +9 -2
- package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +20 -14
- package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +53 -27
- package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +18 -14
- package/docs/reference/decisions/0017-pool-over-a-source-port.md +226 -12
- package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +15 -7
- package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +32 -18
- package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +14 -1
- package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +4 -4
- package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +116 -34
- package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +38 -37
- package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +10 -5
- package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +7 -6
- package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +23 -7
- package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +18 -10
- package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +3 -2
- package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +23 -18
- package/docs/reference/decisions/0032-the-console-unlocks-with-a-callers-credential.md +101 -0
- package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +4 -3
- package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +6 -6
- package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +5 -4
- package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +19 -19
- package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +6 -1
- package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +55 -40
- package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +14 -13
- package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +7 -0
- package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +13 -7
- package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +38 -30
- package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +64 -17
- package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +2 -1
- package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +2 -2
- package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-kept-for-a-set-time.md +109 -0
- package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +51 -23
- package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +94 -54
- package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +101 -47
- package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +32 -9
- package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +17 -13
- package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +56 -30
- package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +35 -25
- package/docs/reference/decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md +4 -3
- package/docs/reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md +37 -10
- package/docs/reference/decisions/0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md +285 -0
- package/docs/reference/decisions/0079-an-agent-holds-mcp-tools-a-machine-calls-them-as-an-effect-and-the-machine-is-the-approval.md +198 -0
- package/docs/reference/decisions.md +6 -4
- package/docs/reference/glossary.md +96 -42
- package/docs/reference/hooks.md +1077 -0
- package/docs/reference/http-api.md +976 -149
- package/docs/why.md +2 -1
- package/package.json +10 -3
- package/src/actor.ts +36 -10
- package/src/agent.ts +50 -0
- package/src/assembly-checks.ts +530 -4
- package/src/callers.ts +245 -0
- package/src/chart.ts +52 -7
- package/src/config.ts +550 -1
- package/src/conversations.ts +453 -0
- package/src/custodian.ts +8 -2
- package/src/customize.ts +143 -4
- package/src/dispatch-effect.ts +142 -26
- package/src/durability.ts +2 -0
- package/src/duration.ts +20 -0
- package/src/effect-checks.ts +2 -1
- package/src/effect.ts +60 -7
- package/src/effector-wire.ts +272 -27
- package/src/gate-brand.ts +16 -0
- package/src/gate.ts +634 -48
- package/src/harness-client.ts +10 -4
- package/src/held-secrets.ts +72 -23
- package/src/holds.ts +2 -2
- package/src/hook-kinds/discord.ts +92 -0
- package/src/hook-kinds/door.ts +107 -0
- package/src/hook-kinds/github.ts +89 -0
- package/src/hook-kinds/gitlab.ts +72 -0
- package/src/hook-kinds/hook.ts +7 -0
- package/src/hook-kinds/index.ts +465 -0
- package/src/hook-kinds/slack.ts +151 -0
- package/src/hook-kinds/webhook.ts +113 -0
- package/src/hooks.ts +506 -0
- package/src/http-effect.ts +76 -38
- package/src/http.ts +889 -94
- package/src/index.ts +16 -5
- package/src/instance.ts +196 -26
- package/src/internal.ts +22 -3
- package/src/machine-doc.ts +26 -1
- package/src/mcp-effect.ts +424 -0
- package/src/mount-digest.ts +41 -7
- package/src/names.ts +64 -2
- package/src/notices.ts +138 -10
- package/src/open-body.ts +25 -11
- package/src/open-effect.ts +17 -4
- package/src/open.ts +4 -2
- package/src/parts.ts +87 -9
- package/src/party.ts +2 -1
- package/src/pick.ts +2 -2
- package/src/pool.ts +1142 -163
- package/src/registration.ts +203 -13
- package/src/run-host.ts +1509 -171
- package/src/run-list.ts +191 -0
- package/src/sandbox-kube.ts +53 -5
- package/src/secret-placement.ts +239 -33
- package/src/server.ts +53 -4
- package/src/setup.ts +72 -32
- package/src/snapshot-store.ts +565 -48
- package/src/steer.ts +111 -0
- package/src/stub-harness.ts +6 -2
- package/src/tokens.ts +263 -22
- package/src/wire.ts +17 -0
- package/src/workspace.ts +50 -6
- package/src/worktree.ts +3 -3
- package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +0 -61
- package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +0 -65
package/src/index.ts
CHANGED
|
@@ -17,20 +17,25 @@ export { jr2Setup } from "./setup.ts";
|
|
|
17
17
|
export { sentBy } from "./party.ts";
|
|
18
18
|
export type { HostInjectedInput } from "./vocabulary.ts";
|
|
19
19
|
|
|
20
|
+
// Gates: a Gate slot hears a Hook (ADR-0011).
|
|
21
|
+
export { gate } from "./gate.ts";
|
|
22
|
+
export type { Delivered, GateLook, GateOutcome, GateReply } from "./gate.ts";
|
|
23
|
+
|
|
20
24
|
// Failure: the Part a Machine invokes to fail its run, and the guard that tells a Failure from a
|
|
21
25
|
// defect in an `onError` (ADR-0073).
|
|
22
26
|
export { fail, isFailure } from "./fail.ts";
|
|
23
27
|
|
|
24
28
|
// Agents: an Agent slot and the definition it carries (ADR-0028, ADR-0049).
|
|
25
29
|
export { agent } from "./harness-client.ts";
|
|
26
|
-
export type { AgentDefinition, ThinkingLevel } from "./agent.ts";
|
|
30
|
+
export type { AgentDefinition, AgentMcpServer, ThinkingLevel } from "./agent.ts";
|
|
27
31
|
|
|
28
32
|
// Workspaces and Repos: a Sandbox and the Repo Slots it binds (ADR-0012, ADR-0051).
|
|
29
33
|
export { workspace } from "./workspace.ts";
|
|
30
34
|
export type { Workspaced } from "./workspace.ts";
|
|
31
35
|
export type { Binding, RepoSlot } from "./parts.ts";
|
|
32
36
|
|
|
33
|
-
// Effects: work a Machine does outside itself, as an actor slot (ADR-0067, ADR-0068, ADR-0071
|
|
37
|
+
// Effects: work a Machine does outside itself, as an actor slot (ADR-0067, ADR-0068, ADR-0071,
|
|
38
|
+
// ADR-0079),
|
|
34
39
|
// and what an author writes between a pick and that work.
|
|
35
40
|
export { arg } from "./effect.ts";
|
|
36
41
|
export type { CommandOutput, LaterOutcome } from "./effect.ts";
|
|
@@ -54,8 +59,14 @@ export type {
|
|
|
54
59
|
} from "./worktree.ts";
|
|
55
60
|
export { dispatch } from "./dispatch-effect.ts";
|
|
56
61
|
export type { DispatchOutput } from "./effect.ts";
|
|
62
|
+
export { mcp } from "./mcp-effect.ts";
|
|
63
|
+
export type { McpOptions } from "./mcp-effect.ts";
|
|
64
|
+
export type { McpCallOutput, McpOutput, McpReadOutput } from "./effector-wire.ts";
|
|
57
65
|
export { answer, fromPick, paramsOf } from "./pick.ts";
|
|
58
66
|
|
|
67
|
+
// Steering: the Machine's free text to one of its Agents, which the Agent hears once (ADR-0002).
|
|
68
|
+
export { steer } from "./steer.ts";
|
|
69
|
+
|
|
59
70
|
// Composition: a part left Open, a Machine's parts retuned, a Pool over a Source (ADR-0017,
|
|
60
71
|
// ADR-0049, ADR-0054, ADR-0060).
|
|
61
72
|
export { open } from "./parts.ts";
|
|
@@ -63,8 +74,8 @@ export { customize } from "./customize.ts";
|
|
|
63
74
|
export type { Customize } from "./customize.ts";
|
|
64
75
|
export type { EffectBinding } from "./open-effect.ts";
|
|
65
76
|
export type { Size, UserContainer } from "./size.ts";
|
|
66
|
-
export { pool, source } from "./pool.ts";
|
|
67
|
-
export type { PoolNextInput } from "./pool.ts";
|
|
77
|
+
export { carry, pool, reread, skip, source } from "./pool.ts";
|
|
78
|
+
export type { PoolNextInput, SourceReply, SourceVerdict } from "./pool.ts";
|
|
68
79
|
|
|
69
80
|
// Charts: the Open body a Chart wrapper places in `actors`, and the grammar a planner's pick
|
|
70
81
|
// declares, whole or narrowed to one wrapper (ADR-0070).
|
|
@@ -74,4 +85,4 @@ export { chartSchema, chartSchemaFor } from "./chart.ts";
|
|
|
74
85
|
|
|
75
86
|
// Config: `jr2.config.ts`, the deployment facts a Machine cannot carry (ADR-0050).
|
|
76
87
|
export { defineConfig } from "./config.ts";
|
|
77
|
-
export type { JR2Config } from "./config.ts";
|
|
88
|
+
export type { JR2Config, McpRemoteServer, McpServer, McpStdioServer, RunsConfig } from "./config.ts";
|
package/src/instance.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// 3. `restore()` in-flight runs from the store (reconcile against the live world — ADR-0007),
|
|
15
15
|
// each inside the Assembly its snapshot names (ADR-0069). With no current Assembly the live
|
|
16
16
|
// rows wait, untouched, and the first publish restores them. Then sweep finished runs older
|
|
17
|
-
// than
|
|
17
|
+
// than `runs.retain` and collect every Assembly no live row holds, and again every hour (ADR-0065,
|
|
18
18
|
// ADR-0069);
|
|
19
19
|
// 4. serve the hono HTTP surface (`createApp`) so the CLI / humans can push + control + observe.
|
|
20
20
|
//
|
|
@@ -26,7 +26,16 @@
|
|
|
26
26
|
|
|
27
27
|
import { mkdir, readdir, stat } from "node:fs/promises";
|
|
28
28
|
import type { JR2Config } from "./config.ts";
|
|
29
|
-
import { loadConfig } from "./config.ts";
|
|
29
|
+
import { loadConfig, retainMs, STATE_VOLUME_DEFAULT } from "./config.ts";
|
|
30
|
+
import { statSync } from "node:fs";
|
|
31
|
+
import {
|
|
32
|
+
bytesUnder,
|
|
33
|
+
ConversationStore,
|
|
34
|
+
deleteOrphanConversations,
|
|
35
|
+
fileSystemBytes,
|
|
36
|
+
guardSpace,
|
|
37
|
+
quantityBytes,
|
|
38
|
+
} from "./conversations.ts";
|
|
30
39
|
import {
|
|
31
40
|
assemblyDoor,
|
|
32
41
|
heldAssemblies,
|
|
@@ -62,16 +71,28 @@ import { RunHost } from "./run-host.ts";
|
|
|
62
71
|
import type { RunRecord, WorkflowDef } from "./run-host.ts";
|
|
63
72
|
import { SqliteSnapshotStore } from "./snapshot-store.ts";
|
|
64
73
|
import type { SnapshotStore } from "./snapshot-store.ts";
|
|
65
|
-
import {
|
|
74
|
+
import {
|
|
75
|
+
createAuthenticator,
|
|
76
|
+
effectorKey,
|
|
77
|
+
harnessToken,
|
|
78
|
+
loadSigningKey,
|
|
79
|
+
mintInstanceToken,
|
|
80
|
+
namedTokens,
|
|
81
|
+
} from "./tokens.ts";
|
|
66
82
|
import type { SandboxPort } from "./workspace.ts";
|
|
83
|
+
import { jwtAuthenticator } from "./callers.ts";
|
|
67
84
|
import type { EffectorPlacement, EffectorTarget } from "./http-effect.ts";
|
|
68
|
-
import { WORKFLOW_NAME } from "./effector-wire.ts";
|
|
85
|
+
import { WORKFLOW_NAME, createMacClient, nodeEffectorTransport, type HookMac } from "./effector-wire.ts";
|
|
86
|
+
import { createHookPost, hookDoor, type HookPost } from "./hooks.ts";
|
|
69
87
|
|
|
70
88
|
export type InstanceOptions = {
|
|
71
89
|
/** The instance folder: the state volume `.jr2/` (its `state.db` unless `store` is supplied, and
|
|
72
90
|
* its published Assemblies). Nothing else in it is read: the Workflows are the current
|
|
73
91
|
* Assembly's (ADR-0069). */
|
|
74
92
|
dir: string;
|
|
93
|
+
/** The size of the state volume claim, as `jr2 up` applied it (`JR2_STATE_VOLUME`, ADR-0065): the
|
|
94
|
+
* space guard measures against it. Absent (host-booted), the config's `runs.volume` or `5Gi`. */
|
|
95
|
+
stateVolume?: string;
|
|
75
96
|
/** Which Assembly to load (ADR-0069). Default: `resolveAssembly(dir)`. The entrypoint resolves
|
|
76
97
|
* it first, because it reads the config from the same root before it builds the ports. */
|
|
77
98
|
assembly?: ResolvedAssembly;
|
|
@@ -81,8 +102,8 @@ export type InstanceOptions = {
|
|
|
81
102
|
/** The image map, read when the door checks a publish (ADR-0069). Present only when deployed;
|
|
82
103
|
* absent, the door does not check `file:` image contexts. */
|
|
83
104
|
imageMap?: () => Promise<ImageRefs>;
|
|
84
|
-
/** The digests of the mounted ConfigMaps
|
|
85
|
-
* when deployed. */
|
|
105
|
+
/** The digests of the mounted ConfigMaps and of the loaded digests Secrets, which
|
|
106
|
+
* `GET /assembly` reports (ADR-0069, ADR-0078). Present only when deployed. */
|
|
86
107
|
mounts?: () => Promise<Record<string, string>>;
|
|
87
108
|
/** Called after a publish has landed and the Workflows swapped: the new current Assembly, its
|
|
88
109
|
* config and its Machines, which the entrypoint swaps into the ports (ADR-0069). Synchronous, so
|
|
@@ -110,6 +131,9 @@ export type InstanceOptions = {
|
|
|
110
131
|
hostname?: string;
|
|
111
132
|
/** Override the durable store. Default: sqlite at `<dir>/.jr2/state.db`. */
|
|
112
133
|
store?: SnapshotStore;
|
|
134
|
+
/** Override the kept conversations (ADR-0023). Default: sqlite at `<dir>/.jr2/conversations.db`,
|
|
135
|
+
* or in memory when `store` is supplied. The space guard watches only the default file. */
|
|
136
|
+
conversations?: ConversationStore;
|
|
113
137
|
/** Probe the live world before re-attaching on restore (ADR-0007). Default: always present. */
|
|
114
138
|
reconcile?: (run: RunRecord) => boolean | Promise<boolean>;
|
|
115
139
|
/** The Sandbox backend for `workspace()` workflows (ADR-0012). Composed by the caller — wired
|
|
@@ -148,6 +172,23 @@ export type InstanceOptions = {
|
|
|
148
172
|
* the instance's Secret and the entrypoint passes it here, so a pod restart keeps the credential
|
|
149
173
|
* the CLI reads from that Secret. Default: minted per boot. */
|
|
150
174
|
instanceToken?: string;
|
|
175
|
+
/** The digests of the named Caller tokens, by name (ADR-0078), read on each request. Deployed, the
|
|
176
|
+
* entrypoint reads them from the `jr2-caller-digests` mount. The current Assembly's config gives
|
|
177
|
+
* each name its scopes. Default: none, so only the Instance token is a Caller. */
|
|
178
|
+
callerDigests?: () => Readonly<Record<string, string>>;
|
|
179
|
+
/** The digests of the `token` Hooks' secrets, by secret name (ADR-0078), read on each delivery.
|
|
180
|
+
* Deployed, the entrypoint reads them from the `jr2-hook-digests` mount. Default: none, so a
|
|
181
|
+
* `token` Hook refuses each delivery. */
|
|
182
|
+
hookDigests?: () => Readonly<Record<string, string>>;
|
|
183
|
+
/** The `mac` check of a Hook's delivery (ADR-0068, ADR-0078). Default: over the Instance
|
|
184
|
+
* Effector's signed wire when `instanceEffector` is set, else none, so a `mac` Hook answers 503.
|
|
185
|
+
* A test injects its own. */
|
|
186
|
+
hookMac?: HookMac;
|
|
187
|
+
/** The follow-up post of a Hook kind's answer, such as the reply to a Slack click (ADR-0011,
|
|
188
|
+
* ADR-0068). Default: one `http` call over the Instance Effector's signed wire when
|
|
189
|
+
* `instanceEffector` is set, else none, so a follow-up fails and the hook log says so. A test
|
|
190
|
+
* injects its own. */
|
|
191
|
+
hookPost?: HookPost;
|
|
151
192
|
};
|
|
152
193
|
|
|
153
194
|
/** What one restore did with the runs it found persisted (ADR-0007, ADR-0030). */
|
|
@@ -210,13 +251,11 @@ export type RunningInstance = {
|
|
|
210
251
|
close: () => Promise<void>;
|
|
211
252
|
};
|
|
212
253
|
|
|
213
|
-
/**
|
|
214
|
-
*
|
|
215
|
-
* like the Sandbox idle timeout: jr2 is not the record of a run's results, and `jr2 status` on an
|
|
216
|
-
* old run is a debugging act. A week is the time a human has to read it.
|
|
217
|
-
*/
|
|
218
|
-
const RETAIN_MS = 7 * 24 * 60 * 60 * 1000;
|
|
254
|
+
/** How often the sweep looks (ADR-0065). How long an ended run's row lives is `runs.retain` of the
|
|
255
|
+
* current config (`retainMs`), read at each sweep, so a publish changes it. */
|
|
219
256
|
const SWEEP_EVERY_MS = 60 * 60 * 1000;
|
|
257
|
+
/** How often the space guard looks at the state volume between two sweeps (ADR-0065). */
|
|
258
|
+
const GUARD_EVERY_MS = 60 * 1000;
|
|
220
259
|
|
|
221
260
|
/** Boot an instance folder into a running orchestrator (discover → restore → serve). */
|
|
222
261
|
export async function startInstance(opts: InstanceOptions): Promise<RunningInstance> {
|
|
@@ -230,6 +269,14 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
230
269
|
}
|
|
231
270
|
await store.init();
|
|
232
271
|
|
|
272
|
+
// The kept conversations (ADR-0023): a second SQLite file beside `state.db` on the state volume.
|
|
273
|
+
// A test that supplies its store keeps them in memory, and no guard measures a volume for it.
|
|
274
|
+
const stateDir = join(opts.dir, ".jr2");
|
|
275
|
+
const onVolume = !opts.conversations && !opts.store;
|
|
276
|
+
const conversations =
|
|
277
|
+
opts.conversations ?? new ConversationStore(onVolume ? join(stateDir, "conversations.db") : ":memory:");
|
|
278
|
+
conversations.init();
|
|
279
|
+
|
|
233
280
|
// Resolved BEFORE the host, and the signing key with it: the host derives every Harness bearer
|
|
234
281
|
// from the key (ADR-0058) — admission, stream, abort, echo. The key is loaded from (or minted
|
|
235
282
|
// into) the instance folder, NOT generated per process: live Sandboxes outlive a restart, their
|
|
@@ -336,6 +383,9 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
336
383
|
// files, as its record lists them. `GET /assembly` answers these; the runtime Charts the host
|
|
337
384
|
// also registers are not part of an Assembly.
|
|
338
385
|
let currentWorkflows: string[] = [];
|
|
386
|
+
// The config of the current Assembly (ADR-0069), for what the HTTP surface reads per request: the
|
|
387
|
+
// named Callers' scopes and the `cors` origins (ADR-0078). A publish replaces it.
|
|
388
|
+
let currentConfig: JR2Config | undefined;
|
|
339
389
|
|
|
340
390
|
/** Swap the registry to `loaded` and make `next` current, in one synchronous step: nothing in it
|
|
341
391
|
* awaits, so no request sees half of one Assembly and half of another (ADR-0069). The named
|
|
@@ -370,6 +420,7 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
370
420
|
// by name. No current Assembly → no Workflows, and the process still serves (ADR-0048).
|
|
371
421
|
if (current) {
|
|
372
422
|
const booted = current;
|
|
423
|
+
currentConfig = await loadConfig(booted.root);
|
|
373
424
|
const loaded = await importAssembly(booted.hash, booted.root);
|
|
374
425
|
swap(loaded, await readChartFiles(booted.root, undefined, contextDirsOf(loaded)), booted);
|
|
375
426
|
} else {
|
|
@@ -431,6 +482,7 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
431
482
|
// Every named Chart is re-admitted against the new Assembly (ADR-0070): a runtime Chart
|
|
432
483
|
// that fails is marked unrunnable, kept on the volume, and named in the publish's answer.
|
|
433
484
|
unrunnable = swap(workflows, files, next);
|
|
485
|
+
currentConfig = config;
|
|
434
486
|
// The Machines the walk imported are this hash's, so a run restored inside it later
|
|
435
487
|
// (the next boot is a new process; this is for the same one) needs no second import.
|
|
436
488
|
imported.set(next.hash, Promise.resolve(workflows));
|
|
@@ -441,15 +493,20 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
441
493
|
// Assembly was published for the old Kit version drifts now, and that is final. The
|
|
442
494
|
// door's collection follows in the same publish, so it removes the Assemblies only those
|
|
443
495
|
// drifted rows named.
|
|
444
|
-
if (
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
496
|
+
if (host.restorePending) {
|
|
497
|
+
try {
|
|
498
|
+
const outcome = await host.restore();
|
|
499
|
+
opts.onRestore?.({ assembly: next.hash, ...outcome });
|
|
500
|
+
} catch (err) {
|
|
501
|
+
// Left pending: the next publish, or the next boot, tries again. The publish itself
|
|
502
|
+
// landed, so it is not refused for this.
|
|
503
|
+
console.error(`restore after publish failed: ${err instanceof Error ? err.message : err}`);
|
|
504
|
+
}
|
|
452
505
|
}
|
|
506
|
+
// The standing Workflows (ADR-0017), after the restore: a live run of the Assembly before
|
|
507
|
+
// is handed over, and a Workflow that this publish adds gets its first run. Not while a
|
|
508
|
+
// deferred restore is still pending: its rows may hold the live standing runs.
|
|
509
|
+
if (!host.restorePending) await host.keepStanding("publish");
|
|
453
510
|
},
|
|
454
511
|
};
|
|
455
512
|
},
|
|
@@ -475,10 +532,13 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
475
532
|
const restored: RestoreOutcome = current
|
|
476
533
|
? await host.restore()
|
|
477
534
|
: { reattached: [], lost: [], drifted: [], failed: [] };
|
|
535
|
+
// The standing Workflows (ADR-0017), after the restore, so a restored standing run is kept and not
|
|
536
|
+
// started a second time. With no current Assembly there is none: the first publish starts them.
|
|
537
|
+
if (current) await host.keepStanding("boot");
|
|
478
538
|
const waiting = current ? [] : (await store.live()).map((row) => row.runId);
|
|
479
539
|
|
|
480
540
|
// Right after restore, not before: restore reads live rows only, and a row it marks `lost` or
|
|
481
|
-
// `drifted` here is written now, so its
|
|
541
|
+
// `drifted` here is written now, so its `runs.retain` starts now (ADR-0065). After the rows, the
|
|
482
542
|
// Assemblies: restore decided which rows stay live, and so which Assemblies stay held (ADR-0069).
|
|
483
543
|
// A sweep deletes finished rows only, so it never takes a waiting run; and with the restore
|
|
484
544
|
// deferred, every live row is a root, and so is the pointer's target, so the boot collection
|
|
@@ -486,11 +546,72 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
486
546
|
// A sweep is housekeeping, never a reason to stay up — nor to fail a boot that has already
|
|
487
547
|
// resumed runs: a failed sweep or collection, at boot or on the hour, is logged, and the next
|
|
488
548
|
// hour tries again. The timer holds no process alive.
|
|
549
|
+
// With no current Assembly, no `runs.retain` is bound, so the rows are not swept: in the Kit bump
|
|
550
|
+
// window every boot has no current Assembly, and a sweep at the default would delete the history
|
|
551
|
+
// that a longer `runs.retain` keeps. The first sweep after the publish uses the published value.
|
|
552
|
+
// The collection still runs. The cutoff is never before the epoch, so a very long `runs.retain`
|
|
553
|
+
// keeps every row and does not fail the sweep.
|
|
554
|
+
// The space guard (ADR-0065). It measures the files on the volume against the smaller of the
|
|
555
|
+
// claim and what `statfs` says, because a hostPath class such as kind's reports the node's disk.
|
|
556
|
+
// The claim is `runs.volume`, or the default when the config sets none. The files other than the
|
|
557
|
+
// two databases (the Assemblies, the Charts) are measured at each sweep, and the databases at each
|
|
558
|
+
// look, so the guard can look every minute and walk the volume only every hour.
|
|
559
|
+
const dbFiles = ["state.db", "state.db-wal", "conversations.db", "conversations.db-wal"].map((f) =>
|
|
560
|
+
join(stateDir, f),
|
|
561
|
+
);
|
|
562
|
+
const dbBytes = (): number =>
|
|
563
|
+
dbFiles.reduce((sum, path) => {
|
|
564
|
+
try {
|
|
565
|
+
return sum + statSync(path).size;
|
|
566
|
+
} catch {
|
|
567
|
+
return sum;
|
|
568
|
+
}
|
|
569
|
+
}, 0);
|
|
570
|
+
let otherBytes = 0;
|
|
571
|
+
const measureOthers = () => {
|
|
572
|
+
otherBytes = Math.max(0, bytesUnder(stateDir) - dbBytes());
|
|
573
|
+
};
|
|
574
|
+
let guarding = false;
|
|
575
|
+
const guard = async (): Promise<void> => {
|
|
576
|
+
if (guarding) return;
|
|
577
|
+
guarding = true;
|
|
578
|
+
try {
|
|
579
|
+
await guardSpace({
|
|
580
|
+
conversations,
|
|
581
|
+
used: () => otherBytes + dbBytes(),
|
|
582
|
+
capacity: () =>
|
|
583
|
+
Math.min(
|
|
584
|
+
fileSystemBytes(stateDir),
|
|
585
|
+
quantityBytes(opts.stateVolume ?? currentConfig?.runs?.volume ?? STATE_VOLUME_DEFAULT) ??
|
|
586
|
+
Number.POSITIVE_INFINITY,
|
|
587
|
+
),
|
|
588
|
+
isLive: (runId) => host.runIsLive(runId),
|
|
589
|
+
onSwept: (runId) =>
|
|
590
|
+
console.log(
|
|
591
|
+
`space guard: the state volume is more than 80% full — deleted the kept conversations of run ${runId} (ADR-0065)`,
|
|
592
|
+
),
|
|
593
|
+
});
|
|
594
|
+
} catch (err) {
|
|
595
|
+
console.error(`space guard failed: ${err instanceof Error ? err.message : err}`);
|
|
596
|
+
} finally {
|
|
597
|
+
guarding = false;
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
// A run's kept conversations go with its row (ADR-0065), and then the space guard looks.
|
|
489
601
|
const sweep = async (): Promise<string[]> => {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
602
|
+
if (current) {
|
|
603
|
+
await store
|
|
604
|
+
.sweep(new Date(Math.max(0, Date.now() - retainMs(currentConfig?.runs))))
|
|
605
|
+
.then((swept) => conversations.deleteRuns(swept))
|
|
606
|
+
.then(() => deleteOrphanConversations(conversations, store))
|
|
607
|
+
.catch((err) => console.error(`sweep failed: ${err instanceof Error ? err.message : err}`));
|
|
608
|
+
}
|
|
609
|
+
const collected = await door.collect();
|
|
610
|
+
if (onVolume) {
|
|
611
|
+
measureOthers();
|
|
612
|
+
await guard();
|
|
613
|
+
}
|
|
614
|
+
return collected;
|
|
494
615
|
};
|
|
495
616
|
const collected = await sweep();
|
|
496
617
|
const onCollect =
|
|
@@ -506,18 +627,65 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
506
627
|
.catch((err) => console.error(`collection announce failed: ${err instanceof Error ? err.message : err}`));
|
|
507
628
|
}, SWEEP_EVERY_MS);
|
|
508
629
|
sweeper.unref();
|
|
630
|
+
// The guard looks every minute too: a conversation can grow fast between two sweeps.
|
|
631
|
+
const guarder = onVolume ? setInterval(() => void guard(), GUARD_EVERY_MS) : undefined;
|
|
632
|
+
guarder?.unref();
|
|
509
633
|
|
|
510
634
|
// 4. Serve, authenticated (ADR-0013) — the tokens and key resolved above.
|
|
511
|
-
|
|
635
|
+
// The named Callers (ADR-0078): the names and scopes of the current config, joined per request with
|
|
636
|
+
// the digests `jr2 up` gave, so a publish or a rotation applies with no restart.
|
|
637
|
+
const auth = createAuthenticator({
|
|
638
|
+
instanceToken,
|
|
639
|
+
signingKey,
|
|
640
|
+
publishToken,
|
|
641
|
+
namedTokens: () => namedTokens(currentConfig?.callers?.tokens, opts.callerDigests?.() ?? {}),
|
|
642
|
+
// The JWT issuers of the current config, read per request, so a publish changes them.
|
|
643
|
+
callers: [jwtAuthenticator(() => currentConfig?.callers?.issuers ?? [])],
|
|
644
|
+
});
|
|
645
|
+
// The Hook's door (ADR-0011, ADR-0078): the Hooks of the current config, read per delivery, so a
|
|
646
|
+
// publish changes them; none while no Assembly is current. A `mac` Hook is checked by the
|
|
647
|
+
// Instance Effector, which holds its secret (ADR-0068).
|
|
648
|
+
const hookMac =
|
|
649
|
+
opts.hookMac ??
|
|
650
|
+
(opts.instanceEffector
|
|
651
|
+
? createMacClient({
|
|
652
|
+
key: effectorKey(signingKey, "instance"),
|
|
653
|
+
transport: nodeEffectorTransport(opts.instanceEffector),
|
|
654
|
+
})
|
|
655
|
+
: undefined);
|
|
656
|
+
// The follow-up of an answer that a person reads goes out through the same Effector (ADR-0068).
|
|
657
|
+
const hookPost =
|
|
658
|
+
opts.hookPost ??
|
|
659
|
+
(opts.instanceEffector
|
|
660
|
+
? createHookPost({
|
|
661
|
+
key: effectorKey(signingKey, "instance"),
|
|
662
|
+
transport: nodeEffectorTransport(opts.instanceEffector),
|
|
663
|
+
})
|
|
664
|
+
: undefined);
|
|
665
|
+
const hooks = hookDoor({
|
|
666
|
+
host,
|
|
667
|
+
store,
|
|
668
|
+
hooks: () => (current ? (currentConfig?.hooks ?? {}) : undefined),
|
|
669
|
+
digests: () => opts.hookDigests?.() ?? {},
|
|
670
|
+
...(hookMac ? { mac: hookMac } : {}),
|
|
671
|
+
...(hookPost ? { post: hookPost } : {}),
|
|
672
|
+
});
|
|
512
673
|
// The Repos are read PER REQUEST, never snapshotted here: a cache the agent cloned minutes
|
|
513
674
|
// after boot must show as present the next time anyone asks (ADR-0048/0051).
|
|
514
675
|
const app = createApp(host, auth, {
|
|
515
676
|
charts,
|
|
677
|
+
conversations,
|
|
516
678
|
dataPlane: opts.dataPlane,
|
|
517
679
|
repos: opts.repos,
|
|
518
680
|
fetchRepo: opts.fetchRepo,
|
|
519
681
|
assembly: door,
|
|
520
682
|
...(opts.mounts ? { mounts: opts.mounts } : {}),
|
|
683
|
+
cors: () => currentConfig?.cors ?? [],
|
|
684
|
+
hooks,
|
|
685
|
+
consoleLogin: () =>
|
|
686
|
+
(currentConfig?.callers?.issuers ?? [])
|
|
687
|
+
.filter((i) => i.login === true)
|
|
688
|
+
.map((i) => ({ issuer: i.issuer, clientId: i.audience })),
|
|
521
689
|
});
|
|
522
690
|
const server = serve({ fetch: app.fetch, port: opts.port ?? 0, hostname });
|
|
523
691
|
const port = await new Promise<number>((resolve) => {
|
|
@@ -562,9 +730,11 @@ export async function startInstance(opts: InstanceOptions): Promise<RunningInsta
|
|
|
562
730
|
// From that call on, `/agents/*` answers 503 until the listener closes: the Turns are parked
|
|
563
731
|
// for the next boot's restore, not over, so no Harness may read a 404 here (ADR-0026).
|
|
564
732
|
clearInterval(sweeper);
|
|
733
|
+
if (guarder) clearInterval(guarder);
|
|
565
734
|
await host.close();
|
|
566
735
|
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
567
736
|
await store.close();
|
|
737
|
+
conversations.close();
|
|
568
738
|
},
|
|
569
739
|
};
|
|
570
740
|
}
|
package/src/internal.ts
CHANGED
|
@@ -18,10 +18,13 @@ export * from "./effect.ts";
|
|
|
18
18
|
export * from "./http-effect.ts";
|
|
19
19
|
export * from "./sandbox-effect.ts";
|
|
20
20
|
export * from "./dispatch-effect.ts";
|
|
21
|
+
export * from "./mcp-effect.ts";
|
|
21
22
|
export type { EffectBinding, OpenEffect, OpenEffectPart } from "./open-effect.ts";
|
|
22
23
|
export { openPartsText } from "./open-effect.ts";
|
|
23
24
|
export * from "./effector-wire.ts";
|
|
24
25
|
export * from "./pick.ts";
|
|
26
|
+
export * from "./steer.ts";
|
|
27
|
+
export * from "./notices.ts";
|
|
25
28
|
export * from "./chart.ts";
|
|
26
29
|
export * from "./open-body.ts";
|
|
27
30
|
export * from "./charts.ts";
|
|
@@ -36,11 +39,15 @@ export * from "./setup.ts";
|
|
|
36
39
|
export { sentBy } from "./party.ts";
|
|
37
40
|
export * from "./vocabulary.ts";
|
|
38
41
|
export * from "./tokens.ts";
|
|
42
|
+
// What a run records of its Callers (ADR-0078): the CLI's `jr2 status` walks `startedBy`.
|
|
43
|
+
export type { CallerRecord, GateAnswer, RunStarter } from "./callers.ts";
|
|
39
44
|
export * from "./durability.ts";
|
|
40
45
|
export * from "./snapshot-store.ts";
|
|
46
|
+
// The run listing of `GET /runs` (ADR-0009): the CLI reads its summary and its query words.
|
|
47
|
+
export * from "./run-list.ts";
|
|
41
48
|
export * from "./actor.ts";
|
|
42
|
-
// The `gate` actor: jr2Setup pre-registers it and a state invokes it as `src: "gate"
|
|
43
|
-
//
|
|
49
|
+
// The `gate` actor: jr2Setup pre-registers it and a state invokes it as `src: "gate"` (ADR-0015).
|
|
50
|
+
// The Authoring surface has `gate({ … })`, a Gate slot that hears a Hook (ADR-0011).
|
|
44
51
|
export * from "./gate.ts";
|
|
45
52
|
// The Failure's brand stays in fail.ts, and so does the logic that throws it: the kit makes a Failure
|
|
46
53
|
// only through `fail()` and `workspace()`, which imports that logic from fail.ts (ADR-0073).
|
|
@@ -74,7 +81,19 @@ export * from "./repos.ts";
|
|
|
74
81
|
export * from "./repo-fetch.ts";
|
|
75
82
|
// Type-only: what a workflow event delivery looks like (the registration TABLE stays internal
|
|
76
83
|
// even here — ADR-0011).
|
|
77
|
-
export type {
|
|
84
|
+
export type {
|
|
85
|
+
ChildErrorMarker,
|
|
86
|
+
DeliveredEvent,
|
|
87
|
+
GateMarker,
|
|
88
|
+
HookRefusedMarker,
|
|
89
|
+
PlacingMarker,
|
|
90
|
+
PoolMarker,
|
|
91
|
+
RunMarker,
|
|
92
|
+
SourceVerdictLine,
|
|
93
|
+
TurnMarker,
|
|
94
|
+
} from "./registration.ts";
|
|
95
|
+
export type { HookOutcome } from "./hooks.ts";
|
|
96
|
+
export type { HookLogLine } from "./snapshot-store.ts";
|
|
78
97
|
export * from "./machine-doc.ts";
|
|
79
98
|
export * from "./run-host.ts";
|
|
80
99
|
export * from "./http.ts";
|
package/src/machine-doc.ts
CHANGED
|
@@ -61,7 +61,19 @@ export type EffectDoc =
|
|
|
61
61
|
/** A dispatch (ADR-0071): the Workflow it starts a run of, whether it waits, and the other
|
|
62
62
|
* Orchestrator's origin (`<open>` while a package leaves it Open); no target is this Orchestrator.
|
|
63
63
|
* The token's secret is named on the parts, never here: the target is what a reader routes on. */
|
|
64
|
-
| { kind: "dispatch"; workflow: string; wait: boolean; target?: string; timeoutMs: number }
|
|
64
|
+
| { kind: "dispatch"; workflow: string; wait: boolean; target?: string; timeoutMs: number }
|
|
65
|
+
/** An mcp Effect (ADR-0079): what it asks of which server, by the server's name in the `mcp`
|
|
66
|
+
* block (`<open>` while a package leaves it Open), and the author's timeout, when it set one. */
|
|
67
|
+
| {
|
|
68
|
+
kind: "mcp";
|
|
69
|
+
op: "call" | "read" | "prompt";
|
|
70
|
+
server: string;
|
|
71
|
+
tool?: string;
|
|
72
|
+
uri?: string;
|
|
73
|
+
prompt?: string;
|
|
74
|
+
timeoutMs?: number;
|
|
75
|
+
idempotent: boolean;
|
|
76
|
+
};
|
|
65
77
|
|
|
66
78
|
/** One state of the Machine; `states` nests in document order. */
|
|
67
79
|
export type MachineStateDoc = {
|
|
@@ -422,6 +434,19 @@ function effectDoc(parts: EffectParts): EffectDoc {
|
|
|
422
434
|
timeoutMs,
|
|
423
435
|
};
|
|
424
436
|
}
|
|
437
|
+
if (parts.kind === "mcp") {
|
|
438
|
+
const { op, server, tool, uri, prompt, timeoutMs, idempotent } = parts;
|
|
439
|
+
return {
|
|
440
|
+
kind: "mcp",
|
|
441
|
+
op,
|
|
442
|
+
server: server === open ? "<open>" : server,
|
|
443
|
+
...(tool !== undefined ? { tool: tool === open ? "<open>" : tool } : {}),
|
|
444
|
+
...(uri !== undefined ? { uri } : {}),
|
|
445
|
+
...(prompt !== undefined ? { prompt } : {}),
|
|
446
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
447
|
+
idempotent,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
425
450
|
const { argv, timeoutMs, secrets, pin } = parts;
|
|
426
451
|
return {
|
|
427
452
|
kind: "command",
|