@nylorun/runtime 0.17.0-beta → 0.19.1-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.
Files changed (223) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/README.md +89 -58
  3. package/dist/adapters/execution/restate.d.ts +1 -3
  4. package/dist/adapters/execution/restate.js +4 -31
  5. package/dist/adapters/replication/pgoutput.js +1 -1
  6. package/dist/adapters/sandbox/local.js +1 -1
  7. package/dist/adapters/sandbox/virtual.js +1 -1
  8. package/dist/api/ag-ui/routes.js +1 -1
  9. package/dist/api/ag-ui/translate.d.ts +1 -3
  10. package/dist/api/ag-ui/translate.js +2 -17
  11. package/dist/api/components.d.ts +4871 -2614
  12. package/dist/api/components.js +12 -11
  13. package/dist/api/gate/routes.d.ts +7 -8
  14. package/dist/api/gate/routes.js +58 -52
  15. package/dist/api/http/app.d.ts +6 -0
  16. package/dist/api/http/app.js +18 -14
  17. package/dist/api/http/define.d.ts +14 -2
  18. package/dist/api/http/define.js +34 -15
  19. package/dist/api/http/routes/access.d.ts +3 -3
  20. package/dist/api/http/routes/access.js +18 -17
  21. package/dist/api/http/routes/artifacts.js +2 -4
  22. package/dist/api/http/routes/files.d.ts +8 -0
  23. package/dist/api/http/routes/files.js +77 -0
  24. package/dist/api/http/routes/keys.d.ts +10 -0
  25. package/dist/api/http/routes/keys.js +64 -0
  26. package/dist/api/http/routes/me.js +5 -2
  27. package/dist/api/http/routes/reads.d.ts +66 -0
  28. package/dist/api/http/routes/reads.js +127 -0
  29. package/dist/api/http/routes/sandboxes.js +7 -4
  30. package/dist/api/http/routes/sessions.js +25 -8
  31. package/dist/api/http/routes/tenant.js +15 -18
  32. package/dist/api/http/routes/vaults.d.ts +10 -9
  33. package/dist/api/http/routes/vaults.js +27 -23
  34. package/dist/api/openapi.d.ts +10 -11
  35. package/dist/api/openapi.js +288 -63
  36. package/dist/artifacts/links.js +1 -1
  37. package/dist/core/flow-host.d.ts +44 -23
  38. package/dist/core/flow-host.js +88 -106
  39. package/dist/core/provider.d.ts +4 -1
  40. package/dist/core/provider.js +6 -1
  41. package/dist/core/sandbox-routes.d.ts +0 -9
  42. package/dist/core/sandbox-routes.js +2 -21
  43. package/dist/execution/memory.d.ts +4 -5
  44. package/dist/execution/memory.js +11 -25
  45. package/dist/execution/types.d.ts +3 -33
  46. package/dist/execution/types.js +2 -12
  47. package/dist/gates/http-tool.d.ts +86 -0
  48. package/dist/gates/http-tool.js +197 -0
  49. package/dist/gates/mcp-handler.d.ts +3 -0
  50. package/dist/gates/mcp-handler.js +1 -3
  51. package/dist/gates/meter.d.ts +2 -2
  52. package/dist/gates/meter.js +6 -0
  53. package/dist/gates/tenant-vaults.d.ts +5 -9
  54. package/dist/gates/tool-calls.d.ts +7 -15
  55. package/dist/gates/tool-calls.js +4 -4
  56. package/dist/gates/tool-client.d.ts +1 -1
  57. package/dist/gates/tool-client.js +23 -47
  58. package/dist/gates/tool-contract.d.ts +27 -39
  59. package/dist/gates/tool-contract.js +30 -21
  60. package/dist/gates/tool-gate.d.ts +25 -24
  61. package/dist/gates/tool-gate.js +11 -7
  62. package/dist/harness/calls.d.ts +10 -4
  63. package/dist/harness/calls.js +15 -6
  64. package/dist/harness/executors.d.ts +1 -1
  65. package/dist/harness/executors.js +17 -12
  66. package/dist/harness/main.d.ts +2 -2
  67. package/dist/harness/main.js +5 -13
  68. package/dist/harness/service.d.ts +4 -5
  69. package/dist/harness/service.js +9 -2
  70. package/dist/harness-api/in-process.js +2 -2
  71. package/dist/harness-api/record.d.ts +6 -3
  72. package/dist/harness-api/record.js +65 -72
  73. package/dist/harness-api/server.d.ts +1 -9
  74. package/dist/harness-api/server.js +19 -17
  75. package/dist/harness-api/start.js +1 -5
  76. package/dist/harness-api/workspace.js +2 -3
  77. package/dist/harness-api/ws-server.js +1 -1
  78. package/dist/host/app.d.ts +2 -9
  79. package/dist/host/app.js +15 -25
  80. package/dist/host/config-for.d.ts +1 -5
  81. package/dist/host/config-for.js +0 -3
  82. package/dist/host/config.d.ts +0 -5
  83. package/dist/host/create-host.d.ts +3 -33
  84. package/dist/host/create-host.js +18 -94
  85. package/dist/host/environment.d.ts +0 -3
  86. package/dist/host/environment.js +0 -9
  87. package/dist/host/gates.d.ts +4 -1
  88. package/dist/host/gates.js +3 -2
  89. package/dist/host/http.d.ts +1 -2
  90. package/dist/host/http.js +1 -7
  91. package/dist/host/index.d.ts +2 -2
  92. package/dist/host/index.js +2 -2
  93. package/dist/host/main.js +27 -34
  94. package/dist/host/operate.d.ts +29 -0
  95. package/dist/host/operate.js +223 -0
  96. package/dist/host/stack-config.d.ts +12 -12
  97. package/dist/host/stack-config.js +5 -32
  98. package/dist/index.d.ts +1 -1
  99. package/dist/index.js +1 -1
  100. package/dist/infra/workers.d.ts +1 -1
  101. package/dist/keys/keys.js +2 -2
  102. package/dist/management-openapi.json +6491 -0
  103. package/dist/mcp/connect.d.ts +8 -4
  104. package/dist/mcp/connect.js +6 -26
  105. package/dist/mcp/pool.d.ts +5 -9
  106. package/dist/mcp/pool.js +8 -19
  107. package/dist/mcp/snapshot.d.ts +8 -2
  108. package/dist/mcp/snapshot.js +29 -2
  109. package/dist/media.d.ts +1 -1
  110. package/dist/media.js +1 -1
  111. package/dist/model/pi-model.js +3 -0
  112. package/dist/openapi.json +9372 -17030
  113. package/dist/reads/access.d.ts +4 -0
  114. package/dist/reads/access.js +12 -0
  115. package/dist/reads/cursor.d.ts +11 -0
  116. package/dist/reads/cursor.js +80 -0
  117. package/dist/reads/types.d.ts +25 -0
  118. package/dist/reads/types.js +1 -0
  119. package/dist/sandbox/manager.d.ts +16 -0
  120. package/dist/sandbox/manager.js +40 -0
  121. package/dist/sandbox/session-sandbox.js +13 -3
  122. package/dist/sandbox/skills.d.ts +13 -0
  123. package/dist/sandbox/skills.js +46 -0
  124. package/dist/sandbox/types.d.ts +2 -2
  125. package/dist/store/ownership.d.ts +9 -0
  126. package/dist/store/ownership.js +13 -0
  127. package/dist/store/postgres/connect.d.ts +2 -0
  128. package/dist/store/postgres/connect.js +29 -0
  129. package/dist/store/postgres/drizzle/0011_key_roles.sql +3 -0
  130. package/dist/store/postgres/drizzle/0012_session_reads.sql +8 -0
  131. package/dist/store/postgres/drizzle/0013_definition_files.sql +16 -0
  132. package/dist/store/postgres/drizzle/0014_action_endpoints_removed.sql +2 -0
  133. package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
  134. package/dist/store/postgres/reads.d.ts +3 -0
  135. package/dist/store/postgres/reads.js +272 -0
  136. package/dist/store/postgres/schema.d.ts +294 -489
  137. package/dist/store/postgres/schema.js +41 -76
  138. package/dist/store/postgres/store.js +51 -154
  139. package/dist/store/postgres/tenant.d.ts +34 -2
  140. package/dist/store/postgres/tenant.js +16 -32
  141. package/dist/store/types.d.ts +27 -96
  142. package/dist/store/types.js +0 -1
  143. package/dist/streams/control.d.ts +0 -2
  144. package/dist/streams/control.js +0 -5
  145. package/dist/streams/types.d.ts +1 -10
  146. package/dist/tenant/advance.d.ts +3 -3
  147. package/dist/tenant/advance.js +10 -7
  148. package/dist/tenant/auth.d.ts +14 -9
  149. package/dist/tenant/auth.js +24 -28
  150. package/dist/tenant/cause.d.ts +3 -3
  151. package/dist/tenant/cause.js +1 -1
  152. package/dist/tenant/commands.d.ts +2 -18
  153. package/dist/tenant/commands.js +35 -172
  154. package/dist/tenant/context.d.ts +14 -24
  155. package/dist/tenant/definition-files.d.ts +24 -0
  156. package/dist/tenant/definition-files.js +103 -0
  157. package/dist/tenant/effects.d.ts +18 -20
  158. package/dist/tenant/effects.js +56 -119
  159. package/dist/tenant/ephemeral.d.ts +7 -6
  160. package/dist/tenant/ephemeral.js +3 -11
  161. package/dist/tenant/host-token.js +1 -1
  162. package/dist/tenant/jwt.js +1 -1
  163. package/dist/tenant/module.d.ts +1 -4
  164. package/dist/tenant/module.js +3 -12
  165. package/dist/tenant/operator-keys.d.ts +34 -8
  166. package/dist/tenant/operator-keys.js +50 -18
  167. package/dist/tenant/outbound.d.ts +10 -1
  168. package/dist/tenant/outbound.js +44 -27
  169. package/dist/tenant/paths.d.ts +1 -1
  170. package/dist/tenant/paths.js +1 -3
  171. package/dist/tenant/principals.d.ts +11 -2
  172. package/dist/tenant/principals.js +27 -8
  173. package/dist/tenant/run-token.js +3 -3
  174. package/dist/tenant/runtime.d.ts +4 -6
  175. package/dist/tenant/runtime.js +19 -18
  176. package/dist/tenant/sandboxes.d.ts +4 -1
  177. package/dist/tenant/sandboxes.js +11 -0
  178. package/dist/tenant/scheduler.d.ts +1 -5
  179. package/dist/tenant/scheduler.js +2 -5
  180. package/dist/tenant/session-streams.d.ts +2 -1
  181. package/dist/tenant/session-streams.js +39 -5
  182. package/dist/tenant/session.d.ts +8 -41
  183. package/dist/tenant/session.js +0 -37
  184. package/dist/tenant/sessions.js +16 -8
  185. package/dist/tenant/signing-keys.d.ts +3 -3
  186. package/dist/tenant/signing-keys.js +5 -5
  187. package/dist/tenant/skill-tool.d.ts +20 -0
  188. package/dist/tenant/skill-tool.js +72 -0
  189. package/dist/tenant/slim.d.ts +1 -1
  190. package/dist/tenant/slim.js +1 -1
  191. package/dist/tenant/status.js +7 -12
  192. package/dist/tenant/store-pg.d.ts +15 -0
  193. package/dist/tenant/store-pg.js +7 -3
  194. package/dist/tenant/streams.d.ts +3 -10
  195. package/dist/tenant/streams.js +1 -24
  196. package/dist/tenant/sweep.js +0 -5
  197. package/dist/tenant/transcript.d.ts +2 -2
  198. package/dist/tenant/transcript.js +2 -2
  199. package/dist/tenant/types.d.ts +15 -22
  200. package/dist/tenant/worker.d.ts +1 -3
  201. package/dist/tenant/worker.js +3 -8
  202. package/dist/vault/sources.d.ts +7 -1
  203. package/dist/vault/sources.js +22 -11
  204. package/dist/version.d.ts +1 -1
  205. package/dist/version.js +1 -1
  206. package/package.json +4 -4
  207. package/dist/admin-openapi.json +0 -904
  208. package/dist/api/http/routes/actions.d.ts +0 -8
  209. package/dist/api/http/routes/actions.js +0 -75
  210. package/dist/api/http/routes/endpoints.d.ts +0 -7
  211. package/dist/api/http/routes/endpoints.js +0 -100
  212. package/dist/host/admin-api.d.ts +0 -30
  213. package/dist/host/admin-api.js +0 -140
  214. package/dist/mcp/stdio.d.ts +0 -17
  215. package/dist/mcp/stdio.js +0 -82
  216. package/dist/tenant/actions.d.ts +0 -14
  217. package/dist/tenant/actions.js +0 -29
  218. package/dist/tenant/delivery-token.d.ts +0 -41
  219. package/dist/tenant/delivery-token.js +0 -104
  220. package/dist/tenant/delivery.d.ts +0 -62
  221. package/dist/tenant/delivery.js +0 -481
  222. package/dist/tenant/endpoints.d.ts +0 -67
  223. package/dist/tenant/endpoints.js +0 -90
package/CHANGELOG.md CHANGED
@@ -1,5 +1,160 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.1-beta
4
+
5
+ ### Patch Changes
6
+
7
+ - 4b499ee: **The Runtime API's reference lists the Service endpoints last.** The Runtime API's tag groups are now Agents, Sessions, Sandboxes, Artifacts and Service. Service holds what was the Runtime tag under Get started: `/health`, `/ready`, `/v1/me`, the JWKS and `/openapi/runtime.json`. Sandboxes and Artifacts are a group each. The document no longer lists the `/openapi.json` alias; the Runtime still serves it.
8
+
9
+ ## 0.19.0-beta
10
+
11
+ ### Major Changes
12
+
13
+ - 4bd2a0b: **Flows run no code: workflow manifest v3 (manifest-only agents, step M2).** A flow agent is data: each stage gets the previous stage's output, a switch reads it, a map runs over it and a loop asks a verifier agent. See MIGRATION.md for what replaces each function.
14
+
15
+ - **Breaking (`@nylorun/core`, `@nylorun/agents`):** stage `input` functions, `switch` `on`, loop `verify` functions and `decide` are removed; a builder option that names one is refused with what replaces it. `.loop()` takes a verifier agent and a required `max`. New `.pipe(...children)` adds one stage per child; `.step()` is a deprecated alias (`NYLORUN_DEP_STEP`). `Chain`, `Switch`, `Parallel`, `Map`, `Loop`, `withInstructions`, `withoutTools`, `isSlot`, `functionKey` and the `StageArgs`, `LoopVerifyFn`, `LoopDecideArgs`, `LoopChoice` and v1 workflow types are removed. `Agent.from` for a flow takes tool nodes only.
16
+ - **Breaking (`@nylorun/core`):** workflow manifests are `workflowSchemaVersion: 3`; no node carries `input`, a switch has no `on`, a loop's `verify` is an agent and `max` is required. A v1 or v2 manifest is refused with a message naming the change. The `fn` and `verify` Actions and effect kinds, and the `loop.decided` event, are removed. `WorkflowManifestV2` / `WorkflowNodeV2` / `isWorkflowManifestV2` are now `WorkflowManifest` / `WorkflowNode` / `isWorkflowManifest`.
17
+ - **Breaking (`@nylorun/harness`):** the flow engine is `flow-3` and runs only v3 manifests; v1 and v2 engines, `agentTurnValue` and the `fn` / `verify` effect kinds are removed. A switch picks the case named by the previous output or its `route` field, a map runs over an array or an `items` array, and a loop retries with its verifier's feedback until `max`. An `agent` effect carries the flow's input as `flowInput` when the stage's input differs.
18
+ - **Breaking (`@nylorun/runtime`):** no `fn` or `verify` Actions are offered or delivered. An agent stage's message shows the flow's input as the original request before its own input, and each verifier verdict is recorded as `loop.verified`.
19
+ - `@nylorun/studio`: the workflow tree draws v3 manifests (a loop shows its verifier agent and `max`); the loop timeline drops decide outcomes, and `loop.verified` shows the feedback.
20
+
21
+ - 713e676: **Remote MCP servers only (blueprint D47).** Nylorun accepts `streamable-http` and `sse` MCP servers, declared by URL and reached through the gates; stdio servers and plugin roots are gone. See MIGRATION.md.
22
+
23
+ - **Breaking (`@nylorun/core`):** `McpServerManifest` and the manifest schema keep only `streamable-http` and `sse`. A `stdio` server is refused by `.mcp({...})` (`McpError`, code `mcp.stdio`), by `Agent.from` and by the wire schema, all with one message (`stdioMcpRefusal`): "MCP server 'x' uses stdio; Nylorun accepts remote MCP servers only (streamable-http or sse). Run the server behind an HTTP transport and declare its URL." `PutAgentRequest` loses `pluginRoots`, `CapabilityDeclaration` loses `pluginRoot`, and the Harness API's `RunRouting` loses `pluginRoots`.
24
+ - **Breaking (`@nylorun/agents`):** `.plugin()` and `plugin()` throw `PluginError` (code `plugin.mcp-stdio`) for a stdio server in a plugin's `mcp.json`; its remote servers and skills load as before. `saveAgent` no longer sends plugin roots. `prepareStdioLaunch`, `expandPluginPlaceholders` and `StdioLaunch` are removed.
25
+ - **Breaking (`@nylorun/runtime`):** no stdio MCP launcher: `PUT /v1/agents/:id` refuses a stdio server (`400`) and `pluginRoots`. `TenantConfig.childEnv`, `TenantPaths.pluginData` and `tmp`, `tenantChildEnvironment`, `startEphemeralRuntime({ baseline })` and `configForFactory`'s `baseline` and `hostConfig` are removed; the harness service no longer takes `childEnv` or `paths.pluginData`.
26
+ - `nylorun`: the local stack no longer mounts the Host root's `plugins/` into the runtime and harness containers, nor the Tenant's `plugin-data/`, `home/` and `tmp/` into the harness, which now mounts only `sandboxes/`.
27
+
28
+ - c135267: **Action endpoints are removed (manifest-only agents, M6).** The Runtime runs no code of yours during a session: an agent's tools are HTTP tools, remote MCP servers, agents used as tools and the Runtime's built-ins. Protocol stays 8; the `action-endpoints` feature is gone, so a client that requires it is refused. See MIGRATION.md, "Action endpoints are removed".
29
+
30
+ - **Breaking (`@nylorun/core`):** the `Action`, endpoint (`PutEndpointsRequest`, `Endpoint`, `EndpointHealth`, …) and delivery schemas, `SIGNATURE_HEADER`, `OUTCOME_HEADER`, `DELIVERY_TOKEN_TYPE` and the `action.*` events (`action.pending`, `.delivered`, `.delivery_failed`, `.completed`, `.uncertain`) are removed, and `ToolDefinition.background` with them. `ActionOutcome` is renamed `EffectOutcome`. Tenant status loses `checks.endpoints`, `agents[].registered` and `agents[].endpoint`, and `counts.pendingActions`; the session view loses `actions`. A `turn.paused` interaction carries the tool call's `callId`. New `codeToolsOf` and `codeToolRefusal` name a definition's tools that would run your code. The Harness API is v2 (`HARNESS_API_VERSION = 2`): `TurnStart.options.holdMs` and `effect.resolved` are removed.
31
+ - **Breaking (`@nylorun/harness`):** held runs are gone: `createHarness` loses `holdMs`, and `apiHost` its `hold` option.
32
+ - **Breaking (`@nylorun/agents`):** `createActionHandler`, `executeAction`, `createActionSandbox`, `definitionDeclaresSandbox`, `isActionSandboxTool` and the `Action`, `ActionOutcome`, `ActionHandler`, `ActionHandlerOptions`, `RegisterOptions`, `ExecuteActionOptions` and `ExecutableDefinition` types are removed. `saveAgent` refuses a code tool (`tool({ run })`) or a flow tool stage before sending; its `implementationVersion` is optional (`NYLORUN_IMPLEMENTATION_VERSION`, else `dev`).
33
+ - **Breaking (`@nylorun/runtime`):** `/v1/endpoints` and `/v1/actions/*` answer `404`; delivery tokens, the deliverer, background tools, held runs (`TenantConfig.actionHoldMs`), `DurableExecution.deliver`, the Restate `NylorunAction` object, the `action_result` wake and the gates service's `/nylorun/v1/deliveries` are removed, and a migration drops the `actions` and `endpoints` tables. `PUT /v1/agents/:id` refuses a definition with a code tool or a flow tool stage (`400`); a tool the Runtime cannot run fails with `tool.unavailable`. The fixture model answers in text when the agent offers no `lookup_order` tool.
34
+ - **Breaking (`@nylorun/cli`):** `nylo endpoints` is removed (a usage error that says why); `nylo status` shows uncertain effects instead of pending Actions.
35
+ - **Breaking (`@nylorun/create-agent`):** the starter saves its agent with `saveAgent` and runs no server: no Action endpoint, `PORT` or `NYLORUN_ACTIONS_URL`. Its assistant has no tools, with a commented `http()` tool to start from.
36
+ - `nylorun`: the local stack's comments speak of MCP servers and HTTP tools on this machine, not Action endpoints.
37
+ - `@nylorun/studio`: the `action.*` event views and delivery status are removed; the chat shows `tool.completed`, and the Agent Manifest tab lists tools without a target as code tools.
38
+
39
+ - d36f0d9: **Hooks are removed; manifests are v5 (manifest-only agents, step M1).** The Runtime no longer calls the developer's code before or after a turn or a model call. See MIGRATION.md for what replaces each use.
40
+
41
+ - **Breaking (`@nylorun/core`, `@nylorun/agents`):** `.beforeTurn()`, `.beforeModel()`, `.afterModel()`, `.afterTurn()`, the deprecated `.before()` / `.after()`, a capability's `before` / `after`, and the `Patch`, `Decision`, `TurnDecision`, `BeforeHook`, `AfterHook`, `HookScope` types and `runHookPoint` / `hooksFrom` helpers are removed. A capability that still passes `before` or `after` is refused with `hooks were removed: …`.
42
+ - **Breaking (`@nylorun/core`):** `manifestSchemaVersion` is 5. `capabilities[].hooks` is gone; a manifest that names it, or a v3/v4 manifest, is refused with a message naming the change. The `hook` Action and the `hook` effect kind of the Harness API are removed.
43
+ - **Breaking (`@nylorun/harness`):** the turn loop runs no hooks; the turn state a checkpoint carries is `{ turnId }`, and the engine version is `hosted-4`, so checkpoints of earlier engines are refused.
44
+ - `@nylorun/runtime`: no `hook` Actions are offered or delivered.
45
+ - `@nylorun/studio`: the Agent Manifest tab drops the Hooks count and the turn lifecycle.
46
+
47
+ - 107b07d: **Skills are files the Runtime holds and serves itself (track R2 M4).** Breaking: a skill's manifest names every file of its folder, and the skill tools no longer run in the developer's process. The protocol stays at 8 until the track ships.
48
+
49
+ - `@nylorun/core`: `SkillManifest` gains `files`, each path of the skill's folder (`SKILL.md` required, `/`-separated, no `..`, at most 500 files) mapped to `sha256:<hex>`, so the manifest hash pins them. `skillRecords` and `SkillRecord` are gone; a declaration's `skillFiles` holds the bytes to upload (`SkillFileSource`). `load_skill` and `read_skill_resource` keep their names and input schemas but fail with `skills.runtime-only` outside a Runtime. New `DefinitionFileViewSchema`, error code `definition_files_missing`, Harness API request `definition.file`, and `definitionFilesOf`, `isSkillTool` and the definition-file limits. A top-level `functions` key is reserved and refused ("Functions are not available yet").
50
+ - `@nylorun/runtime`: `PUT /v1/files/sha256:<hex>` stores a definition file (application key; at most 10 MiB; a body of another hash is `400`; `201` stored, `200` held already) in the Object store at `definitions/sha256/<hex>`, and `HEAD` says whether the Tenant holds one. New tables `definition_files` and `definition_file_uses` (migration `0013_definition_files`). `PUT /v1/agents/{id}` refuses a definition, nested agents and flow agents included, that names a file the Tenant lacks (`400 definition_files_missing`). Core serves `load_skill` (the `SKILL.md` body, the other files' paths, and `sandboxPath` with a sandbox) and `read_skill_resource` (text files only) from those files, with no Action. A session's sandbox gets each skill's files read-only under `/skills/<name>/` before the first call that opens it, and the sandbox's instructions name them; pod sandboxes mount an `emptyDir` at `/skills`. Unused files are not deleted yet.
51
+ - `@nylorun/agents`: `.skills()`, `skills()` and `.plugin()` read every file of a skill's folder, binary included (not `.git/`, `node_modules/`, OS files or `.env` files), and hash it; a file over 10 MiB or more than 500 files fail the build. `saveAgent` uploads the files the Runtime lacks before the definition; `client.files` (`has`, `upload`, `ensure`) does it by hand.
52
+ - `@nylorun/harness`: tests only.
53
+ - `@nylorun/studio`: the agent's manifest lists each skill's files.
54
+
55
+ ### Minor Changes
56
+
57
+ - a64aaca: **HTTP in flows (manifest-only agents, after M2 and M3).** An `http()` tool is a flow stage, and `http({ url })` is a Loop's HTTP verifier; the Runtime makes both requests through its Tool Gate, with no Action endpoint.
58
+
59
+ - `@nylorun/core`: an HTTP tool may be a stage in `.pipe()`, a switch case, a Map item or a Loop body; its tool node carries its `http` target and binds nothing. The build refuses an HTTP stage whose input is known to be the wrong type (`flow.input-mismatch`, e.g. after an agent with no `.output()`) and `approval: "always"` on one (`flow.approval-unsupported`). `http()` without a name and an input returns an `HttpTarget`, an HTTP verifier: `.loop(body, { verify: http({ url, method?, credential?, timeoutMs? }), max })`, in the manifest `loop.verify: { http }`. `fn` and `command` verify targets are refused ("Functions are not available yet"). New `flowHttpTarget()` finds an HTTP stage or verifier by stage key; `isHttpTarget()`, `WorkflowHttpVerify` and `WorkflowLoopVerify` are exported.
60
+ - `@nylorun/harness`: the flow engine checks an HTTP stage's input against its schema (`tool.invalid-input`), runs it as a `tool` effect and fails the stage on a failed outcome (`http.status`, `http.timeout`, `tool.invalid-output`, …). An HTTP verifier is a `tool` effect with `{ input, output, iteration }` and `context.role: "verify-http"`; a non-verdict or a failed request is `loop.verify-failed`. A Loop body that starts with an HTTP stage is retried with the Loop's input.
61
+ - `@nylorun/agents`: `http()` builds HTTP verifiers too.
62
+ - `@nylorun/runtime`: a flow's HTTP stages and verifiers are executed like an agent's HTTP tool: address policy, the flow session's vault credential, `Nylorun-Session-Id`/`-Turn-Id`/`-Agent-Id` (the flow agent's id) and the flow effect id as `Idempotency-Key`, run once at the gates service (`POST /nylorun/v1/http-calls` takes `tool: { sessionId?, stage }`) and `uncertain` when the answer is lost. An HTTP verifier's verdict is recorded as `loop.verified`.
63
+ - `@nylorun/studio`: the workflow tree shows HTTP stages and HTTP verifiers with their method and URL.
64
+
65
+ - 40b7648: **HTTP tools and static approval (manifest-only agents, M3).** A tool can be one HTTP request the Runtime makes through its Tool Gate, with no Action endpoint; code tools keep working.
66
+
67
+ - `@nylorun/core`: `ToolManifest` gains `http` (`url`, `method` `POST`/`PUT`/`PATCH`, `credential`, `timeoutMs` up to 300000) and `approval` (`never`/`always`, HTTP tools only); a tool is never both an agent and an HTTP request, and `fn` and `command` are refused ("Functions are not available yet"). Remote MCP servers take `approval`. `http()` builds an HTTP tool, `httpToolOf()` reads one; `SESSION_ID_HEADER`, `TURN_ID_HEADER` and `AGENT_ID_HEADER` name the headers it sends. `Agent.from` rebuilds HTTP tools without an implementation; an HTTP tool is refused as a flow stage.
68
+ - `@nylorun/harness`: hosted HTTP tools keep their target, and `approval: "always"` (an HTTP tool's, or `DurableSessionTool.approval` for a remote MCP server's tools) pauses each call for approval. **Breaking:** `HarnessExecutors.recovers.remoteMcp` is renamed `recovers.tool`.
69
+ - `@nylorun/agents`: exports `http` and the identity header constants.
70
+ - `@nylorun/runtime`: the Tool Gate runs HTTP tool calls (`POST /nylorun/v1/http-calls` at the gates service, or in process): the input as JSON under the Host's address policy, the session's vault credential bound to the URL, `Nylorun-Session-Id`/`-Turn-Id`/`-Agent-Id` and the effect id as `Idempotency-Key`. A keyed call runs once (`tool_crossings`), so a re-send after a takeover joins it and one lost with the gateway is `uncertain`. Non-2xx answers, timeouts, refused addresses, missing credentials and output mismatches are tool errors the model sees. The credential resolver is asked with `target.kind: "http"` and the tool's `credential` name.
71
+ - `@nylorun/studio`: the Agent Manifest tab lists HTTP tools with their method and URL, and marks tools and MCP servers that wait for approval.
72
+
73
+ ### Patch Changes
74
+
75
+ - Pin core to the tested release.
76
+ - Pin harness to the tested release.
77
+ - Updated dependencies [4bd2a0b]
78
+ - Updated dependencies [a64aaca]
79
+ - Updated dependencies [40b7648]
80
+ - Updated dependencies [713e676]
81
+ - Updated dependencies [c135267]
82
+ - Updated dependencies [d36f0d9]
83
+ - Updated dependencies [107b07d]
84
+ - Updated dependencies
85
+ - @nylorun/core@0.15.0-beta
86
+ - @nylorun/harness@0.23.0-beta
87
+
88
+ ## 0.18.0-beta
89
+
90
+ ### Major Changes
91
+
92
+ - 7f763c3: **The Admin API and the operator listener are gone (Runtime and Management APIs, step A5).** Host work moves to the machine: `nylorun` runs `nylorun-operate` inside the runtime container, and every remote client uses the Runtime API or the Management API.
93
+
94
+ - **Breaking (`@nylorun/runtime`):** `/v1/admin/*` (status, host, shutdown, keys, openapi.json) is removed; it answers like any unknown route. The operator listener, `NYLORUN_ADMIN_LISTEN_PORT`, `NYLORUN_ADMIN_LISTEN_HOST`, `NYLORUN_ADMIN_ALLOWED_HOSTS` and `host.json`'s `adminPort` are gone, and so is the `admin-openapi.json` package file. Stop the Host with SIGTERM. `nylorun-operate status [--json]` reports the version, protocol and the Tenant's id, name, state and cause, exiting 2 when the Tenant is not open. `/ready` adds `harness: { mode, connected }` while the Tenant is open. `startEphemeralRuntime` loses `operatorListener` and `adminUrl`. The admin key stays: it derives Studio's key.
95
+ - **Breaking (`@nylorun/admin`):** `createAdmin()` is the Management API client (`tenant`, `keys`, `models`, `vaults`, `signingKeys`, `settings`) with a management key: explicit `{ url, key }`, else `NYLORUN_RUNTIME_URL` + `NYLORUN_MANAGEMENT_KEY`, else the Project link's or the local Host root's management key. `status()`, `adminUrl`, the Admin API keys, `NYLORUN_ADMIN_URL`/`NYLORUN_ADMIN_KEY` and `OPERATOR_KEYS_FEATURE` are removed; `deriveStudioToken` and `mintStudioLoginToken` stay.
96
+ - **Breaking (`@nylorun/core`):** `admin-status` leaves `PROTOCOL_FEATURES` (the Host still advertises it for protocol 5–7 clients) and `operator-keys` is removed; `AdminStatusSchema`, `AdminHostStatusSchema`, `HostAggregateSchema` and `HostShutdownResponseSchema` are removed.
97
+ - **Breaking (`nylorun`):** no admin port: `NYLORUN_ADMIN_PORT` is no longer written or published (an existing one is ignored). `nylorun start` waits for `/ready`, and `nylorun status` reads readiness from `/ready` and the Tenant from `nylorun-operate status`.
98
+ - `@nylorun/cli`: `nylo status` no longer falls back to the Admin API; when the Tenant does not answer it points to `npx nylorun status`.
99
+
100
+ - 98b0d37: **Protocol 8: the Runtime API and the Management API take separate keys (Runtime and Management APIs, step A4).** Upgrade every package together; `nylorun`, `@nylorun/cli` and Studio already use management keys (A3).
101
+
102
+ - **Breaking (`@nylorun/runtime`): `/v1/tenant/*` takes only a management key.** An application key there, alone or acting for a subject, is `403 key_role_mismatch`; a management key acting for a subject is `403 subject_invalid`. This covers the Tenant's status, seed and reset, models, providers, usage and budgets, sandbox and artifact settings, application keys, vaults and signing keys. A management key on any other route but `/v1/me` and the public `/v1/access/jwks` is `403 key_role_mismatch`.
103
+ - **Breaking (`@nylorun/runtime`): vaults and signing keys moved.** They are at `/v1/tenant/vaults…` (including `…/oauth/start`) and `/v1/tenant/signing-keys…`; `/v1/vaults…` and `/v1/access/signing-keys…` are gone, with no alias. Opening a session with `vaultIds` is unchanged, as are `GET /v1/oauth/callback` and `GET /v1/access/jwks`.
104
+ - **Breaking (`@nylorun/core`, `@nylorun/runtime`): `tenant:settings` is retired.** It leaves `SUBJECT_SCOPES`; `Nylorun-Scopes` may still name it and it grants nothing. `/v1/tenant/models` and `/v1/tenant/providers` no longer admit `agents:write` subjects: apps don't read the model catalog.
105
+ - **Breaking (`@nylorun/agents`):** the vault methods (`createVault`, `listVaults`, `getVault`, `deleteVault`, `createCredential`, `listCredentials`, `getCredential`, `rotateCredential`, `deleteCredential`) and `client.access.signingKeys` / `SigningKeysClient` are removed; use `admin.vaults` and `admin.signingKeys` from `@nylorun/admin`'s `createManagementClient`. `client.access.jwks()` stays.
106
+ - `@nylorun/core`: `PROTOCOL_VERSION` is 8 and `HOST_PROTOCOL` 4–8, with the required feature `management-api`. Runtime API routes keep their request and response shapes.
107
+ - `@nylorun/runtime`: `startEphemeralRuntime` registers a management key (`managementKey`, the key `bootstrap`).
108
+
109
+ ### Minor Changes
110
+
111
+ - 3b3bdc6: **The clients use management keys (Runtime and Management APIs, step A3).** The protocol stays at 7; every client keeps working against a protocol 7 Runtime's routes.
112
+
113
+ - `nylorun`: `nylorun start` keeps an application key (`project`) and a management key (`project-management`) for a Project, in `<Host root>/project-credentials.json` and the Project's `.nylorun/credentials.json` (still format 1, with new `managementKey` and `managementPrincipalId` fields). A credentials file holding only an application key gains a management key at the next start. Commands outside a project keep `cli` and `cli-management`. Keys are issued through `nylorun-operate` in the runtime container instead of the Admin API, and `nylorun key put <id> --management` puts a management key. Seeding the Tenant and `nylorun mcp connect` use the management key (`/v1/tenant/vaults`). Studio reaches the Runtime's public listener.
114
+ - `@nylorun/cli`: `status`, `reset`, `configure`, `doctor` and `access signing-keys` use the Management API through `@nylorun/admin` with the Project's management key, or `NYLORUN_MANAGEMENT_KEY`.
115
+ - `@nylorun/studio`: local Studio needs no login. A request on the published loopback address (`localhost` or `127.0.0.1` at Studio's port) acts as signed in; hosts behind a sign-in proxy and embedding keep their login, and state-changing requests still need Studio's own `Origin`. Studio learns its Tenant from `GET /v1/tenant` with its key instead of the Admin API, and its Connections page manages vaults through `@nylorun/admin/client` at `/v1/tenant/vaults`.
116
+ - **Breaking (`@nylorun/admin`, `@nylorun/runtime`): Studio's key is derived from the admin key alone.** `deriveStudioToken(adminKey)` takes no Tenant id (HMAC-SHA256 over `nylorun/studio/v2`). The Host registers the new key's hash at its next start, replacing the old one; an app that embeds Studio and derives its key must update.
117
+ - `@nylorun/core`: `ProjectCredentialsFileSchema` gains optional `managementKey` and `managementPrincipalId`.
118
+
119
+ - 6576e12: **Key roles and management keys (Runtime and Management APIs, step A1).** Additive; the protocol stays at 7. Application keys keep reaching every route they reach today.
120
+
121
+ - `@nylorun/runtime`: a key now has a role. `application` keys are unchanged. A new **management key** (role `management`) reaches the Management API (`/v1/tenant/*`) and `/v1/me` only, as itself: `Nylorun-Subject` or `Nylorun-Scopes` with it is `403 subject_invalid`, an `Origin` is `403 origin_rejected`, and any other route is `403 key_role_mismatch`. `/v1/me` reports it as `via: management:<id>` with no scopes and no agents. Studio's derived key has role `studio`, which reaches both. Migration `0011_key_roles` gives the existing `studio` principal its role.
122
+ - `@nylorun/runtime`: management keys are issued only on the Tenant's machine, with the new `nylorun-operate` command in the runtime image (`nylorun-operate keys list | put <id> [--role application|management] | rm <id>`), or from `NYLORUN_MANAGEMENT_KEY_FILE` (64 hex characters), which the Host registers as the key `bootstrap` at every start and replaces when the file changes. `bootstrap` is reserved like `studio`. Rotating a key keeps its role; putting an id that holds the other role is refused.
123
+ - `@nylorun/core`: `KEY_ROLES`, `KeyRole`, `BOOTSTRAP_KEY_ID` and the error code `key_role_mismatch`.
124
+
125
+ - a6108f4: **The Management API's routes and client (Runtime and Management APIs, step A2).** Additive; the protocol stays at 7.
126
+
127
+ - `@nylorun/runtime`: `GET /v1/tenant/keys`, `PUT /v1/tenant/keys/{keyId}` and `DELETE /v1/tenant/keys/{keyId}` manage the Tenant's application keys with a management key. A management key's name, `studio` and `bootstrap` are refused, so no API call creates, rotates or deletes a management key. Vaults (`/v1/tenant/vaults…`, including `…/oauth/start`) and signing keys (`/v1/tenant/signing-keys…`) are also served under `/v1/tenant`, for management keys only; the old `/v1/vaults…` and `/v1/access/signing-keys…` paths keep serving application keys until protocol 8. `GET /v1/oauth/callback` and `GET /v1/access/jwks` keep their paths.
128
+ - `@nylorun/admin`: `createManagementClient({ url, key })` is the Management API's client: `tenant` (status, seed, reset), `keys` (application keys), `models` (catalog, providers, get, put, select, usage, budgets), `vaults` (with credentials and `startOAuth`), `signingKeys` and `settings` (sandbox, artifacts). `@nylorun/admin/client` exports it with no Node module, for browser apps behind a proxy that adds the key.
129
+
130
+ - 005a200: **Two reference documents (Runtime and Management APIs, step A6).** The Runtime serves the Runtime API's OpenAPI document at `/openapi/runtime.json` (`/openapi.json` stays as its alias) and the Management API's at `/openapi/management.json`, both without a key. The package ships them as `@nylorun/runtime/openapi.json` and the new `@nylorun/runtime/management-openapi.json`, and both are attached to each release. Each document has described tags, every operation in one of them, in the order a developer uses them, and only the schemas it uses. The Runtime API's tags are grouped (`x-tagGroups`): Get started (Runtime), Agents (Agents, Action endpoints, Deliveries), Sessions (Sessions API, AG-UI, A2A), Sandboxes & artifacts. The Management API's tags are Tenant, Application keys, Models, Vaults, Signing keys and Settings.
131
+ - c66d8ed: Add optional session reads and a resumable model-ledger export: pinned manifests, usage totals, model calls, and opt-in session/history/sandbox pages (Host feature `session-reads`), and `GET /v1/tenant/calls/model` on the Management API (Host feature `calls-export`). Usage and model calls take an application key acting as itself; the export takes a management key. Runtime reads use a separate bounded, read-only Drizzle pool. The additive migration `0012_session_reads` preserves unknown legacy creation times and usage quality; the export uses safe transaction order without skipping committed rows. `@nylorun/agents` adds `client.sessions.page()`, `session.manifest()`, `session.usage()`, `session.modelCalls()`, `session.history({ limit })` and `client.sandboxes.page()`; `@nylorun/admin` adds `models.exportCalls()`. Legacy unpaged responses are unchanged.
132
+
133
+ ### Patch Changes
134
+
135
+ - b387620: **A flow agent's tool step that asks now pauses the flow.** A tool step calling `ctx.approve(...)` or `ctx.ask(...)` used to settle its `interaction-required` outcome as the step's output, so the flow moved on and `turn.completed` carried that object, resume token and all. Now the flow session pauses with `turn.paused` and a wait (with the tool node's `path` and `toolName`); `session.approve(...)` or `session.respond(...)` on the flow's own session runs the tool again with the answer and its resume token, and the steps before it replay from the journal. A rejected approval settles the step `denied` without running the tool again, as in an agent's turn, so the turn fails with `tool.denied`. A flow's resume stays in its checkpoint segment (`FlowCheckpoint.resumes`), so its wake is keyed by the interaction. Waits a workflow copied from its linked sessions are no longer read back as its own.
136
+ - b28bdd7: **Local MCP servers work on a local Tenant, and a server that does not connect shows.** Additive; the protocol stays at 7.
137
+
138
+ - `@nylorun/runtime`: remote MCP servers (`streamable-http`, `sse`) are reached under the Host's address policy, as Action endpoints are (`NYLORUN_ENDPOINT_*`, `tenant/outbound.ts`). In the local Docker stack `localhost`, `127.0.0.1` and `[::1]` now mean the machine that runs Docker (`host.docker.internal`), so `.mcp({ x: { type: "streamable-http", url: "http://localhost:3002/x" } })` connects where it used to fail with `fetch failed`. With `NYLORUN_ENDPOINT_PRIVATE=refuse` a server on a private address is refused; with `NYLORUN_ENDPOINT_HTTP=refuse` an `http` server is refused. Redirects are still not followed. A connection failure now names its cause (`connect ECONNREFUSED …`) instead of `fetch failed`. This applies in the gateway, a harness process and an in-process Tenant. `guardedFetch` takes `stream: true`: the answer streams, unbounded, with no timeout but the caller's signal.
139
+ - `@nylorun/core`: new session event `mcp.discovered`, recorded once on the session's first turn with the MCP snapshot: one entry per declared server with `outcome` (`connected`, `refused`, `failed`), `message` and the number of `tools` it added (`McpDiscoveredPayloadSchema`, `McpServerOutcomeSchema`). A server that does not connect adds no tools for the session's life; this is where that shows in the event log, beside `mcpDiagnostics`.
140
+ - `@nylorun/agents`: `.plugin()` and `plugin()` emit a process warning (`NylorunPluginWarning`, the diagnostic's code) for each part of the package they skip, so building or registering the agent says when a plugin's MCP server was dropped. The `plugin.mcp-server-skipped` message now says why: for example, plain `http` is accepted only for `localhost`, `127.0.0.1` or `[::1]`.
141
+ - `@nylorun/studio`: the event list labels `mcp.discovered` and summarizes each server's outcome.
142
+
143
+ - 92faa35: **`nylorun-operate keys` names a database error.** When the Tenant's database cannot be read (a connection or driver failure), `nylorun-operate keys` now exits 2 with `The Tenant's database cannot be read: <cause>` instead of reporting that the database holds no Tenant.
144
+ - Pin core to the tested release.
145
+ - Pin harness to the tested release.
146
+ - Updated dependencies [3b3bdc6]
147
+ - Updated dependencies [b387620]
148
+ - Updated dependencies [6576e12]
149
+ - Updated dependencies [b28bdd7]
150
+ - Updated dependencies [cc107b1]
151
+ - Updated dependencies [7f763c3]
152
+ - Updated dependencies [98b0d37]
153
+ - Updated dependencies [c66d8ed]
154
+ - Updated dependencies
155
+ - @nylorun/core@0.14.0-beta
156
+ - @nylorun/harness@0.22.2-beta
157
+
3
158
  ## 0.17.0-beta
4
159
 
5
160
  ### Major Changes
package/README.md CHANGED
@@ -2,8 +2,10 @@
2
2
 
3
3
  The independent OSS **Runtime Host** consumes `@nylorun/harness/run` and
4
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`; the Host's status and operator keys belong to `@nylorun/admin`.
5
+ and does not import this package. Every Tenant serves two APIs on one URL: the
6
+ **Runtime API** for developers (agents, sessions with AG-UI and
7
+ A2A, sandboxes, artifacts), whose client is `@nylorun/agents`, and the
8
+ **Management API** for operators (`/v1/tenant/*`), whose client is `@nylorun/admin`.
7
9
  Vocabulary: [src/CONTEXT.md](./src/CONTEXT.md).
8
10
 
9
11
  Requires Node 24+. Build from the repository root:
@@ -35,14 +37,16 @@ transaction under an advisory lock, records them in `nylorun.__drizzle_migration
35
37
  refuses a database holding a migration it does not ship (`schema-too-new`); then, on
36
38
  first start, it creates the Tenant there: its id (`NYLORUN_TENANT_ID`, default a
37
39
  new one), its name (`NYLORUN_TENANT_NAME`, default `default`) and its Studio principal,
38
- whose key the admin key derives (the only derived key). Operator keys (`/v1/admin/keys`) add, rotate and delete the Tenant's
39
- application keys after that; a rotated or deleted key stops authenticating at once. A database written by a Runtime that kept several Tenants in one
40
+ whose key the admin key derives (the only derived key). Management keys come from
41
+ `nylorun-operate` or `NYLORUN_MANAGEMENT_KEY_FILE` (below), and a management key adds,
42
+ rotates and deletes the Tenant's application keys (`PUT /v1/tenant/keys/{keyId}`); a rotated
43
+ or deleted key stops authenticating at once. A database written by a Runtime that kept several Tenants in one
40
44
  database (`tenant_<id>` schemas), or by a pre-release build of one Tenant per database
41
45
  (`schema_version` tables), is refused: this release starts fresh on a new database. Restate runs one advance of a session at a time and holds the Tenant's sweep
42
46
  timer (Durable Session Execution); every session's events are relayed from the record to
43
47
  its own S2 stream, which history and SSE read (Durable Streams). One image runs every **service**,
44
- and `--service` picks what a process runs: `core` serves the Tenant API, Admin
45
- API and SSE and runs the stream relay, `loop` runs advances (the Worker), and
48
+ and `--service` picks what a process runs: `core` serves the Runtime API, the
49
+ Management API and SSE and runs the stream relay, `loop` runs advances (the Worker), and
46
50
  `gates` is the Model Gate, the only process that reads a model credential and
47
51
  calls providers. `core` and `loop` may share a process; `gates` never joins
48
52
  them. A local Tenant packs `core,loop` into the `runtime` container and
@@ -50,8 +54,7 @@ them. A local Tenant packs `core,loop` into the `runtime` container and
50
54
  api|worker|all` is the deprecated name of `--service core`, `loop` and
51
55
  `core,loop`.
52
56
 
53
- `harness` runs alone: agent turns, stdio MCP servers and workspaces, apart from
54
- core. With `NYLORUN_HARNESS=remote`, core runs no turn itself and opens the
57
+ `harness` runs alone: agent turns and workspaces, apart from core. With `NYLORUN_HARNESS=remote`, core runs no turn itself and opens the
55
58
  Harness API listener (`NYLORUN_HARNESS_LISTEN_HOST`, `NYLORUN_HARNESS_LISTEN_PORT`,
56
59
  default 4200, `NYLORUN_HARNESS_ALLOWED_HOSTS`), which accepts only
57
60
  `NYLORUN_HARNESS_TOKEN`; `in-process` (the default outside Compose) runs turns in
@@ -67,16 +70,15 @@ sets: `NYLORUN_DATABASE_URL` (required), `NYLORUN_RESTATE_INGRESS_URL`,
67
70
  `NYLORUN_RESTATE_ADMIN_URL`, `NYLORUN_WORKER_URL` and
68
71
  `NYLORUN_RESTATE_IDENTITY_KEY` (Restate), `NYLORUN_S2_ENDPOINT` and
69
72
  `NYLORUN_S2_TOKEN`, and in container mode `NYLORUN_LISTEN_HOST`,
70
- `NYLORUN_LISTEN_PORT`, `NYLORUN_ALLOWED_HOSTS` and `NYLORUN_PUBLIC_URL`, plus
71
- the operator listener
72
- (`NYLORUN_ADMIN_LISTEN_PORT`, `NYLORUN_ADMIN_LISTEN_HOST`,
73
- `NYLORUN_ADMIN_ALLOWED_HOSTS`). `NYLORUN_IDENTITY_FILE` names the identity
74
- file, a YAML list of the trusted issuers whose JWTs the Tenant API accepts
73
+ `NYLORUN_LISTEN_PORT`, `NYLORUN_ALLOWED_HOSTS` and `NYLORUN_PUBLIC_URL`.
74
+ `NYLORUN_MANAGEMENT_KEY_FILE` names the bootstrap secret (below).
75
+ `NYLORUN_IDENTITY_FILE` names the identity
76
+ file, a YAML list of the trusted issuers whose JWTs the Runtime API accepts
75
77
  (Host feature `trusted-issuers`), read once at boot; a malformed file stops the
76
78
  boot ([DEPLOYMENT.md](../DEPLOYMENT.md#trusted-issuers)). A process that runs `loop` sends its model
77
79
  calls to the gate at `NYLORUN_GATES_URL`; in a container it refuses to start
78
80
  without it and `NYLORUN_GATES_TOKEN`. That token is core's credential: the gate
79
- accepts only it for vault writes, token signing and Action deliveries. Model and
81
+ accepts only it for vault writes and token signing. Model, HTTP tool and
80
82
  remote MCP calls carry a run token instead, which the loop mints for each
81
83
  session it advances, and the gate takes the call's session, turn and agent from
82
84
  it; a token whose turn was cancelled or whose session another process took over
@@ -95,12 +97,25 @@ egress-gate on `NYLORUN_EGRESS_LISTEN_HOST`:`NYLORUN_EGRESS_LISTEN_PORT`
95
97
  tunnels only to the hosts its sandbox spec allows, on 443 or 80, never to a
96
98
  private address. `NYLORUN_PACKING` (`combined` or `split`) is logged at startup.
97
99
 
98
- With an operator listener (a local Tenant's default: container port 4001), the Host
99
- serves two ports. The public one serves the Tenant API, to browsers too (with a
100
- trusted issuer's token), and answers admin routes with the opaque `404`. The
101
- operator one serves the Admin API, Host shutdown and the Tenant API, never to
102
- browsers; keep it on loopback or a private network and never proxy it. Outside
103
- a container, `adminPort` in `host.json` does the same on loopback.
100
+ The Host has one listener, which serves both APIs. Host work runs on the machine
101
+ instead, with `nylorun-operate`, the image's operator command, inside the runtime
102
+ container (`docker compose exec runtime nylorun-operate …`, or
103
+ `kubectl exec … -- nylorun-operate …`). It reads the Tenant's database from
104
+ `NYLORUN_DATABASE_URL`, does one job and exits: being able to run it is the
105
+ authorization.
106
+
107
+ ```sh
108
+ nylorun-operate status [--json] # version, protocol, the Tenant's id, name, state and cause; exit 2 when not open
109
+ nylorun-operate keys list [--json] # every key: id, role, when issued
110
+ nylorun-operate keys put <id> [--role application|management] [--json] # prints the key once
111
+ nylorun-operate keys rm <id> [--json]
112
+ ```
113
+
114
+ `status` needs no key, so it reports why a Tenant cannot open. Where no one can run
115
+ `nylorun-operate`, `NYLORUN_MANAGEMENT_KEY_FILE` names a file holding a management key
116
+ (64 hex characters), the **bootstrap secret**: the Host registers it as the key
117
+ `bootstrap` at every start, and replaces it when the file changes. Stop the Host with
118
+ SIGTERM.
104
119
 
105
120
  The Host root is `NYLORUN_HOME` or `~/.nylorun` (for a local Tenant,
106
121
  `~/.nylorun/tenants/<name>/`, bind-mounted at `/nylorun` in its containers). What stays on the Host is under `tenant/`.
@@ -109,11 +124,11 @@ The Host root is `NYLORUN_HOME` or `~/.nylorun` (for a local Tenant,
109
124
 
110
125
  ```text
111
126
  <host root>/
112
- host.json # format 1: hostId, host, port, adminPort?, runtimeVersion, …
113
- host-credentials.json # adminKey (0600)
127
+ host.json # format 1: hostId, host, port, runtimeVersion, …
128
+ host-credentials.json # adminKey (0600): the root secret Studio's key derives from
114
129
  identity.yaml # optional: trusted issuers (NYLORUN_IDENTITY_FILE)
115
130
  docker/ # compose.yaml, .env (0600), Restate identity key
116
- tenant/ # vault-kek, plugin-data, logs, home, tmp, sandboxes
131
+ tenant/ # logs, home, sandboxes
117
132
  ```
118
133
 
119
134
  ## HTTP surface
@@ -121,29 +136,27 @@ The Host root is `NYLORUN_HOME` or `~/.nylorun` (for a local Tenant,
121
136
  | Route | Auth | Notes |
122
137
  | --- | --- | --- |
123
138
  | `GET /health` | none | `service: "nylorun-runtime"`, `hostId`, protocol `{min,max,features}`, pid |
124
- | `GET /ready` | none | Listener up, the Tenant open, and Postgres, Restate and S2 answer (`checks`) |
125
- | `GET /openapi.json` | none | The Tenant API's OpenAPI 3.2 document (below); refuses an `Origin` |
126
- | `GET /v1/admin/status` | admin key | `AdminStatusSchema`: the Host, its protocol and its Tenant (`tenant`: id, name, `open` or `unavailable`, and the cause when it could not be opened); alias `GET /v1/admin/host`. On the operator listener when there is one |
127
- | `POST /v1/admin/host/shutdown` | admin key | Host-private; not in `@nylorun/admin` |
128
- | `PUT /v1/admin/keys/{id}` | admin key | Operator keys (Host feature `operator-keys`): creates key `id` or rotates it, and returns it once (`PutOperatorKeyResponse`); `studio` is refused |
129
- | `GET /v1/admin/keys` | admin key | Every key of the Tenant: id, role, when issued (`ListOperatorKeysResponse`), never the keys |
130
- | `DELETE /v1/admin/keys/{id}` | admin key | The key stops authenticating at once; `404` when there is none |
131
- | `GET /v1/admin/openapi.json` | admin key | The Admin API's OpenAPI 3.2 document |
132
- | `/v1/*` Tenant routes | application key, trusted issuer's token or delivery token | Require `Nylorun-Protocol`; nothing names the Tenant |
133
- | `POST /v1/vaults/{vaultId}/oauth/start` | application key | MCP OAuth connect into an installation vault (F9 C2): `{url, server, clientId?}` → `{authorizeUrl, expiresAt}`; the gateway's keys module does discovery, registration and the exchange. `oauth_client_required` without DCR or a `clientId` |
139
+ | `GET /ready` | none | Listener up, the Tenant open, and Postgres, Restate and S2 answer (`checks`); `harness: { mode, connected }` while the Tenant is open |
140
+ | `GET /openapi/runtime.json` | none | The Runtime API's OpenAPI 3.2 document (below); alias `GET /openapi.json`. Refuses an `Origin` |
141
+ | `GET /openapi/management.json` | none | The Management API's OpenAPI 3.2 document. Refuses an `Origin` |
142
+ | `/v1/*` Runtime API routes (all but `/v1/tenant/*`) | application key or trusted issuer's token | Require `Nylorun-Protocol`; nothing names the Tenant. A management key is `403 key_role_mismatch`, except on `/v1/me` and the public `GET /v1/access/jwks` |
143
+ | `/v1/tenant/*` Management API routes | management key | Require `Nylorun-Protocol`. An application key, alone or acting for a subject, is `403 key_role_mismatch`; a management key with `Nylorun-Subject` or `Nylorun-Scopes` is `403 subject_invalid` |
144
+ | `PUT /v1/tenant/keys/{keyId}` | management key | Creates application key `keyId` or rotates it, and returns it once; `GET /v1/tenant/keys` lists every key (id, role, when issued, never the keys) and `DELETE` deletes one. `studio`, `bootstrap` and management keys are refused |
145
+ | `POST /v1/tenant/vaults/{vaultId}/oauth/start` | management key | MCP OAuth connect into an installation vault (F9 C2): `{url, server, clientId?}` → `{authorizeUrl, expiresAt}`; the gateway's keys module does discovery, registration and the exchange. `oauth_client_required` without DCR or a `clientId` |
134
146
  | `GET /v1/oauth/callback` | the `state` itself | Where the authorization server sends the browser back: no credential, no `Nylorun-Protocol`; finishes the connect once (`oauth_state_invalid` after) and answers a small HTML page. Its base is `NYLORUN_PUBLIC_URL`, else the start request's origin |
135
147
  | `GET /v1/artifact-links/{token}` | the link itself | A capability link to one artifact version (protocol 6): no credential, no `Nylorun-Protocol`, Range supported; a folder's link opens its zip, or one of its files |
136
148
 
137
149
  Every route checks `Host` first (`421 host_rejected`) and rejects non-JSON bodies
138
150
  with `415 unsupported_media_type`, except an artifact upload (`POST /v1/artifacts`,
139
151
  `POST /v1/artifacts/{id}/versions`), whose body is the file in any media type. An `Origin` is `403 origin_rejected` on
140
- `/health`, `/ready`, admin routes and the operator listener. On Tenant routes a browser
141
- presents a trusted issuer's token; application keys and delivery tokens are refused
142
- from browsers before they are looked up. The Runtime sends no CORS headers, and answers
152
+ `/health`, `/ready` and the OpenAPI documents. On `/v1` routes a browser
153
+ presents a trusted issuer's token; keys (application and management)
154
+ are refused from browsers before they are looked up. The Runtime sends no CORS headers, and answers
143
155
  `OPTIONS` with `204` and `Allow` only: the operator's reverse proxy answers preflights
144
156
  ([DEPLOYMENT.md](../DEPLOYMENT.md#calling-the-runtime-from-browsers-and-apps)). Missing or
145
- unsupported protocol → `426` before authentication (the Host serves protocols 4 to 7;
146
- protocol 7 removes subject tokens, the access policy, revocations, browser keys and
157
+ unsupported protocol → `426` before authentication (the Host serves protocols 4 to 8;
158
+ protocol 8 gives keys roles, moves vaults and signing keys under `/v1/tenant` and removes
159
+ the Admin API, and those old paths answer `404` with no alias; protocol 7 removes subject tokens, the access policy, revocations, browser keys and
147
160
  derived principals, whose routes answer `404`; protocol 6 adds file and folder artifacts and message `parts`; at each turn's end the
148
161
  Runtime exports `/workspace/outputs` of the session's sandbox as a version of its
149
162
  `outputs` folder, read at `/v1/artifacts/{id}/versions/{n|latest}/tree`, `/files/{path}`,
@@ -157,21 +170,28 @@ once the caller is known.
157
170
  The Runtime describes its APIs as OpenAPI 3.2 documents, generated from the routes it serves,
158
171
  so they cannot drift from its answers:
159
172
 
160
- | Document | In the package | Served | On each release |
173
+ | Document | In the package | Served (no key) | On each release |
161
174
  | --- | --- | --- | --- |
162
- | Tenant API | `@nylorun/runtime/openapi.json` | `GET /openapi.json` | `openapi.json` |
163
- | Admin API | `@nylorun/runtime/admin-openapi.json` | `GET /v1/admin/openapi.json` (admin key) | `admin-openapi.json` |
175
+ | Runtime API | `@nylorun/runtime/openapi.json` | `GET /openapi/runtime.json` (alias `GET /openapi.json`) | `openapi.json` |
176
+ | Management API | `@nylorun/runtime/management-openapi.json` | `GET /openapi/management.json` | `management-openapi.json` |
164
177
 
165
178
  The release assets are on the `@nylorun/runtime@<version>` GitHub Release. Point any OpenAPI 3.2
166
179
  tool at one of them; for [Scalar](https://scalar.com), the package file of a version works as is:
167
180
 
168
181
  ```text
169
182
  https://cdn.jsdelivr.net/npm/@nylorun/runtime@<version>/dist/openapi.json
183
+ https://cdn.jsdelivr.net/npm/@nylorun/runtime@<version>/dist/management-openapi.json
170
184
  ```
171
185
 
172
- Each operation's `security` says which credentials it takes (application key, trusted
173
- issuer's token, delivery token, admin key), and its `x-nylorun-credentials` and
174
- `x-nylorun-scopes` (the subject scopes that reach it) fields say who may call it. Event streams are `text/event-stream` with an `itemSchema`. `runtime/openapi/` holds the committed snapshots: a change to a route changes
186
+ Each document has described tags, in the order a developer uses them. The Runtime API's are
187
+ grouped (`x-tagGroups`): Agents (Agents, Definition files), Sessions (Sessions API, AG-UI,
188
+ A2A), Sandboxes, Artifacts and Service (health, readiness, `/v1/me`, the JWKS and the
189
+ document; the `/openapi.json` alias is served but not listed). The Management API's are
190
+ Tenant, Application keys, Models, Vaults, Signing keys and Settings. Each operation's
191
+ `security` says which credentials it takes (application key and trusted issuer's token in
192
+ the Runtime API; management key in the Management API), and its
193
+ `x-nylorun-credentials` and `x-nylorun-scopes` (the subject scopes that reach it) fields say
194
+ who may call it. Event streams are `text/event-stream` with an `itemSchema`. `runtime/openapi/` holds the committed snapshots: a change to a route changes
175
195
  them (`node scripts/build-openapi.mjs --write`), and `check-package` fails until they are
176
196
  updated.
177
197
 
@@ -180,15 +200,16 @@ updated.
180
200
  Routes are Hono routes (`@hono/zod-openapi`), each declared once with who may call it
181
201
  (`api/http/define.ts`): that declaration serves the route, checks subject scopes and makes
182
202
  the OpenAPI document. `host/` holds the listeners, the `Host`
183
- check (in Node, before Hono) and the Host pipeline (`host/app.ts`); `api/` the Tenant and
184
- Admin routes (`api/http/routes/`, `api/ag-ui/`, `api/a2a/`, `host/admin-api.ts`). Only `host/`
185
- and `api/` import Hono.
203
+ check (in Node, before Hono) and the Host pipeline (`host/app.ts`); `api/` the routes of
204
+ both APIs (`api/http/routes/`, `api/ag-ui/`, `api/a2a/`). Only `host/` and `api/` import
205
+ Hono. `nylorun-operate` is `host/operate.ts`.
186
206
 
187
207
  ## Embedding and tests
188
208
 
189
209
  Tests and ephemeral embeds use `startEphemeralRuntime()` from
190
210
  `@nylorun/runtime/core`: private Host on port 0, temporary Host root, one Tenant,
191
- returns `{ url, tenantId, applicationKey, adminKey, close() }`. Its Tenant is the
211
+ returns `{ url, tenantId, applicationKey, managementKey, adminKey, close() }`
212
+ (`managementKey` is the key `bootstrap`, for the Management API). Its Tenant is the
192
213
  one Tenant of the Postgres database you pass as `database` (required): a pool, which
193
214
  you end, or a URL, for which it opens a pool and ends it on `close()`. It creates the
194
215
  Tenant there on first start, as a Host does (with `tenantId`, `name` and an application
@@ -210,10 +231,11 @@ The package's own tests run every Session Store on Postgres: `npm test` gives ea
210
231
  test file a database on the Docker test stack (`test/stack/compose.yaml`) and starts
211
232
  the stack when it is down; see [CONTRIBUTING.md](../CONTRIBUTING.md).
212
233
 
213
- Register Action endpoints with `PUT /v1/endpoints` using the application principal
214
- (`createActionHandler(...).register({ url })` in `@nylorun/agents` does this). The
215
- Runtime delivers each Action there with an `http` or `https` POST, so the URL must be
216
- reachable from the Runtime. Model gateway
234
+ Save agents with `PUT /v1/agents/{agentId}` using the application principal (`saveAgent`
235
+ in `@nylorun/agents`). The Runtime runs the agent from its manifest and never calls your
236
+ code during a session: a definition with a tool that would (`tool({ run })`, a flow's tool
237
+ stage) is refused. Your services are reached as tools: HTTP tools, POSTed from the Runtime,
238
+ so their URLs must be reachable from it, and remote MCP servers. Model gateway
217
239
  and sandbox backend are Tenant configuration (vault / seed), not Host process
218
240
  env.
219
241
 
@@ -221,12 +243,10 @@ env.
221
243
 
222
244
  The session-first `/v1` API is specified in
223
245
  [HOST_CONTRACT.md](../harness/HOST_CONTRACT.md). Application tokens authorize
224
- definition/session APIs. The Runtime delivers Actions to Action endpoints, and a
225
- delivery token authorizes only its own Action's heartbeat, result and sandbox calls.
226
- Session observers cannot submit action results.
246
+ definition/session APIs.
227
247
 
228
248
  Postgres transactions persist session checkpoints, command receipts, individual
229
- effects/actions, waits and the record of session events — in the Tenant's database; history is
249
+ effects, waits and the record of session events — in the Tenant's database; history is
230
250
  read from Durable Streams (S2). An advance owns its session through a lease with
231
251
  an epoch; a Worker that takes over after a crash marks in-flight effects
232
252
  `uncertain`. Vault ciphertext needs that Tenant's own KEK.
@@ -246,14 +266,25 @@ the Project link (outside a project it runs the Tenant `default`); the project's
246
266
  | Symptom | What to do |
247
267
  | --- | --- |
248
268
  | `kek-missing` | Restore `vault-kek` in the Tenant directory |
249
- | `GET /ready` is 503 and `/v1/admin/status` names a `tenant.cause` | The Tenant could not be opened; every Tenant request is the opaque `404`. Follow the cause's `repair`, then restart the Runtime |
269
+ | `GET /ready` is 503 with `checks.tenant: false` | The Tenant could not be opened; every `/v1` request is the opaque `404`. `nylorun status` on a local Tenant, or `nylorun-operate status` in the runtime container, names the cause and its repair. Follow it, then restart the Runtime; otherwise the Runtime's log names the cause |
250
270
  | `corrupt` / `migration-failed` / `envelope-invalid` / `open-failed` / `open-timeout` | Follow the cause's `repair` string |
251
271
  | `schema-too-new` | Run a Runtime at least as new as the one that migrated the database |
252
272
  | `database-layout-old` | The database holds `tenant_<id>` schemas of an older Runtime, or the `schema_version` tables of a pre-release one: point the Runtime at a new database (locally, a new Tenant: `nylorun start --tenant <new name>`); the old one is left as it is |
253
273
  | `426 protocol_unsupported` | Upgrade clients or Host to a compatible set |
254
- | `421 host_rejected` / `403 origin_rejected` | In a container, list the `Host` in `NYLORUN_ALLOWED_HOSTS`. From a browser, send a trusted issuer's token, never a Tenant key |
274
+ | `421 host_rejected` / `403 origin_rejected` | In a container, list the `Host` in `NYLORUN_ALLOWED_HOSTS`. From a browser, send a trusted issuer's token, never a key |
275
+ | `403 key_role_mismatch` | The key belongs to the other API: use a management key on `/v1/tenant/*` (`@nylorun/admin`) and an application key everywhere else (`@nylorun/agents`) |
255
276
  | `503` for a Tenant | Postgres or Restate is unreachable; `GET /ready` names which |
256
277
  | Port in use | Change `NYLORUN_PORT` in `~/.nylorun/tenants/<name>/docker/.env` and run `nylorun start` |
257
278
  | Logs | `nylorun logs runtime` |
258
279
 
259
280
  Definitions have no `agent.run()`; applications use `@nylorun/agents`.
281
+
282
+ ## Session reads
283
+
284
+ Hosts advertising `session-reads` serve pinned session manifests, recorded usage, model-call
285
+ pages and opt-in session/history/sandbox pagination. `calls-export` adds the Management API's
286
+ unfiltered, resumable model ledger export (`GET /v1/tenant/calls/model`, a management key) in
287
+ safe transaction order. Existing list/history
288
+ requests without `limit` retain their response shapes. These are public APIs for Studio,
289
+ CLI and custom clients; clients never need database access. See the
290
+ [API contracts, authorization, SDK examples and Studio handoff](https://github.com/nylorun/agents/blob/main/runtime/docs/session-reads.md).
@@ -96,11 +96,9 @@ export declare class RestateExecution implements DurableExecution {
96
96
  session: string;
97
97
  tenant: string;
98
98
  timer: string;
99
- action: string;
100
99
  sandbox: string;
101
100
  };
102
101
  wake(tenantId: string, sessionId: string, wake: Wake): Promise<void>;
103
- deliver(tenantId: string, actionId: string): Promise<void>;
104
102
  sandbox(tenantId: string, sandboxId: string, signal: SandboxSignal): Promise<void>;
105
103
  timer(tenantId: string, key: string, at: Date): Promise<void>;
106
104
  armSweep(tenantId: string): Promise<void>;
@@ -118,7 +116,7 @@ export declare class RestateExecution implements DurableExecution {
118
116
  private definitions;
119
117
  /**
120
118
  * Runs a Worker handler with a signal aborted by `stop` or by the end of the Restate
121
- * attempt (`advance` and `deliver`).
119
+ * attempt (`advance` and `reconcile`).
122
120
  */
123
121
  private runAborted;
124
122
  /** Runs a Worker handler so that `stop` waits for it. Refuses once stopping; Restate retries. */
@@ -17,11 +17,6 @@
17
17
  * - `<prefix>NylorunTimer`, key `<tenantId>:<timer key>`. `set` records the
18
18
  * latest time and sends a delayed `fire`; a `fire` for an older time is a
19
19
  * no-op, which is how setting a key again replaces it.
20
- * - `<prefix>NylorunAction`, key `<tenantId>:<actionId>`. Its exclusive
21
- * `deliver` handler calls `WorkerHandlers.deliver`. Like `advance`, it keeps
22
- * no state and makes no `ctx.run`: its only journal entry is the delayed
23
- * self-send after a `retry` result, so an endpoint that is down never spends
24
- * the retry budget, which is for infrastructure errors.
25
20
  * - `<prefix>NylorunSandbox`, key `<tenantId>:<sandboxId>` (F7.2). Its
26
21
  * exclusive handlers serialize a pod sandbox's reconciles and timers:
27
22
  * `reconcile` calls `WorkerHandlers.sandbox`; `arm` records a timer's latest
@@ -29,7 +24,7 @@
29
24
  * `fire`; a `fire` for an older time is a no-op, as the timer object's.
30
25
  * What a run answers arms its timers and its retry.
31
26
  *
32
- * Wakes, deliveries, timers and sweep arming go through the ingress as one-way
27
+ * Wakes, sandbox reconciles, timers and sweep arming go through the ingress as one-way
33
28
  * sends, so an API node can call them without ever calling `start`.
34
29
  */
35
30
  import { createServer } from "node:http2";
@@ -60,7 +55,6 @@ export class RestateExecution {
60
55
  session: `${prefix}NylorunSession`,
61
56
  tenant: `${prefix}NylorunTenant`,
62
57
  timer: `${prefix}NylorunTimer`,
63
- action: `${prefix}NylorunAction`,
64
58
  sandbox: `${prefix}NylorunSandbox`,
65
59
  };
66
60
  this.ingressUrl = options.ingressUrl.replace(/\/+$/, "");
@@ -76,9 +70,6 @@ export class RestateExecution {
76
70
  throw new Error(`Unknown wake reason: ${String(wake.reason)}`);
77
71
  await this.send(this.names.session, sessionKey(tenantId, sessionId), "advance", { reason: wake.reason }, wake.dedupeKey);
78
72
  }
79
- async deliver(tenantId, actionId) {
80
- await this.send(this.names.action, sessionKey(tenantId, actionId), "deliver", {});
81
- }
82
73
  async sandbox(tenantId, sandboxId, signal) {
83
74
  const key = sessionKey(tenantId, sandboxId);
84
75
  if (signal.kind === "reconcile")
@@ -259,24 +250,6 @@ export class RestateExecution {
259
250
  },
260
251
  options: serviceOptions,
261
252
  });
262
- const action = restate.object({
263
- name: names.action,
264
- handlers: {
265
- deliver: async (ctx, _input) => {
266
- const { tenantId, sessionId: actionId } = parseSessionKey(ctx.key);
267
- const result = await this.runAborted(ctx.request().attemptCompletedSignal, (handlers, signal) => {
268
- if (!handlers.deliver)
269
- throw new Error("WorkerHandlers.deliver is required for deliveries");
270
- return handlers.deliver(tenantId, actionId, signal);
271
- });
272
- if (result.status === "retry")
273
- ctx
274
- .objectSendClient({ name: names.action }, ctx.key)
275
- .deliver({}, restate.rpc.sendOpts({ delay: Math.max(0, result.retryAfterMs) }));
276
- },
277
- },
278
- options: serviceOptions,
279
- });
280
253
  /** Sets a sandbox timer: the latest time wins; `fire` checks it. */
281
254
  const armSandbox = async (ctx, input) => {
282
255
  ctx.set(`at:${input.timer}`, input.at);
@@ -318,11 +291,11 @@ export class RestateExecution {
318
291
  },
319
292
  options: serviceOptions,
320
293
  });
321
- return [session, tenant, timer, action, sandbox];
294
+ return [session, tenant, timer, sandbox];
322
295
  }
323
296
  /**
324
297
  * Runs a Worker handler with a signal aborted by `stop` or by the end of the Restate
325
- * attempt (`advance` and `deliver`).
298
+ * attempt (`advance` and `reconcile`).
326
299
  */
327
300
  async runAborted(attemptDone, fn) {
328
301
  const controller = new AbortController();
@@ -424,7 +397,7 @@ export async function listStuckInvocations(options) {
424
397
  const prefix = options.servicePrefix ?? "";
425
398
  if (!/^[A-Za-z0-9_]*$/.test(prefix))
426
399
  throw new Error(`Invalid Restate service prefix: ${prefix}`);
427
- const services = ["NylorunSession", "NylorunTenant", "NylorunTimer", "NylorunAction", "NylorunSandbox"].map((name) => `'${prefix}${name}'`);
400
+ const services = ["NylorunSession", "NylorunTenant", "NylorunTimer", "NylorunSandbox"].map((name) => `'${prefix}${name}'`);
428
401
  const clauses = [
429
402
  `target_service_name IN (${services.join(", ")})`,
430
403
  `status IN ('paused', 'backing-off')`,
@@ -146,7 +146,7 @@ export function createPgoutputSource(options) {
146
146
  },
147
147
  async lag() {
148
148
  // An idle relay confirms one byte past the last record, ahead of pg_current_wal_lsn():
149
- // that is no lag, not -1 (the Admin status refuses a negative lag).
149
+ // that is no lag, not -1.
150
150
  const { rows } = await pool.query(`SELECT GREATEST(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn), 0)::text AS lag
151
151
  FROM pg_replication_slots WHERE slot_name = $1`, [slot]);
152
152
  return rows[0]?.lag == null ? undefined : Number(rows[0].lag);
@@ -164,7 +164,7 @@ export function localBackend(options) {
164
164
  return { entries, truncated: !complete };
165
165
  },
166
166
  async writeFile(path, content) {
167
- await writeFile(path, content, "utf8");
167
+ await (typeof content === "string" ? writeFile(path, content, "utf8") : writeFile(path, content));
168
168
  },
169
169
  async stop() { },
170
170
  };
@@ -140,7 +140,7 @@ export function virtualBackend(options) {
140
140
  return { entries, truncated: !complete };
141
141
  },
142
142
  async writeFile(path, content) {
143
- await fs.writeFile(path, content, "utf8");
143
+ await (typeof content === "string" ? fs.writeFile(path, content, "utf8") : fs.writeFile(path, content));
144
144
  },
145
145
  async stop() { },
146
146
  };