@nylorun/runtime 0.9.0-beta → 0.11.0-beta
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/CHANGELOG.md +81 -0
- package/README.md +110 -37
- package/dist/adapters/execution/restate.d.ts +130 -0
- package/dist/adapters/execution/restate.js +442 -0
- package/dist/adapters/media.d.ts +2 -2
- package/dist/adapters/media.js +2 -2
- package/dist/adapters/observe.d.ts +2 -1
- package/dist/adapters/observe.js +2 -3
- package/dist/adapters/sandbox/virtual.js +1 -1
- package/dist/adapters/streams/s2.d.ts +18 -0
- package/dist/adapters/streams/s2.js +361 -0
- package/dist/assets.d.ts +2 -2
- package/dist/assets.js +5 -3
- package/dist/core/executors.d.ts +15 -3
- package/dist/core/executors.js +40 -5
- package/dist/core/flow-host.d.ts +225 -0
- package/dist/core/flow-host.js +518 -0
- package/dist/core/limits.d.ts +40 -0
- package/dist/core/limits.js +76 -0
- package/dist/core/runtime.d.ts +5 -90
- package/dist/core/runtime.js +3 -1447
- package/dist/core/sandbox-routes.d.ts +40 -0
- package/dist/core/sandbox-routes.js +106 -0
- package/dist/core/turn-manifest.d.ts +50 -0
- package/dist/core/turn-manifest.js +66 -0
- package/dist/execution/memory.d.ts +54 -0
- package/dist/execution/memory.js +217 -0
- package/dist/execution/types.d.ts +125 -0
- package/dist/execution/types.js +52 -0
- package/dist/host/config-for.d.ts +17 -0
- package/dist/host/config-for.js +27 -0
- package/dist/host/config.d.ts +16 -0
- package/dist/host/create-host.d.ts +56 -0
- package/dist/host/create-host.js +420 -0
- package/dist/host/environment.d.ts +13 -0
- package/dist/host/environment.js +53 -0
- package/dist/host/execution.d.ts +61 -0
- package/dist/host/execution.js +69 -0
- package/dist/host/http.d.ts +39 -0
- package/dist/host/http.js +142 -0
- package/dist/host/index.d.ts +8 -0
- package/dist/host/index.js +7 -0
- package/dist/host/logger.d.ts +3 -0
- package/dist/host/logger.js +18 -0
- package/dist/host/main.d.ts +3 -0
- package/dist/host/main.js +201 -0
- package/dist/host/stack-config.d.ts +72 -0
- package/dist/host/stack-config.js +193 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +4 -2
- package/dist/infra/database.d.ts +16 -0
- package/dist/infra/database.js +31 -0
- package/dist/infra/execution.d.ts +39 -0
- package/dist/infra/execution.js +68 -0
- package/dist/infra/index.d.ts +42 -0
- package/dist/infra/index.js +56 -0
- package/dist/infra/readiness.d.ts +33 -0
- package/dist/infra/readiness.js +53 -0
- package/dist/infra/streams.d.ts +17 -0
- package/dist/infra/streams.js +33 -0
- package/dist/infra/workers.d.ts +39 -0
- package/dist/infra/workers.js +31 -0
- package/dist/mcp/connect.d.ts +1 -0
- package/dist/mcp/connect.js +2 -0
- package/dist/mcp/pool.d.ts +3 -1
- package/dist/mcp/pool.js +2 -1
- package/dist/mcp/stdio.d.ts +2 -0
- package/dist/mcp/stdio.js +3 -1
- package/dist/model/auth-store.d.ts +1 -1
- package/dist/model/auth-store.js +2 -2
- package/dist/model/models.d.ts +4 -0
- package/dist/model/models.js +22 -26
- package/dist/model/pi-model.d.ts +2 -2
- package/dist/model/pi-model.js +6 -6
- package/dist/model/settings.d.ts +5 -1
- package/dist/model/settings.js +6 -2
- package/dist/sandbox/manager.d.ts +26 -8
- package/dist/sandbox/manager.js +95 -47
- package/dist/sandbox/select.d.ts +5 -4
- package/dist/sandbox/select.js +18 -13
- package/dist/sandbox/share.d.ts +23 -0
- package/dist/sandbox/share.js +58 -0
- package/dist/sandbox/types.d.ts +2 -2
- package/dist/store/canonical.d.ts +5 -0
- package/dist/store/canonical.js +17 -0
- package/dist/store/cursor.d.ts +9 -0
- package/dist/store/cursor.js +18 -0
- package/dist/store/memory.d.ts +57 -0
- package/dist/store/memory.js +643 -0
- package/dist/store/ownership.d.ts +19 -0
- package/dist/store/ownership.js +33 -0
- package/dist/store/postgres/connect.d.ts +25 -0
- package/dist/store/postgres/connect.js +25 -0
- package/dist/store/postgres/locking.d.ts +16 -0
- package/dist/store/postgres/locking.js +22 -0
- package/dist/store/postgres/migrations/001_initial.d.ts +27 -0
- package/dist/store/postgres/migrations/001_initial.js +196 -0
- package/dist/store/postgres/migrations/index.d.ts +49 -0
- package/dist/store/postgres/migrations/index.js +75 -0
- package/dist/store/postgres/names.d.ts +11 -0
- package/dist/store/postgres/names.js +42 -0
- package/dist/store/postgres/store.d.ts +11 -0
- package/dist/store/postgres/store.js +790 -0
- package/dist/store/postgres/tenants.d.ts +90 -0
- package/dist/store/postgres/tenants.js +207 -0
- package/dist/store/types.d.ts +440 -0
- package/dist/store/types.js +10 -0
- package/dist/streams/basin.d.ts +23 -0
- package/dist/streams/basin.js +51 -0
- package/dist/streams/memory.d.ts +25 -0
- package/dist/streams/memory.js +124 -0
- package/dist/streams/relay.d.ts +37 -0
- package/dist/streams/relay.js +254 -0
- package/dist/streams/types.d.ts +115 -0
- package/dist/streams/types.js +86 -0
- package/dist/tenant/actions.d.ts +153 -0
- package/dist/tenant/actions.js +191 -0
- package/dist/tenant/advance.d.ts +15 -0
- package/dist/tenant/advance.js +439 -0
- package/dist/tenant/auth.d.ts +11 -0
- package/dist/tenant/auth.js +34 -0
- package/dist/tenant/commands.d.ts +3 -0
- package/dist/tenant/commands.js +384 -0
- package/dist/tenant/context.d.ts +140 -0
- package/dist/tenant/context.js +40 -0
- package/dist/tenant/effects.d.ts +20 -0
- package/dist/tenant/effects.js +539 -0
- package/dist/tenant/envelope.d.ts +7 -0
- package/dist/tenant/envelope.js +22 -0
- package/dist/tenant/ephemeral.d.ts +42 -0
- package/dist/tenant/ephemeral.js +224 -0
- package/dist/tenant/http.d.ts +32 -0
- package/dist/tenant/http.js +51 -0
- package/dist/tenant/live.d.ts +92 -0
- package/dist/tenant/live.js +290 -0
- package/dist/tenant/logger.d.ts +9 -0
- package/dist/tenant/logger.js +25 -0
- package/dist/tenant/model-setting.d.ts +16 -0
- package/dist/tenant/model-setting.js +12 -0
- package/dist/tenant/module.d.ts +38 -0
- package/dist/tenant/module.js +319 -0
- package/dist/tenant/paths.d.ts +28 -0
- package/dist/tenant/paths.js +91 -0
- package/dist/tenant/pool.d.ts +10 -0
- package/dist/tenant/pool.js +54 -0
- package/dist/tenant/principals.d.ts +13 -0
- package/dist/tenant/principals.js +37 -0
- package/dist/tenant/quarantine-error.d.ts +6 -0
- package/dist/tenant/quarantine-error.js +9 -0
- package/dist/tenant/quarantine.d.ts +27 -0
- package/dist/tenant/quarantine.js +72 -0
- package/dist/tenant/reset.d.ts +22 -0
- package/dist/tenant/reset.js +81 -0
- package/dist/tenant/routes-tenant.d.ts +12 -0
- package/dist/tenant/routes-tenant.js +126 -0
- package/dist/tenant/routes.d.ts +9 -0
- package/dist/tenant/routes.js +142 -0
- package/dist/tenant/runtime.d.ts +81 -0
- package/dist/tenant/runtime.js +298 -0
- package/dist/tenant/scheduler.d.ts +25 -0
- package/dist/tenant/scheduler.js +84 -0
- package/dist/tenant/session.d.ts +60 -0
- package/dist/tenant/session.js +94 -0
- package/dist/tenant/sessions.d.ts +34 -0
- package/dist/tenant/sessions.js +149 -0
- package/dist/tenant/status.d.ts +37 -0
- package/dist/tenant/status.js +130 -0
- package/dist/tenant/store-memory.d.ts +16 -0
- package/dist/tenant/store-memory.js +111 -0
- package/dist/tenant/store-pg.d.ts +15 -0
- package/dist/tenant/store-pg.js +140 -0
- package/dist/tenant/streams.d.ts +126 -0
- package/dist/tenant/streams.js +419 -0
- package/dist/tenant/sweep.d.ts +15 -0
- package/dist/tenant/sweep.js +122 -0
- package/dist/tenant/types.d.ts +205 -0
- package/dist/tenant/types.js +23 -0
- package/dist/tenant/worker.d.ts +84 -0
- package/dist/tenant/worker.js +189 -0
- package/dist/vault/kek.d.ts +5 -2
- package/dist/vault/kek.js +7 -10
- package/dist/vault/service.d.ts +37 -31
- package/dist/vault/service.js +439 -359
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +14 -11
- package/dist/adapters/sandbox/microsandbox.d.ts +0 -2
- package/dist/adapters/sandbox/microsandbox.js +0 -238
- package/dist/core/main.js +0 -35
- package/dist/core/store.d.ts +0 -30
- package/dist/core/store.js +0 -202
- /package/dist/{core/main.d.ts → host/config.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,86 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.11.0-beta
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bf1c2da: **`nylorun dev --ephemeral` runs on the Docker stack, with a Tenant-level fixture model (breaking beta).**
|
|
8
|
+
|
|
9
|
+
- `nylorun dev --ephemeral` creates a temporary Tenant through `@nylorun/admin` (no Project link written), seeds it from `.env` with the fixture model, opens Studio on it and runs the watcher; the Tenant is deleted with its active work cancelled when the watcher ends, Ctrl-C included. It needs a Runtime that advertises `tenant-fixture-model`.
|
|
10
|
+
- `PUT /v1/tenant/config/seed` accepts `fixtureModel: true`, stored as Tenant setting `model.fixture`: that Tenant's model calls use the Runtime's fixture model while other Tenants on the Host keep theirs. `HOST_PROTOCOL` advertises the new optional feature `tenant-fixture-model` (`OPTIONAL_HOST_FEATURES` in `@nylorun/core/compatibility`); clients do not require it.
|
|
11
|
+
- `startEphemeralRuntime()` keeps its signature but its Tenants live in memory instead of SQLite under the Host root; nothing survives `close()`.
|
|
12
|
+
- Closing a Tenant waits for running advances at most the advance grace period (30 s by default) and then abandons them; their lease lapses and the next advance takes over.
|
|
13
|
+
- A Worker stop, Tenant close or ended Restate attempt no longer fails or cancels the turn it interrupts: outcomes already returned are recorded, nothing is settled, and the next advance resumes the turn from its checkpoint. Only a user cancel settles `cancelled`; an advance deadline fails the turn with the deadline's message.
|
|
14
|
+
|
|
15
|
+
- bf1c2da: **The microsandbox backend is removed; the Runtime runs sandbox tools on the virtual backend only.** The optional `microsandbox` dependency is gone. `sandbox.backend` and `NYLORUN_SANDBOX` accept `auto` or `virtual`, and `auto` selects `virtual`. A Tenant that stored `microsandbox` reads it as `auto`. `nylorun doctor sandbox` and the `nylorun dev` banner report only the virtual shell.
|
|
16
|
+
- bf1c2da: **Tenants are Postgres schemas only; SQLite and the `nylorun-runtime` launcher are removed (breaking beta).**
|
|
17
|
+
|
|
18
|
+
- The Runtime runs on Postgres (the Session Store, one schema per Tenant), Restate (Durable Session Execution: one advance per session, fenced by an ownership epoch, and a per-Tenant sweep) and S2 (Durable Streams: every event is written to a Postgres outbox and relayed to the session's stream, which history and SSE read). `--role api|worker|all` selects the process role; `/ready` covers Postgres, Restate and S2.
|
|
19
|
+
- SQLite Tenants are not migrated. On first start the Runtime moves every `tenants/<id>/` directory that holds a `tenant.sqlite` to `trash/<id>-sqlite-<time>/` and logs `sqlite_tenant_moved_to_trash`; recreate those Tenants.
|
|
20
|
+
- `@nylorun/runtime` has no bin: the `nylorun-runtime` launcher and `host-state.json` are gone. The Runtime runs as the `ghcr.io/nylorun/runtime` image (`nylorun start`); its Host entry requires `NYLORUN_DATABASE_URL`.
|
|
21
|
+
- `openTenantRuntime(config, hooks)` requires the Tenant's opened `store` and `envelope`; `OpenTenantRuntime` receives them from the Tenant store. `HostStateFile` is no longer exported.
|
|
22
|
+
- `@nylorun/core`: `LAUNCHER_PROTOCOL` and the launcher error codes are removed; `QuarantineSchema` drops `locked`, `lockPath` and `lockPid`; `TenantStatusSchema.checks.sqlite` is now `checks.store`. `TenantStatusSchema` gains optional `execution` (stuck invocations) and `streams` (basin, outbox depth, relay lag); `HostAggregateSchema` gains optional `outboxDepth` and `relayLagMs`.
|
|
23
|
+
|
|
24
|
+
- bf1c2da: **Tenants can register a Studio principal.** `CreateTenantRequest` gains optional `studioCredentialHash` behind the new protocol feature `studio-principal`; the Runtime stores it as application principal `studio`, and idempotent create compares it too. `@nylorun/admin` exports `deriveStudioToken(adminKey, tenantId)` (HMAC-SHA256 over `nylorun/studio/v1`, NUL, Tenant id) and `createTenant` sends the hash of that key, so Studio can reach any Tenant's API with a key derived from the admin key. Clients require the new feature, so upgrade the Runtime with them.
|
|
25
|
+
- 1d84b3e: **Native Windows is no longer supported; Windows developers use WSL2.** Nylorun runs on macOS and Linux. On native Windows, `nylorun` and `npm create @nylorun/agent` stop with WSL2 guidance. Install Node 24 and Docker (Docker Desktop's WSL integration) inside your WSL distribution and keep projects in its Linux filesystem. The Windows-only process handling (`taskkill`, `.cmd` shims, `npm.cmd`) is removed. `nylorun doctor` reports WSL as `Linux (WSL: <distribution>)`.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- ba1b239: **`nylorun` sets up the local stack; `@nylorun/cli` becomes the Runtime client `nylo` (breaking beta).**
|
|
30
|
+
|
|
31
|
+
- New unscoped package **`nylorun`**: `npx nylorun up` sets up the Docker stack on the first run and starts it after that, from any directory; `npx nylorun down` stops it (volumes are kept). `up` and `down` are aliases of `start` and `stop`. It also owns `status`, `logs`, `studio`, `reset` and `doctor`, pins the Runtime and Studio images (`package.json` `nylorun.runtime` / `nylorun.studio`), depends on `@nylorun/core` only, and never creates Tenants.
|
|
32
|
+
- **`@nylorun/cli`** is the Runtime client with the command **`nylo`**: `nylo tenant create [name]` (creates the Tenant; in a project, writes the Project link and seeds the model provider and sandbox from `.env`), `nylo tenant current|list|use|status|reset|delete`, `nylo configure`, `nylo env` (was `nylorun status --env`) and `nylo doctor sandbox`. It no longer provides the `nylorun` command or the stack commands.
|
|
33
|
+
- **Removed:** `nylorun dev` and `nylorun dev --ephemeral`. Link once with `nylo tenant create`, then run the project's own `npm run dev`. Moved commands exit 2 and name their replacement.
|
|
34
|
+
- **Starter:** the generated project depends on `@nylorun/agents` only (no Nylorun devDependency); `dev` is `tsx watch --env-file-if-exists=.env src/main.ts`. `npm create @nylorun/agent` installs the project and prints the next steps (`npx nylorun up`, `npx @nylorun/cli tenant create`, `npm run dev`) instead of starting development; `--no-open` is accepted and ignored.
|
|
35
|
+
- `connectAgents` names those steps when it finds no Runtime connection. Runtime repair hints, model errors and core's sandbox message name `nylo` and `nylorun up`.
|
|
36
|
+
|
|
37
|
+
- 262bded: A Tenant's stream wiring no longer logs after it stops. A basin repair that failed after the Tenant closed could write to a Tenant log directory that was already removed and end the process with an unhandled rejection.
|
|
38
|
+
- Pin core to the tested release.
|
|
39
|
+
- Pin harness to the tested release.
|
|
40
|
+
- Updated dependencies [bf1c2da]
|
|
41
|
+
- Updated dependencies [ba1b239]
|
|
42
|
+
- Updated dependencies [bf1c2da]
|
|
43
|
+
- Updated dependencies [bf1c2da]
|
|
44
|
+
- Updated dependencies [bf1c2da]
|
|
45
|
+
- Updated dependencies
|
|
46
|
+
- @nylorun/core@0.6.0-beta
|
|
47
|
+
- @nylorun/harness@0.19.1-beta
|
|
48
|
+
|
|
49
|
+
## 0.10.0-beta
|
|
50
|
+
|
|
51
|
+
### Minor Changes
|
|
52
|
+
|
|
53
|
+
- c49efed: **Runtime Clients and Admin API (supporting packages).**
|
|
54
|
+
|
|
55
|
+
- **core:** `AdminStatusSchema`, Project-link schemas, `ERROR_CODES` (launcher codes include `platform_unsupported`, `launcher_failed`, `downgrade_refused`), `admin-status` feature, `newPrincipalId`, `compareVersions`.
|
|
56
|
+
- **runtime:** `/v1/admin/status` (alias `/v1/admin/host`), loopback/`Origin`/content-type checks; the launcher ships as this package's `nylorun-runtime` bin (source under `src/launcher/`, not in `exports`) and runs the Host on the Node it runs on.
|
|
57
|
+
- **studio:** `nylorun-studio` binary; connects via `resolveConnection`; waits for `dev`; never calls Admin API or writes `.nylorun/`.
|
|
58
|
+
|
|
59
|
+
**Prerequisites:** developers install Node 24+ and `@nylorun/runtime` (`npm install --global @nylorun/runtime`) themselves; no package downloads Node or the Runtime, and there are no per-platform Runtime packages. Launcher commands: `version`, `up`, `down`, `restart`, `run`, `status`, `logs` (launcher protocol 1).
|
|
60
|
+
|
|
61
|
+
- c49efed: **Breaking (pre-1.0 minor):** Replace a single SQLite Runtime per Project or home directory with a **Runtime Host** that serves isolated **Tenants**, selected by `Nylorun-Tenant` and negotiated with `Nylorun-Protocol` (protocol `2`, feature `runtime-tenants`). Vocabulary: Host root + Tenant + Project link.
|
|
62
|
+
|
|
63
|
+
- **core:** `PROTOCOL_VERSION = 2`, `HOST_PROTOCOL`, `TENANT_HEADER`, `PROTOCOL_HEADER`, `newTenantId` / `isTenantId`, `checkCompatibility`; health schema gains `hostId` + `protocol` (`service: "nylorun-runtime"`); Tenant/admin wire schemas; Tenant model routes under `/v1/tenant/*`.
|
|
64
|
+
- **runtime:** Host process + Tenant module; Tenant model routes under `/v1/tenant/*`; `startEphemeralRuntime` for tests/embeds; executors via `PUT /v1/executors`; sandbox prefix `nylorun-<tenant-id>-`.
|
|
65
|
+
- **agents:** `createClient({ url, key, tenant })`; Transport sends Tenant + protocol headers; `/health` compatibility cache; `IncompatibleRuntimeError` with upgrade remedies.
|
|
66
|
+
- **cli:** Host root lifecycle (`runtime up|down|status|logs|restart|run`); Project link (`.nylorun/link.json` + `credentials.json`); `tenant` commands; `runtime status --env` exports `NYLORUN_RUNTIME_URL`, `NYLORUN_SERVER_KEY`, `NYLORUN_TENANT`; removed Project/home SQLite selectors.
|
|
67
|
+
- **studio:** `startStudio({ …, tenant: { id, name } })`; proxy forwards Tenant + protocol headers; UI shows Tenant name/short id.
|
|
68
|
+
|
|
69
|
+
- fd9fd87: Add workflows: compose agents and `tool()` with `Chain`, `Switch`, `Parallel`, `Map`, and `Loop`. A workflow is a registered runnable (`kind: "workflow"`) with the same session API as an agent — `export const agents`, `saveAgent` (saves referenced agents first), `createSession`, `input` (`content` or `data`), `observe({ follow })`, `pending`, `approve`, `cancel`. Slots (`{ run, id?, input? }`) reshape data between nodes. The flow engine (`runFlowDurable`) returns effects only; `harness/src/loop/` and `runDurable` are unchanged.
|
|
70
|
+
|
|
71
|
+
HostEffect gains flow kinds `agent`, `tool` (node), `fn`, and `verify`, each with `path`, `key`, and `iterations`. The Runtime drives agent nodes through the public session contract (linked sessions, shared sandbox via `PutSession.sandbox`), offers `fn` / `verify` again on lease expiry, and routes executor Actions by `(workflowId, key)` with claim-scoped `ctx.sandbox`. Optional `message.manifest` is a turn-only variant of the session pin (turn manifests). Studio shows the manifest tree, live node status, and session links. Examples under `examples/agents/{chain,switch,parallel,map,loop,ship-feature}/`.
|
|
72
|
+
|
|
73
|
+
### Patch Changes
|
|
74
|
+
|
|
75
|
+
- Pin core to the tested release.
|
|
76
|
+
- Pin harness to the tested release.
|
|
77
|
+
- Updated dependencies [c49efed]
|
|
78
|
+
- Updated dependencies [c49efed]
|
|
79
|
+
- Updated dependencies [fd9fd87]
|
|
80
|
+
- Updated dependencies
|
|
81
|
+
- @nylorun/core@0.5.0-beta
|
|
82
|
+
- @nylorun/harness@0.19.0-beta
|
|
83
|
+
|
|
3
84
|
## 0.9.0-beta
|
|
4
85
|
|
|
5
86
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# @nylorun/runtime
|
|
2
2
|
|
|
3
|
-
The independent OSS
|
|
3
|
+
The independent OSS **Runtime Host** consumes `@nylorun/harness/run` and
|
|
4
|
+
`@nylorun/core/contracts`. Cloud installs published `@nylorun/harness` from npm
|
|
5
|
+
and does not import this package. Client authoring and sessions belong to
|
|
6
|
+
`@nylorun/agents`; Tenant lifecycle management belongs to `@nylorun/admin`.
|
|
7
|
+
Vocabulary: [src/CONTEXT.md](./src/CONTEXT.md).
|
|
4
8
|
|
|
5
9
|
Requires Node 24+. Build from the repository root:
|
|
6
10
|
|
|
@@ -9,43 +13,112 @@ npm install
|
|
|
9
13
|
npm run build --workspace @nylorun/core
|
|
10
14
|
npm run build --workspace @nylorun/harness
|
|
11
15
|
npm run build --workspace @nylorun/runtime
|
|
12
|
-
NYLORUN_SERVER_KEY='<separate-secret-at-least-16-characters>' npm start --workspace @nylorun/runtime
|
|
13
16
|
```
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
18
|
+
## Running the Runtime
|
|
19
|
+
|
|
20
|
+
The Runtime runs as the `ghcr.io/nylorun/runtime` image, next to Postgres,
|
|
21
|
+
Restate and S2: `nylorun start` runs that stack on a developer machine. The
|
|
22
|
+
package is a library with no bin; its Host entry is `@nylorun/runtime/server`
|
|
23
|
+
(`dist/host/main.js`), which requires `NYLORUN_DATABASE_URL`. For tests and
|
|
24
|
+
ephemeral embeds, use `startEphemeralRuntime()` from `@nylorun/runtime/core`.
|
|
25
|
+
See [MIGRATION.md](../MIGRATION.md).
|
|
26
|
+
|
|
27
|
+
No Tenant state lives only in the Runtime process. Each Tenant's data is the
|
|
28
|
+
Postgres schema `tenant_<id>` (the Session Store); Restate runs one advance of a session at a
|
|
29
|
+
time and holds the Tenant's sweep timer (Durable Session Execution); every
|
|
30
|
+
session's events are relayed from the schema's outbox to its own S2 stream,
|
|
31
|
+
which history and SSE read (Durable Streams). An API node serves the Tenant API,
|
|
32
|
+
Admin API and SSE, and a Worker runs advances; `--role api|worker|all` picks
|
|
33
|
+
them, and the local stack runs one process with `all`.
|
|
34
|
+
|
|
35
|
+
The container is configured by its environment, which the stack's Compose file
|
|
36
|
+
sets: `NYLORUN_DATABASE_URL` (required), `NYLORUN_RESTATE_INGRESS_URL`,
|
|
37
|
+
`NYLORUN_RESTATE_ADMIN_URL`, `NYLORUN_WORKER_URL` and
|
|
38
|
+
`NYLORUN_RESTATE_IDENTITY_KEY` (Restate), `NYLORUN_S2_ENDPOINT` and
|
|
39
|
+
`NYLORUN_S2_TOKEN`, and in container mode `NYLORUN_LISTEN_HOST`,
|
|
40
|
+
`NYLORUN_LISTEN_PORT`, `NYLORUN_ALLOWED_HOSTS` and `NYLORUN_PUBLIC_URL`.
|
|
41
|
+
|
|
42
|
+
The Host root is `NYLORUN_HOME` or `~/.nylorun` (bind-mounted at `/nylorun` in
|
|
43
|
+
the stack). What stays on the Host is under `tenants/<tenantId>/`.
|
|
44
|
+
|
|
45
|
+
## Layout
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
<host root>/
|
|
49
|
+
host.json # format 1: hostId, host, port, runtimeVersion, …
|
|
50
|
+
host-credentials.json # adminKey (0600)
|
|
51
|
+
stack/ # compose.yaml, .env (0600), Restate identity key
|
|
52
|
+
tenants/<tenantId>/ # vault-kek, plugin-data, logs, home, tmp, sandboxes
|
|
53
|
+
trash/ # SQLite Tenants from before the Postgres switch
|
|
31
54
|
```
|
|
32
55
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
## HTTP surface
|
|
57
|
+
|
|
58
|
+
| Route | Auth | Notes |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| `GET /health` | none | `service: "nylorun-runtime"`, `hostId`, protocol `{min,max,features}`, pid |
|
|
61
|
+
| `GET /ready` | none | Listener up, Tenants discovered, and Postgres, Restate and S2 answer (`checks`) |
|
|
62
|
+
| `GET /v1/admin/status` | admin key | `AdminStatusSchema`; alias `GET /v1/admin/host` |
|
|
63
|
+
| `/v1/admin/tenants*` | admin key | Create / list / get / delete Tenants |
|
|
64
|
+
| `POST /v1/admin/host/shutdown` | admin key | Host-private; not in `@nylorun/admin` |
|
|
65
|
+
| `/v1/*` Tenant routes | application or executor | Require `Nylorun-Tenant` + `Nylorun-Protocol` |
|
|
66
|
+
|
|
67
|
+
Every route checks `Host` first (`421 host_rejected`), rejects any `Origin`
|
|
68
|
+
(`403 origin_rejected`, no CORS headers), and rejects non-JSON bodies with
|
|
69
|
+
`415 unsupported_media_type`. Missing or unsupported protocol → `426` before
|
|
70
|
+
authentication. Unknown, quarantined or rejected Tenant credentials → opaque
|
|
71
|
+
`404` with identical body.
|
|
72
|
+
|
|
73
|
+
## Embedding and tests
|
|
74
|
+
|
|
75
|
+
Tests and ephemeral embeds use `startEphemeralRuntime()` from
|
|
76
|
+
`@nylorun/runtime/core`: private Host on port 0, temporary Host root, one Tenant,
|
|
77
|
+
returns `{ url, tenantId, applicationKey, adminKey, close() }`. It is not durable:
|
|
78
|
+
its Tenants live in memory and are gone after `close()`. The smoke checks'
|
|
79
|
+
temporary Tenants (`scripts/lib/temporary-tenant.mjs`) do not use it; they are
|
|
80
|
+
created on the Docker stack.
|
|
81
|
+
|
|
82
|
+
Register executors with `PUT /v1/executors` using the application principal
|
|
83
|
+
(application-mode `connectAgents` does this with derived tokens). Model gateway
|
|
84
|
+
and sandbox backend are Tenant configuration (vault / seed), not Host process
|
|
85
|
+
env.
|
|
86
|
+
|
|
87
|
+
## Session behaviour
|
|
88
|
+
|
|
89
|
+
The session-first `/v1` API is specified in
|
|
90
|
+
[HOST_CONTRACT.md](../harness/HOST_CONTRACT.md). Application tokens authorize
|
|
91
|
+
definition/session APIs; executor credentials authorize authenticated SSE
|
|
92
|
+
connect, action discovery, claims, renewal and results. Session observers cannot
|
|
93
|
+
claim actions.
|
|
94
|
+
|
|
95
|
+
Postgres transactions persist session checkpoints, command receipts, individual
|
|
96
|
+
effects/actions, waits and the event outbox — **per Tenant schema**; history is
|
|
97
|
+
read from Durable Streams (S2). An advance owns its session through a lease with
|
|
98
|
+
an epoch; a Worker that takes over after a crash marks in-flight effects
|
|
99
|
+
`uncertain`. Vault ciphertext needs that Tenant's own KEK.
|
|
100
|
+
|
|
101
|
+
Agents that declare `.use(sandbox())` get Runtime-executed sandbox tools. The
|
|
102
|
+
Tenant owns each sandbox; backend names are prefixed `nylorun-<tenant-id>-`.
|
|
103
|
+
|
|
104
|
+
## Local Project workflow
|
|
105
|
+
|
|
106
|
+
A project depends on `@nylorun/agents` only. `npx nylorun up` runs the local
|
|
107
|
+
stack (Docker); `npx @nylorun/cli tenant create` (`nylo`) creates the
|
|
108
|
+
project's Tenant and writes its Project link; the project's `npm run dev` runs
|
|
109
|
+
`src/main.ts` under `tsx watch`; `npx nylorun studio` opens Studio.
|
|
110
|
+
|
|
111
|
+
## Troubleshooting
|
|
112
|
+
|
|
113
|
+
| Symptom | What to do |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `kek-missing` | Restore `vault-kek` in the Tenant directory |
|
|
116
|
+
| `corrupt` / `migration-failed` / `envelope-invalid` / `open-failed` / `open-timeout` | Follow the `nylo tenant status` repair string |
|
|
117
|
+
| `schema-too-new` | Run a Runtime at least as new as the one that migrated the schema |
|
|
118
|
+
| `426 protocol_unsupported` | Upgrade clients or Host to a compatible set |
|
|
119
|
+
| `421 host_rejected` / `403 origin_rejected` | Call from a server process, not a browser; in a container, list the `Host` in `NYLORUN_ALLOWED_HOSTS` |
|
|
120
|
+
| `503` for a Tenant | Postgres or Restate is unreachable; `GET /ready` names which |
|
|
121
|
+
| Port in use | Change `NYLORUN_PORT` in `<Host root>/stack/.env` and run `nylorun up` |
|
|
122
|
+
| Logs | `nylorun logs runtime` |
|
|
123
|
+
|
|
124
|
+
Definitions have no `agent.run()`; applications use `@nylorun/agents`.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type DurableExecution, type StuckInvocation, type Wake, type WorkerHandlers } from "../../execution/types.js";
|
|
2
|
+
export interface RestateTimeouts {
|
|
3
|
+
/**
|
|
4
|
+
* How long an invocation may run without journal progress before Restate
|
|
5
|
+
* asks it to suspend. An advance makes no journal entries while it runs, so
|
|
6
|
+
* this must exceed the longest segment. Default one hour.
|
|
7
|
+
*/
|
|
8
|
+
inactivityMs?: number;
|
|
9
|
+
/** How long after the inactivity timeout Restate aborts the attempt. Default one hour. */
|
|
10
|
+
abortMs?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Retries of a handler that throws (an infrastructure error). After
|
|
14
|
+
* `maxAttempts` the invocation is paused, never killed, and shows up in
|
|
15
|
+
* `listStuckInvocations` until an operator resumes it.
|
|
16
|
+
*/
|
|
17
|
+
export interface RestateRetry {
|
|
18
|
+
/** Default 100. */
|
|
19
|
+
initialIntervalMs?: number;
|
|
20
|
+
/** Default 30000. */
|
|
21
|
+
maxIntervalMs?: number;
|
|
22
|
+
/** Default 2. */
|
|
23
|
+
exponentiationFactor?: number;
|
|
24
|
+
/** Attempts, including the first, before pausing. Default 70. */
|
|
25
|
+
maxAttempts?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface RestateExecutionOptions {
|
|
28
|
+
/** Restate ingress, e.g. `http://restate:8080`. */
|
|
29
|
+
ingressUrl: string;
|
|
30
|
+
/** Restate admin API, e.g. `http://restate:9070`. Needed by `start`. */
|
|
31
|
+
adminUrl: string;
|
|
32
|
+
/** Where `start` serves the Worker endpoint (HTTP/2 cleartext). */
|
|
33
|
+
workerListen?: {
|
|
34
|
+
host: string;
|
|
35
|
+
port: number;
|
|
36
|
+
};
|
|
37
|
+
/** The endpoint URL Restate calls, registered by `start`. */
|
|
38
|
+
workerAdvertisedUrl?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Prepended to every service name, so several Runtimes (or test runs) can
|
|
41
|
+
* share one Restate server without taking each other's invocations.
|
|
42
|
+
* Letters, digits and `_` only. Default "".
|
|
43
|
+
*/
|
|
44
|
+
servicePrefix?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Request identity public keys (`publickeyv1_...`). When given, the Worker
|
|
47
|
+
* endpoint accepts only requests signed by a Restate server holding the
|
|
48
|
+
* matching private key.
|
|
49
|
+
*/
|
|
50
|
+
identityKeys?: string[];
|
|
51
|
+
timeouts?: RestateTimeouts;
|
|
52
|
+
retry?: RestateRetry;
|
|
53
|
+
/** Delay between sweep passes of one Tenant. Default 5000. */
|
|
54
|
+
sweepIntervalMs?: number;
|
|
55
|
+
/**
|
|
56
|
+
* How long wakes with a `dedupeKey` are remembered. Default and minimum
|
|
57
|
+
* 24 hours (§12.3).
|
|
58
|
+
*/
|
|
59
|
+
dedupeRetentionMs?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Overwrite a deployment already registered at `workerAdvertisedUrl`, so a
|
|
62
|
+
* restarted Worker with changed code takes effect. Default true, which suits
|
|
63
|
+
* a stable URL on a developer machine. Rolling upgrades should advertise a
|
|
64
|
+
* versioned URL instead (§14.6).
|
|
65
|
+
*/
|
|
66
|
+
forceRegistration?: boolean;
|
|
67
|
+
/** How long `start` keeps retrying registration while Restate comes up. Default 60000. */
|
|
68
|
+
registrationTimeoutMs?: number;
|
|
69
|
+
/** Replaces the SDK's console logging. */
|
|
70
|
+
logger?: (level: string, message: string) => void;
|
|
71
|
+
}
|
|
72
|
+
/** A Restate invocation that needs an operator: paused, or retrying after failures. */
|
|
73
|
+
export type { StuckInvocation };
|
|
74
|
+
export declare function createRestateExecution(options: RestateExecutionOptions): RestateExecution;
|
|
75
|
+
export declare class RestateExecution implements DurableExecution {
|
|
76
|
+
private readonly options;
|
|
77
|
+
private handlers?;
|
|
78
|
+
private stopping;
|
|
79
|
+
private server?;
|
|
80
|
+
private readonly sessions;
|
|
81
|
+
private readonly controllers;
|
|
82
|
+
private readonly inflight;
|
|
83
|
+
private readonly names;
|
|
84
|
+
private readonly ingressUrl;
|
|
85
|
+
private readonly adminUrl;
|
|
86
|
+
private readonly sweepIntervalMs;
|
|
87
|
+
constructor(options: RestateExecutionOptions);
|
|
88
|
+
/** Service names this execution registers, for diagnostics and tests. */
|
|
89
|
+
get serviceNames(): {
|
|
90
|
+
session: string;
|
|
91
|
+
tenant: string;
|
|
92
|
+
timer: string;
|
|
93
|
+
};
|
|
94
|
+
wake(tenantId: string, sessionId: string, wake: Wake): Promise<void>;
|
|
95
|
+
timer(tenantId: string, key: string, at: Date): Promise<void>;
|
|
96
|
+
armSweep(tenantId: string): Promise<void>;
|
|
97
|
+
disarmSweep(tenantId: string): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Readiness: the admin API (`/health`), which `start` registers with, and the
|
|
100
|
+
* ingress (`/restate/health`), which every wake, timer and sweep goes
|
|
101
|
+
* through, both answer.
|
|
102
|
+
*/
|
|
103
|
+
probe(signal: AbortSignal): Promise<void>;
|
|
104
|
+
/** This Runtime's paused or backing-off invocations for `tenantId` (Tenant status). */
|
|
105
|
+
stuckInvocations(tenantId: string): Promise<StuckInvocation[]>;
|
|
106
|
+
start(handlers: WorkerHandlers): Promise<void>;
|
|
107
|
+
stop(): Promise<void>;
|
|
108
|
+
private definitions;
|
|
109
|
+
/** Runs `advance` with a signal aborted by `stop` or by the end of the Restate attempt. */
|
|
110
|
+
private runAdvance;
|
|
111
|
+
/** Runs a Worker handler so that `stop` waits for it. Refuses once stopping; Restate retries. */
|
|
112
|
+
private runTracked;
|
|
113
|
+
private staleSweepMs;
|
|
114
|
+
private serviceOptions;
|
|
115
|
+
/** One-way send through the ingress. Retries while the ingress is unreachable or overloaded. */
|
|
116
|
+
private send;
|
|
117
|
+
/** Registers the Worker endpoint with the admin API, retrying until Restate is up. */
|
|
118
|
+
private register;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Lists invocations of this Runtime's services that need an operator: paused
|
|
122
|
+
* after exhausting retries, or backing off after a failure. Reads Restate's
|
|
123
|
+
* SQL introspection (`POST /query` on the admin API).
|
|
124
|
+
*/
|
|
125
|
+
export declare function listStuckInvocations(options: {
|
|
126
|
+
adminUrl: string;
|
|
127
|
+
servicePrefix?: string;
|
|
128
|
+
tenantId?: string;
|
|
129
|
+
limit?: number;
|
|
130
|
+
}): Promise<StuckInvocation[]>;
|