@nylorun/runtime 0.16.0-beta → 0.19.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 +207 -0
- package/README.md +105 -63
- package/dist/adapters/execution/restate.d.ts +1 -3
- package/dist/adapters/execution/restate.js +4 -31
- package/dist/adapters/replication/pgoutput.js +1 -1
- package/dist/adapters/sandbox/local.js +1 -1
- package/dist/adapters/sandbox/virtual.js +1 -1
- package/dist/api/ag-ui/endpoint.js +1 -2
- package/dist/api/ag-ui/routes.d.ts +1 -1
- package/dist/api/ag-ui/routes.js +11 -13
- package/dist/api/ag-ui/translate.d.ts +1 -3
- package/dist/api/ag-ui/translate.js +2 -17
- package/dist/api/components.d.ts +4783 -2588
- package/dist/api/components.js +19 -21
- package/dist/api/gate/routes.d.ts +7 -8
- package/dist/api/gate/routes.js +58 -52
- package/dist/api/http/app.d.ts +6 -0
- package/dist/api/http/app.js +20 -14
- package/dist/api/http/define.d.ts +22 -13
- package/dist/api/http/define.js +43 -39
- package/dist/api/http/routes/access.d.ts +3 -19
- package/dist/api/http/routes/access.js +25 -184
- package/dist/api/http/routes/artifacts.js +3 -7
- package/dist/api/http/routes/files.d.ts +8 -0
- package/dist/api/http/routes/files.js +77 -0
- package/dist/api/http/routes/keys.d.ts +10 -0
- package/dist/api/http/routes/keys.js +64 -0
- package/dist/api/http/routes/me.d.ts +13 -0
- package/dist/api/http/routes/me.js +48 -0
- package/dist/api/http/routes/reads.d.ts +66 -0
- package/dist/api/http/routes/reads.js +127 -0
- package/dist/api/http/routes/sandboxes.d.ts +2 -2
- package/dist/api/http/routes/sandboxes.js +8 -7
- package/dist/api/http/routes/sessions.js +31 -20
- package/dist/api/http/routes/tenant.js +15 -18
- package/dist/api/http/routes/vaults.d.ts +13 -3
- package/dist/api/http/routes/vaults.js +136 -64
- package/dist/api/openapi.d.ts +10 -11
- package/dist/api/openapi.js +292 -68
- package/dist/artifacts/links.js +6 -6
- package/dist/artifacts/service.js +1 -1
- package/dist/core/flow-host.d.ts +44 -23
- package/dist/core/flow-host.js +88 -106
- package/dist/core/provider.d.ts +4 -1
- package/dist/core/provider.js +6 -1
- package/dist/core/sandbox-routes.d.ts +0 -9
- package/dist/core/sandbox-routes.js +2 -21
- package/dist/execution/memory.d.ts +4 -5
- package/dist/execution/memory.js +11 -25
- package/dist/execution/types.d.ts +3 -33
- package/dist/execution/types.js +2 -12
- package/dist/gates/http-tool.d.ts +86 -0
- package/dist/gates/http-tool.js +197 -0
- package/dist/gates/mcp-handler.d.ts +3 -0
- package/dist/gates/mcp-handler.js +6 -4
- package/dist/gates/meter.d.ts +2 -2
- package/dist/gates/meter.js +6 -0
- package/dist/gates/tenant-vaults.d.ts +19 -14
- package/dist/gates/tenant-vaults.js +17 -12
- package/dist/gates/tool-calls.d.ts +7 -15
- package/dist/gates/tool-calls.js +4 -4
- package/dist/gates/tool-client.d.ts +1 -1
- package/dist/gates/tool-client.js +23 -47
- package/dist/gates/tool-contract.d.ts +27 -39
- package/dist/gates/tool-contract.js +30 -21
- package/dist/gates/tool-gate.d.ts +25 -24
- package/dist/gates/tool-gate.js +11 -7
- package/dist/harness/calls.d.ts +10 -4
- package/dist/harness/calls.js +15 -6
- package/dist/harness/executors.d.ts +1 -1
- package/dist/harness/executors.js +17 -12
- package/dist/harness/main.d.ts +2 -2
- package/dist/harness/main.js +5 -13
- package/dist/harness/service.d.ts +4 -5
- package/dist/harness/service.js +9 -2
- package/dist/harness-api/in-process.js +2 -2
- package/dist/harness-api/record.d.ts +6 -3
- package/dist/harness-api/record.js +65 -72
- package/dist/harness-api/server.d.ts +1 -9
- package/dist/harness-api/server.js +19 -17
- package/dist/harness-api/start.js +1 -5
- package/dist/harness-api/workspace.js +2 -3
- package/dist/harness-api/ws-server.js +1 -1
- package/dist/host/app.d.ts +2 -10
- package/dist/host/app.js +24 -44
- package/dist/host/config-for.d.ts +5 -5
- package/dist/host/config-for.js +2 -3
- package/dist/host/config.d.ts +0 -11
- package/dist/host/create-host.d.ts +3 -40
- package/dist/host/create-host.js +18 -91
- package/dist/host/environment.d.ts +0 -3
- package/dist/host/environment.js +0 -9
- package/dist/host/gates.d.ts +4 -1
- package/dist/host/gates.js +9 -3
- package/dist/host/http.d.ts +1 -2
- package/dist/host/http.js +1 -7
- package/dist/host/index.d.ts +2 -2
- package/dist/host/index.js +2 -2
- package/dist/host/main.js +55 -40
- package/dist/host/operate.d.ts +29 -0
- package/dist/host/operate.js +223 -0
- package/dist/host/stack-config.d.ts +23 -20
- package/dist/host/stack-config.js +28 -44
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/infra/workers.d.ts +1 -1
- package/dist/keys/client.js +9 -1
- package/dist/keys/keys.d.ts +12 -2
- package/dist/keys/keys.js +10 -2
- package/dist/management-openapi.json +6491 -0
- package/dist/mcp/connect.d.ts +8 -4
- package/dist/mcp/connect.js +8 -27
- package/dist/mcp/pool.d.ts +6 -9
- package/dist/mcp/pool.js +8 -18
- package/dist/mcp/snapshot.d.ts +8 -2
- package/dist/mcp/snapshot.js +29 -2
- package/dist/media.d.ts +1 -1
- package/dist/media.js +1 -1
- package/dist/model/pi-model.js +3 -0
- package/dist/openapi.json +6228 -15615
- package/dist/reads/access.d.ts +4 -0
- package/dist/reads/access.js +12 -0
- package/dist/reads/cursor.d.ts +11 -0
- package/dist/reads/cursor.js +80 -0
- package/dist/reads/types.d.ts +25 -0
- package/dist/reads/types.js +1 -0
- package/dist/sandbox/manager.d.ts +16 -0
- package/dist/sandbox/manager.js +40 -0
- package/dist/sandbox/session-sandbox.js +13 -3
- package/dist/sandbox/skills.d.ts +13 -0
- package/dist/sandbox/skills.js +46 -0
- package/dist/sandbox/types.d.ts +2 -2
- package/dist/store/ownership.d.ts +9 -0
- package/dist/store/ownership.js +13 -0
- package/dist/store/postgres/connect.d.ts +2 -0
- package/dist/store/postgres/connect.js +29 -0
- package/dist/store/postgres/drizzle/0008_installation_vaults.sql +2 -0
- package/dist/store/postgres/drizzle/0009_oauth_pending.sql +19 -0
- package/dist/store/postgres/drizzle/0010_oss_auth_removals.sql +3 -0
- package/dist/store/postgres/drizzle/0011_key_roles.sql +3 -0
- package/dist/store/postgres/drizzle/0012_session_reads.sql +8 -0
- package/dist/store/postgres/drizzle/0013_definition_files.sql +16 -0
- package/dist/store/postgres/drizzle/0014_action_endpoints_removed.sql +2 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +49 -0
- package/dist/store/postgres/reads.d.ts +3 -0
- package/dist/store/postgres/reads.js +272 -0
- package/dist/store/postgres/schema.d.ts +423 -594
- package/dist/store/postgres/schema.js +84 -101
- package/dist/store/postgres/store.js +96 -248
- package/dist/store/postgres/tenant.d.ts +34 -2
- package/dist/store/postgres/tenant.js +16 -32
- package/dist/store/types.d.ts +44 -119
- package/dist/store/types.js +0 -1
- package/dist/streams/control.d.ts +0 -7
- package/dist/streams/control.js +0 -13
- package/dist/streams/types.d.ts +2 -20
- package/dist/streams/types.js +1 -1
- package/dist/tenant/advance.d.ts +3 -3
- package/dist/tenant/advance.js +10 -7
- package/dist/tenant/auth.d.ts +24 -15
- package/dist/tenant/auth.js +44 -55
- package/dist/tenant/cause.d.ts +3 -3
- package/dist/tenant/cause.js +1 -1
- package/dist/tenant/commands.d.ts +2 -18
- package/dist/tenant/commands.js +38 -179
- package/dist/tenant/context.d.ts +33 -45
- package/dist/tenant/definition-files.d.ts +24 -0
- package/dist/tenant/definition-files.js +103 -0
- package/dist/tenant/effects.d.ts +20 -18
- package/dist/tenant/effects.js +59 -133
- package/dist/tenant/ephemeral.d.ts +21 -8
- package/dist/tenant/ephemeral.js +11 -12
- package/dist/tenant/host-token.js +5 -5
- package/dist/tenant/identity-file.d.ts +75 -0
- package/dist/tenant/identity-file.js +202 -0
- package/dist/tenant/issuers.d.ts +48 -0
- package/dist/tenant/issuers.js +311 -0
- package/dist/tenant/jwt.js +3 -3
- package/dist/tenant/module.d.ts +1 -4
- package/dist/tenant/module.js +3 -12
- package/dist/tenant/operator-keys.d.ts +44 -0
- package/dist/tenant/operator-keys.js +87 -0
- package/dist/tenant/outbound.d.ts +40 -1
- package/dist/tenant/outbound.js +167 -18
- package/dist/tenant/paths.d.ts +1 -1
- package/dist/tenant/paths.js +1 -3
- package/dist/tenant/principals.d.ts +13 -13
- package/dist/tenant/principals.js +35 -36
- package/dist/tenant/run-token.js +6 -6
- package/dist/tenant/runtime.d.ts +5 -3
- package/dist/tenant/runtime.js +29 -15
- package/dist/tenant/sandboxes.d.ts +9 -6
- package/dist/tenant/sandboxes.js +16 -5
- package/dist/tenant/scheduler.d.ts +1 -5
- package/dist/tenant/scheduler.js +2 -5
- package/dist/tenant/session-streams.d.ts +8 -11
- package/dist/tenant/session-streams.js +48 -32
- package/dist/tenant/session.d.ts +8 -41
- package/dist/tenant/session.js +0 -37
- package/dist/tenant/sessions.d.ts +2 -2
- package/dist/tenant/sessions.js +17 -9
- package/dist/tenant/signing-keys.d.ts +3 -2
- package/dist/tenant/signing-keys.js +5 -5
- package/dist/tenant/skill-tool.d.ts +20 -0
- package/dist/tenant/skill-tool.js +72 -0
- package/dist/tenant/slim.d.ts +1 -1
- package/dist/tenant/slim.js +1 -1
- package/dist/tenant/status.js +7 -12
- package/dist/tenant/store-pg.d.ts +15 -0
- package/dist/tenant/store-pg.js +7 -3
- package/dist/tenant/streams.d.ts +3 -11
- package/dist/tenant/streams.js +2 -29
- package/dist/tenant/sweep.js +0 -5
- package/dist/tenant/transcript.d.ts +2 -2
- package/dist/tenant/transcript.js +2 -2
- package/dist/tenant/types.d.ts +33 -19
- package/dist/tenant/worker.d.ts +1 -3
- package/dist/tenant/worker.js +3 -8
- package/dist/vault/crypto.d.ts +7 -0
- package/dist/vault/crypto.js +16 -0
- package/dist/vault/oauth.d.ts +55 -0
- package/dist/vault/oauth.js +186 -0
- package/dist/vault/service.d.ts +54 -7
- package/dist/vault/service.js +261 -17
- package/dist/vault/sources.d.ts +60 -0
- package/dist/vault/sources.js +196 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -4
- package/dist/admin-openapi.json +0 -604
- package/dist/api/http/routes/actions.d.ts +0 -8
- package/dist/api/http/routes/actions.js +0 -76
- package/dist/api/http/routes/endpoints.d.ts +0 -7
- package/dist/api/http/routes/endpoints.js +0 -100
- package/dist/host/admin-api.d.ts +0 -23
- package/dist/host/admin-api.js +0 -74
- package/dist/host/cors.d.ts +0 -27
- package/dist/host/cors.js +0 -64
- package/dist/mcp/stdio.d.ts +0 -17
- package/dist/mcp/stdio.js +0 -82
- package/dist/tenant/access-policy.d.ts +0 -30
- package/dist/tenant/access-policy.js +0 -52
- package/dist/tenant/actions.d.ts +0 -14
- package/dist/tenant/actions.js +0 -29
- package/dist/tenant/browser.d.ts +0 -15
- package/dist/tenant/browser.js +0 -39
- package/dist/tenant/delivery-token.d.ts +0 -41
- package/dist/tenant/delivery-token.js +0 -104
- package/dist/tenant/delivery.d.ts +0 -62
- package/dist/tenant/delivery.js +0 -481
- package/dist/tenant/endpoints.d.ts +0 -67
- package/dist/tenant/endpoints.js +0 -90
- package/dist/tenant/subject-limits.d.ts +0 -16
- package/dist/tenant/subject-limits.js +0 -45
- package/dist/tenant/tokens.d.ts +0 -14
- package/dist/tenant/tokens.js +0 -187
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,212 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.0-beta
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 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.
|
|
8
|
+
|
|
9
|
+
- **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.
|
|
10
|
+
- **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`.
|
|
11
|
+
- **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.
|
|
12
|
+
- **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`.
|
|
13
|
+
- `@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.
|
|
14
|
+
|
|
15
|
+
- 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.
|
|
16
|
+
|
|
17
|
+
- **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`.
|
|
18
|
+
- **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.
|
|
19
|
+
- **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`.
|
|
20
|
+
- `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/`.
|
|
21
|
+
|
|
22
|
+
- 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".
|
|
23
|
+
|
|
24
|
+
- **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.
|
|
25
|
+
- **Breaking (`@nylorun/harness`):** held runs are gone: `createHarness` loses `holdMs`, and `apiHost` its `hold` option.
|
|
26
|
+
- **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`).
|
|
27
|
+
- **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.
|
|
28
|
+
- **Breaking (`@nylorun/cli`):** `nylo endpoints` is removed (a usage error that says why); `nylo status` shows uncertain effects instead of pending Actions.
|
|
29
|
+
- **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.
|
|
30
|
+
- `nylorun`: the local stack's comments speak of MCP servers and HTTP tools on this machine, not Action endpoints.
|
|
31
|
+
- `@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.
|
|
32
|
+
|
|
33
|
+
- 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.
|
|
34
|
+
|
|
35
|
+
- **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: …`.
|
|
36
|
+
- **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.
|
|
37
|
+
- **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.
|
|
38
|
+
- `@nylorun/runtime`: no `hook` Actions are offered or delivered.
|
|
39
|
+
- `@nylorun/studio`: the Agent Manifest tab drops the Hooks count and the turn lifecycle.
|
|
40
|
+
|
|
41
|
+
- 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.
|
|
42
|
+
|
|
43
|
+
- `@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").
|
|
44
|
+
- `@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.
|
|
45
|
+
- `@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.
|
|
46
|
+
- `@nylorun/harness`: tests only.
|
|
47
|
+
- `@nylorun/studio`: the agent's manifest lists each skill's files.
|
|
48
|
+
|
|
49
|
+
### Minor Changes
|
|
50
|
+
|
|
51
|
+
- 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.
|
|
52
|
+
|
|
53
|
+
- `@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.
|
|
54
|
+
- `@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.
|
|
55
|
+
- `@nylorun/agents`: `http()` builds HTTP verifiers too.
|
|
56
|
+
- `@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`.
|
|
57
|
+
- `@nylorun/studio`: the workflow tree shows HTTP stages and HTTP verifiers with their method and URL.
|
|
58
|
+
|
|
59
|
+
- 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.
|
|
60
|
+
|
|
61
|
+
- `@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.
|
|
62
|
+
- `@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`.
|
|
63
|
+
- `@nylorun/agents`: exports `http` and the identity header constants.
|
|
64
|
+
- `@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.
|
|
65
|
+
- `@nylorun/studio`: the Agent Manifest tab lists HTTP tools with their method and URL, and marks tools and MCP servers that wait for approval.
|
|
66
|
+
|
|
67
|
+
### Patch Changes
|
|
68
|
+
|
|
69
|
+
- Pin core to the tested release.
|
|
70
|
+
- Pin harness to the tested release.
|
|
71
|
+
- Updated dependencies [4bd2a0b]
|
|
72
|
+
- Updated dependencies [a64aaca]
|
|
73
|
+
- Updated dependencies [40b7648]
|
|
74
|
+
- Updated dependencies [713e676]
|
|
75
|
+
- Updated dependencies [c135267]
|
|
76
|
+
- Updated dependencies [d36f0d9]
|
|
77
|
+
- Updated dependencies [107b07d]
|
|
78
|
+
- Updated dependencies
|
|
79
|
+
- @nylorun/core@0.15.0-beta
|
|
80
|
+
- @nylorun/harness@0.23.0-beta
|
|
81
|
+
|
|
82
|
+
## 0.18.0-beta
|
|
83
|
+
|
|
84
|
+
### Major Changes
|
|
85
|
+
|
|
86
|
+
- 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.
|
|
87
|
+
|
|
88
|
+
- **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.
|
|
89
|
+
- **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.
|
|
90
|
+
- **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.
|
|
91
|
+
- **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`.
|
|
92
|
+
- `@nylorun/cli`: `nylo status` no longer falls back to the Admin API; when the Tenant does not answer it points to `npx nylorun status`.
|
|
93
|
+
|
|
94
|
+
- 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).
|
|
95
|
+
|
|
96
|
+
- **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`.
|
|
97
|
+
- **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`.
|
|
98
|
+
- **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.
|
|
99
|
+
- **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.
|
|
100
|
+
- `@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.
|
|
101
|
+
- `@nylorun/runtime`: `startEphemeralRuntime` registers a management key (`managementKey`, the key `bootstrap`).
|
|
102
|
+
|
|
103
|
+
### Minor Changes
|
|
104
|
+
|
|
105
|
+
- 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.
|
|
106
|
+
|
|
107
|
+
- `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.
|
|
108
|
+
- `@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`.
|
|
109
|
+
- `@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`.
|
|
110
|
+
- **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.
|
|
111
|
+
- `@nylorun/core`: `ProjectCredentialsFileSchema` gains optional `managementKey` and `managementPrincipalId`.
|
|
112
|
+
|
|
113
|
+
- 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.
|
|
114
|
+
|
|
115
|
+
- `@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.
|
|
116
|
+
- `@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.
|
|
117
|
+
- `@nylorun/core`: `KEY_ROLES`, `KeyRole`, `BOOTSTRAP_KEY_ID` and the error code `key_role_mismatch`.
|
|
118
|
+
|
|
119
|
+
- a6108f4: **The Management API's routes and client (Runtime and Management APIs, step A2).** Additive; the protocol stays at 7.
|
|
120
|
+
|
|
121
|
+
- `@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.
|
|
122
|
+
- `@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.
|
|
123
|
+
|
|
124
|
+
- 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.
|
|
125
|
+
- 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.
|
|
126
|
+
|
|
127
|
+
### Patch Changes
|
|
128
|
+
|
|
129
|
+
- 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.
|
|
130
|
+
- b28bdd7: **Local MCP servers work on a local Tenant, and a server that does not connect shows.** Additive; the protocol stays at 7.
|
|
131
|
+
|
|
132
|
+
- `@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.
|
|
133
|
+
- `@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`.
|
|
134
|
+
- `@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]`.
|
|
135
|
+
- `@nylorun/studio`: the event list labels `mcp.discovered` and summarizes each server's outcome.
|
|
136
|
+
|
|
137
|
+
- 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.
|
|
138
|
+
- Pin core to the tested release.
|
|
139
|
+
- Pin harness to the tested release.
|
|
140
|
+
- Updated dependencies [3b3bdc6]
|
|
141
|
+
- Updated dependencies [b387620]
|
|
142
|
+
- Updated dependencies [6576e12]
|
|
143
|
+
- Updated dependencies [b28bdd7]
|
|
144
|
+
- Updated dependencies [cc107b1]
|
|
145
|
+
- Updated dependencies [7f763c3]
|
|
146
|
+
- Updated dependencies [98b0d37]
|
|
147
|
+
- Updated dependencies [c66d8ed]
|
|
148
|
+
- Updated dependencies
|
|
149
|
+
- @nylorun/core@0.14.0-beta
|
|
150
|
+
- @nylorun/harness@0.22.2-beta
|
|
151
|
+
|
|
152
|
+
## 0.17.0-beta
|
|
153
|
+
|
|
154
|
+
### Major Changes
|
|
155
|
+
|
|
156
|
+
- bd478ee: **Subject tokens, browser keys and derived principals leave open source (F9 I3, protocol 7).** Upgrade these with the Runtime: they speak protocol 7, which this Runtime serves beside 4, 5 and 6; protocol 6 clients keep working on every route that remains. Browsers and apps present a trusted issuer's token (F9 I2), servers an operator key (F9 I1), and a person's own credentials come from the operator's credential resolver (F9 C1). See MIGRATION.md.
|
|
157
|
+
|
|
158
|
+
- **Breaking (`@nylorun/runtime`, `@nylorun/core`): subject tokens are gone.** `POST /v1/tokens`, `POST /v1/access/revocations`, subject-token verification, revocation epochs and the `subject.revoked` stream signal are removed; the routes answer `404`, and a JWT no trusted issuer signed is the opaque `404`. A stream opened with a token now ends only at its expiry (`event: nylorun.closed`, reason `token_expired`; `StreamClosedFrame` loses `revoked`). Migration `0010_oss_auth_removals` drops the `subject_epochs`, `subject_usage` and `publishable_keys` tables. The `token` caller is a trusted issuer's token only: it loses `role`, `limits` and `epoch`, and `issuer` is always set; `GET /v1/me` no longer reports `via: token`. Core drops `SUBJECT_TOKEN_TYPE`, `SUBJECT_TOKEN_AUDIENCE`, `subjectTokenIssuer` (the Runtime's own tokens use `tenantTokenIssuer`, same value), `CreateTokenRequest`/`Response`, `RevokeSubject*`, `SubjectTokenClaims`, `TOKEN_TTL_MIN_SECONDS` and `TOKEN_TTL_DEFAULT_SECONDS`; `TOKEN_SCOPES` is `agents:read`, `sessions:own`, `sandboxes:write`.
|
|
159
|
+
- **Breaking (`@nylorun/runtime`, `@nylorun/core`): the access policy and role limits are gone.** `GET`/`PUT /v1/access/policy` answer `404`, a turn is never refused with `429 limit_exceeded` for a role (limit requests at your proxy), and an existing `access.policy` setting is ignored. Core drops `AccessPolicy*`, `AccessRole*`, `RoleLimits*`, `DEFAULT_ACCESS_POLICY`, `PutAccessPolicyRequest` and `ROLE_NAME_PATTERN`.
|
|
160
|
+
- **Breaking (`@nylorun/runtime`, `@nylorun/core`): publishable keys and the Runtime's CORS are gone.** `/v1/access/publishable-keys*` answer `404`, `Nylorun-Key` is ignored, `NYLORUN_BROWSER_ACCESS` and `browserAccess` (host.json, `createHost`, `startEphemeralRuntime`) are removed, and the Runtime sends no CORS headers. A request with `Origin` reaches the Tenant routes of the public listener with no toggle: a trusted issuer's token is served, an application key or delivery token is `403 origin_rejected`; admin routes, `/health`, `/ready` and the operator listener still refuse `Origin`. Any `OPTIONS` request is `204` with `Allow` and no CORS header: the operator's proxy answers preflights. Route declarations lose `browser` (`x-nylorun-browser` leaves the OpenAPI document) and the `publishable` credential; the token security scheme is `issuerToken`. Core drops `PUBLISHABLE_KEY_HEADER`, `PUBLISHABLE_KEY_PATTERN`, `PUBLISHABLE_KEY_ID_PATTERN`, `tenantOfPublishableKey`, `newPublishableKey`, `newPublishableKeyId`, `PublishableKey*`, `OriginEntrySchema`, `originAllowed` and `LOOPBACK_ORIGIN_WILDCARDS`.
|
|
161
|
+
- **Breaking (`@nylorun/runtime`, `@nylorun/core`, `@nylorun/agents`): vault routes are application-only, and `vaults:own` is retired.** Every `/v1/vaults` route takes an application key acting for no one (operator keys, Studio); a request acting for a subject or a trusted issuer's token gets `403 scope_required`. `vaults:own` leaves `SUBJECT_SCOPES`, `TOKEN_SCOPES` and the issuer scopes; `Nylorun-Scopes` may still name it and it grants nothing. Existing user vaults stay attachable to their own owner's sessions. `client.createVault` takes `{ scope: "installation" }` or `ownerUserId`, and `client.listVaults()` takes an optional owner.
|
|
162
|
+
- **Breaking (`@nylorun/runtime`, `@nylorun/core`, `@nylorun/admin`, `nylorun`): derived principals are gone.** Only Studio's key is derived from the admin key. `NYLORUN_DERIVED_PRINCIPALS` is ignored and no longer written, `hostPrincipals` takes no `derived`, `startEphemeralRuntime` no `derivedPrincipals`, and `@nylorun/admin` drops `deriveTenantKey`, `PROJECT_PRINCIPAL_ID` and `admin.deriveTenantKey`. Keys an earlier Host derived stay in the database and keep working as ordinary keys; replace them with operator keys. Core renames `DERIVED_PRINCIPAL_ID_PATTERN` to `APPLICATION_KEY_ID_PATTERN`.
|
|
163
|
+
- **Breaking (`@nylorun/agents`):** `createTokenEndpoint`, `createBrowserClient` and the `@nylorun/agents/browser` entry, `client.tokens`, `TokensClient`, `PublishableKeysClient`, `client.access.getPolicy`/`putPolicy`/`revokeSubject`/`publishableKeys` and `Destination.publishableKey` are removed. `client.access.signingKeys` and `client.access.jwks()` stay, and `Destination.token` takes a trusted issuer's tokens.
|
|
164
|
+
- **Breaking (`@nylorun/cli`):** `nylo access policy|keys|revoke|token` are removed and name what replaces them; `nylo access signing-keys list|rotate|revoke` stays.
|
|
165
|
+
- **Breaking (`@nylorun/core`, `@nylorun/agents`, `@nylorun/studio`): the Studio embed message `open.babai` is now `open.session`** (`{ sessionId }`): it asks the embedding app to open that session in its own UI. Studio sends no such message itself.
|
|
166
|
+
- **Breaking (`nylorun`): Studio embedding is opt-in.** No origin may frame Studio by default; list your app's origins with `nylorun start --studio-embed-origin <origin>`. A Tenant's `.env` from an earlier nylorun keeps the origins it had until `--studio-embed-origin-reset`.
|
|
167
|
+
- `PROTOCOL_VERSION` is 7 and `HOST_PROTOCOL` 4–7; the Host features `subject-tokens`, `browser-access` and `derived-principals` are removed. `@nylorun/studio` and `@nylorun/create-agent` speak protocol 7.
|
|
168
|
+
|
|
169
|
+
### Minor Changes
|
|
170
|
+
|
|
171
|
+
- 8773586: **Installation vaults and a credential resolver (F9 C1).** A session's MCP credential now comes from its attached vaults, then from the operator's own credential resolver; nothing changes for existing vaults, and the protocol stays at 6.
|
|
172
|
+
|
|
173
|
+
- Installation vaults: `POST /v1/vaults` takes `scope: "installation"` (no `ownerUserId`) from an application key acting for no one; a request acting for a subject gets `403`. The vault is owned by `installation`, now a reserved subject like `host`. Any session may attach one and select its credentials. `GET /v1/vaults` from an application key lists them after the named person's vaults, and lists only them without `ownerUserId`; a request acting for a subject never sees one (the opaque `404`). The host model vault stays hidden and unattachable. Migration 0008 adds the scope.
|
|
174
|
+
- The credential resolver: `NYLORUN_RESOLVER_URL` and `NYLORUN_RESOLVER_TOKEN` on the gateway (`TenantConfig.resolver` and `startEphemeralRuntime({ resolver })` in process). When the session's vaults hold nothing for a remote MCP server's URL, the Runtime POSTs `{ owner, session, turn, target: { kind: "mcp", server, agent, url } }` with the resolver's bearer: `200 { headers, expiresAt? }` is used, `404` goes without a credential, and anything else or no answer within 5 s refuses the server with `credential_unavailable`. Owner and turn come from the session row. Answers are cached per owner and URL until `expiresAt`, at most 5 minutes (60 s without one), and concurrent misses share one request. See DEPLOYMENT.md, Credentials.
|
|
175
|
+
- `nylorun`: the gateway's Compose service passes `NYLORUN_RESOLVER_URL` and `NYLORUN_RESOLVER_TOKEN` from the shell that runs `nylorun start` (unset by default).
|
|
176
|
+
- Studio: the Vault page is now **Connections**, and creates installation vaults.
|
|
177
|
+
|
|
178
|
+
- e1bfb4b: **MCP OAuth connect for installation vaults (F9 C2).** The installation can sign in once to a remote MCP server that uses OAuth, and every session that attaches the vault uses the credential. Additive; the protocol stays at 6.
|
|
179
|
+
|
|
180
|
+
- `POST /v1/vaults/{vaultId}/oauth/start` (application keys acting for no one, installation vaults only) takes `{ url, server, clientId? }` and answers `{ authorizeUrl, expiresAt }`. The Runtime discovers the server's authorization server (RFC 9728, then RFC 8414), registers itself (RFC 7591) unless `clientId` names a registered client, and starts an S256 PKCE sign-in whose `state` works once, for ten minutes. A server without registration and no `clientId` is `400 oauth_client_required`.
|
|
181
|
+
- `GET /v1/oauth/callback` takes the browser back: anonymous and unversioned like an artifact link, it exchanges the code and stores an `oauth` credential bound to the URL, named after `server` (connecting again rotates it), and answers a small HTML page. An unknown, used or expired `state` is `oauth_state_invalid`; the authorization server's refusal is `oauth_failed`. The callback's base is `NYLORUN_PUBLIC_URL` (`TenantConfig.publicUrl`), else the start request's origin.
|
|
182
|
+
- Every OAuth step runs in the gateway's keys module (F9-D14): the runtime container never sees a token, the PKCE verifier or a client secret, and makes no outbound call. Migration 0009 adds `oauth_pending`, with the verifier and secret sealed under the vault key. `Keys` gains `startOAuth` and `finishOAuth`.
|
|
183
|
+
- OAuth requests, including refresh of every OAuth vault credential, now go through `guardedFetch` (`tenant/outbound.ts`): the `NYLORUN_ENDPOINT_*` address policy checked on the address connected to, no redirects, a bounded answer. With `NYLORUN_ENDPOINT_PRIVATE=refuse` a token endpoint on a private address is refused, where refresh used to call it.
|
|
184
|
+
- `@nylorun/core`: `ERROR_CODES` adds `oauth_client_required`, `oauth_state_invalid` and `oauth_failed`; `StartOAuthRequestSchema` and `StartOAuthResponseSchema`.
|
|
185
|
+
- `nylorun mcp connect <url> --server <name> [--vault <id>] [--client-id <id>]`: creates the installation vault `mcp` if needed, opens the sign-in page and waits up to 10 minutes for the credential. See DEPLOYMENT.md, "Connecting a remote MCP server with OAuth".
|
|
186
|
+
|
|
187
|
+
- 5cfaed9: **Operator keys, and project links on them (F9 I1).** The Admin API manages the Tenant's application keys by name: `PUT /v1/admin/keys/{id}` creates a key or rotates it and returns it once, `GET /v1/admin/keys` lists every key's id, role and issue time (never the keys), and `DELETE /v1/admin/keys/{id}` removes one. A rotated or deleted key stops authenticating on its next request. Ids follow `^[a-z][a-z0-9-]{0,31}$`; `studio` (derived from the admin key) is refused. Keys keep today's format (64 hex) and only their SHA-256 is stored, in the existing principals table (no migration). Host feature `operator-keys` (additive, protocol unchanged); core adds the `OperatorKey`, `ListOperatorKeysResponse`, `PutOperatorKeyResponse` and `DeleteOperatorKeyResponse` schemas.
|
|
188
|
+
|
|
189
|
+
- `@nylorun/admin`: `admin.keys.put(id)`, `admin.keys.list()` and `admin.keys.delete(id)`; they refuse with `incompatible_host` when the Host lacks `operator-keys`.
|
|
190
|
+
- `nylorun key put|list|rm <id>` manages a running local Tenant's keys; `put` prints the key once on stdout.
|
|
191
|
+
- `nylorun start` no longer derives the project's key. It keeps `.nylorun/credentials.json` while its key still reaches the Tenant (one authenticated read); otherwise it gives the project the operator key `project`, which the Host root keeps in `project-credentials.json` (0600) so every checkout linked to the Tenant shares it. An existing derived project key keeps working and is adopted.
|
|
192
|
+
- `nylorun sandbox` uses the linked project's key, or the operator key `cli` it puts once and keeps in `<Host root>/cli-credentials.json` (0600).
|
|
193
|
+
- The ephemeral Runtime (`startEphemeralRuntime`) no longer registers the derived `project` principal; pass `derivedPrincipals: ["project"]` to keep it. Derived principals (`NYLORUN_DERIVED_PRINCIPALS`, `deriveTenantKey`) still work on a Host.
|
|
194
|
+
|
|
195
|
+
- c0b604e: **Trusted issuers (F9 I2).** The Tenant API accepts JWTs from the operator's own identity provider as bearers, configured in an identity file: `NYLORUN_IDENTITY_FILE` names a YAML file listing each issuer's `name`, `issuer`, `audience`, `jwks` URL or static PEM `keys`, a `subject` template over scalar claims (`u:{sub}`), `scopes` from a claim or a fixed list, `allowedScopes`, an optional `agents` allowlist, optional `sandboxes` grant templates (`{org_id}/*`) and `maxLifetime`. A malformed file stops the boot, naming the issuer and the field; a subject template without a claim is malformed. A bearer whose unverified `iss` names an issuer is verified with RS256, ES256 or EdDSA only, up to 16 KiB, `aud` matching, `exp` and `iat` required and `exp − iat` within `maxLifetime`, and becomes a token caller (`role: issuer:<name>`) with the issuer's scopes, agents and rendered sandbox grants; subject revocation does not reach it. JWKS keys are fetched only from the configured URL (no redirects), cached by `kid`, refetched at most once a minute for an unknown `kid`; while a JWKS is unreachable cached keys keep working and a new `kid` is `401 issuer_unavailable` (new error code). A browser request with an issuer token needs no publishable key (CORS comes from the operator's proxy). New: `GET /v1/me` reports the subject, scopes, agents, sandbox grants and `via` (`application:<id>`, `subject`, `token` or `issuer:<name>`) of any credential; the issuer-only scope `studio`; `ISSUER_SCOPES`, `CALLER_SCOPES` and `MeResponseSchema` in `@nylorun/core/contracts`; `parseIdentityFile` and `createTrustedIssuers` in `@nylorun/runtime`, and an `issuers` option on `startEphemeralRuntime`; Host feature `trusted-issuers` (additive, protocol unchanged). `nylorun start` sets `NYLORUN_IDENTITY_FILE=/nylorun/identity.yaml` on the runtime container when `<Host root>/identity.yaml` exists.
|
|
196
|
+
|
|
197
|
+
### Patch Changes
|
|
198
|
+
|
|
199
|
+
- Pin core to the tested release.
|
|
200
|
+
- Pin harness to the tested release.
|
|
201
|
+
- Updated dependencies [8773586]
|
|
202
|
+
- Updated dependencies [e1bfb4b]
|
|
203
|
+
- Updated dependencies [5cfaed9]
|
|
204
|
+
- Updated dependencies [bd478ee]
|
|
205
|
+
- Updated dependencies [c0b604e]
|
|
206
|
+
- Updated dependencies
|
|
207
|
+
- @nylorun/core@0.13.0-beta
|
|
208
|
+
- @nylorun/harness@0.22.1-beta
|
|
209
|
+
|
|
3
210
|
## 0.16.0-beta
|
|
4
211
|
|
|
5
212
|
### 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.
|
|
6
|
-
|
|
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:
|
|
@@ -34,15 +36,17 @@ database, in the fixed schemas `nylorun` (its state: the Session Store) and
|
|
|
34
36
|
transaction under an advisory lock, records them in `nylorun.__drizzle_migrations`, and
|
|
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
|
-
new one), its name (`NYLORUN_TENANT_NAME`, default `default`)
|
|
38
|
-
the
|
|
39
|
-
|
|
39
|
+
new one), its name (`NYLORUN_TENANT_NAME`, default `default`) and its Studio principal,
|
|
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
|
|
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
|
|
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,13 +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
|
|
71
|
-
`
|
|
72
|
-
|
|
73
|
-
|
|
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
|
|
77
|
+
(Host feature `trusted-issuers`), read once at boot; a malformed file stops the
|
|
78
|
+
boot ([DEPLOYMENT.md](../DEPLOYMENT.md#trusted-issuers)). A process that runs `loop` sends its model
|
|
74
79
|
calls to the gate at `NYLORUN_GATES_URL`; in a container it refuses to start
|
|
75
80
|
without it and `NYLORUN_GATES_TOKEN`. That token is core's credential: the gate
|
|
76
|
-
accepts only it for vault writes
|
|
81
|
+
accepts only it for vault writes and token signing. Model, HTTP tool and
|
|
77
82
|
remote MCP calls carry a run token instead, which the loop mints for each
|
|
78
83
|
session it advances, and the gate takes the call's session, turn and agent from
|
|
79
84
|
it; a token whose turn was cancelled or whose session another process took over
|
|
@@ -81,19 +86,36 @@ is refused with `409 run_stale`. A `gates` process needs only
|
|
|
81
86
|
`NYLORUN_DATABASE_URL`, `NYLORUN_GATES_TOKEN`, its listener
|
|
82
87
|
(`NYLORUN_GATES_LISTEN_HOST`, `NYLORUN_GATES_LISTEN_PORT`, default 4100, and
|
|
83
88
|
`NYLORUN_GATES_ALLOWED_HOSTS`) and the Host's `tenant/` directory, which it
|
|
84
|
-
never writes; it serves the database's one Tenant.
|
|
89
|
+
never writes; it serves the database's one Tenant. `NYLORUN_RESOLVER_URL` and
|
|
90
|
+
`NYLORUN_RESOLVER_TOKEN` (both or neither, gates only) name the operator's
|
|
91
|
+
credential resolver, which the gate asks for a person's MCP credential when the
|
|
92
|
+
session's vaults hold none ([DEPLOYMENT.md](../DEPLOYMENT.md#credentials)); an
|
|
93
|
+
embedding or `startEphemeralRuntime` takes `resolver: { url, token }` instead. With `egress`
|
|
85
94
|
(`--service gates,keys,egress`, for pod sandboxes) the same process runs
|
|
86
95
|
egress-gate on `NYLORUN_EGRESS_LISTEN_HOST`:`NYLORUN_EGRESS_LISTEN_PORT`
|
|
87
96
|
(default `0.0.0.0:4200`): a CONNECT proxy that admits a pod's egress token and
|
|
88
97
|
tunnels only to the hosts its sandbox spec allows, on 443 or 80, never to a
|
|
89
98
|
private address. `NYLORUN_PACKING` (`combined` or `split`) is logged at startup.
|
|
90
99
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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.
|
|
97
119
|
|
|
98
120
|
The Host root is `NYLORUN_HOME` or `~/.nylorun` (for a local Tenant,
|
|
99
121
|
`~/.nylorun/tenants/<name>/`, bind-mounted at `/nylorun` in its containers). What stays on the Host is under `tenant/`.
|
|
@@ -102,10 +124,11 @@ The Host root is `NYLORUN_HOME` or `~/.nylorun` (for a local Tenant,
|
|
|
102
124
|
|
|
103
125
|
```text
|
|
104
126
|
<host root>/
|
|
105
|
-
host.json # format 1: hostId, host, port,
|
|
106
|
-
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
|
|
129
|
+
identity.yaml # optional: trusted issuers (NYLORUN_IDENTITY_FILE)
|
|
107
130
|
docker/ # compose.yaml, .env (0600), Restate identity key
|
|
108
|
-
tenant/ #
|
|
131
|
+
tenant/ # logs, home, sandboxes
|
|
109
132
|
```
|
|
110
133
|
|
|
111
134
|
## HTTP surface
|
|
@@ -113,29 +136,32 @@ The Host root is `NYLORUN_HOME` or `~/.nylorun` (for a local Tenant,
|
|
|
113
136
|
| Route | Auth | Notes |
|
|
114
137
|
| --- | --- | --- |
|
|
115
138
|
| `GET /health` | none | `service: "nylorun-runtime"`, `hostId`, protocol `{min,max,features}`, pid |
|
|
116
|
-
| `GET /ready` | none | Listener up, the Tenant open, and Postgres, Restate and S2 answer (`checks`) |
|
|
117
|
-
| `GET /openapi.json` | none | The
|
|
118
|
-
| `GET /
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
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` |
|
|
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 |
|
|
122
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 |
|
|
123
148
|
|
|
124
149
|
Every route checks `Host` first (`421 host_rejected`) and rejects non-JSON bodies
|
|
125
150
|
with `415 unsupported_media_type`, except an artifact upload (`POST /v1/artifacts`,
|
|
126
151
|
`POST /v1/artifacts/{id}/versions`), whose body is the file in any media type. An `Origin` is `403 origin_rejected` on
|
|
127
|
-
`/health`, `/ready
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
|
155
|
+
`OPTIONS` with `204` and `Allow` only: the operator's reverse proxy answers preflights
|
|
156
|
+
([DEPLOYMENT.md](../DEPLOYMENT.md#calling-the-runtime-from-browsers-and-apps)). Missing or
|
|
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
|
|
160
|
+
derived principals, whose routes answer `404`; protocol 6 adds file and folder artifacts and message `parts`; at each turn's end the
|
|
135
161
|
Runtime exports `/workspace/outputs` of the session's sandbox as a version of its
|
|
136
162
|
`outputs` folder, read at `/v1/artifacts/{id}/versions/{n|latest}/tree`, `/files/{path}`,
|
|
137
|
-
`/diff?from=` and `/zip`). Protocol 5 and
|
|
138
|
-
another Tenant (or malformed), a
|
|
163
|
+
`/diff?from=` and `/zip`). Protocol 5 and later clients name no Tenant. A protocol 4 client's `Nylorun-Tenant` naming
|
|
164
|
+
another Tenant (or malformed), a Tenant that
|
|
139
165
|
could not be opened and rejected credentials → opaque `404` with identical body. A path or method no route serves is `404 Route not found`
|
|
140
166
|
once the caller is known.
|
|
141
167
|
|
|
@@ -144,39 +170,45 @@ once the caller is known.
|
|
|
144
170
|
The Runtime describes its APIs as OpenAPI 3.2 documents, generated from the routes it serves,
|
|
145
171
|
so they cannot drift from its answers:
|
|
146
172
|
|
|
147
|
-
| Document | In the package | Served | On each release |
|
|
173
|
+
| Document | In the package | Served (no key) | On each release |
|
|
148
174
|
| --- | --- | --- | --- |
|
|
149
|
-
|
|
|
150
|
-
|
|
|
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` |
|
|
151
177
|
|
|
152
178
|
The release assets are on the `@nylorun/runtime@<version>` GitHub Release. Point any OpenAPI 3.2
|
|
153
179
|
tool at one of them; for [Scalar](https://scalar.com), the package file of a version works as is:
|
|
154
180
|
|
|
155
181
|
```text
|
|
156
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
|
|
157
184
|
```
|
|
158
185
|
|
|
159
|
-
Each
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
186
|
+
Each document has described tags, in the order a developer uses them. The Runtime API's are
|
|
187
|
+
grouped (`x-tagGroups`): Get started (Runtime), Agents (Agents, Definition files),
|
|
188
|
+
Sessions (Sessions API, AG-UI, A2A) and Sandboxes & artifacts. The Management API's are
|
|
189
|
+
Tenant, Application keys, Models, Vaults, Signing keys and Settings. Each operation's
|
|
190
|
+
`security` says which credentials it takes (application key and trusted issuer's token in
|
|
191
|
+
the Runtime API; management key in the Management API), and its
|
|
192
|
+
`x-nylorun-credentials` and `x-nylorun-scopes` (the subject scopes that reach it) fields say
|
|
193
|
+
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
|
|
163
194
|
them (`node scripts/build-openapi.mjs --write`), and `check-package` fails until they are
|
|
164
195
|
updated.
|
|
165
196
|
|
|
166
197
|
## HTTP layer
|
|
167
198
|
|
|
168
199
|
Routes are Hono routes (`@hono/zod-openapi`), each declared once with who may call it
|
|
169
|
-
(`api/http/define.ts`): that declaration serves the route, checks subject scopes
|
|
170
|
-
|
|
171
|
-
check (in Node, before Hono) and the Host pipeline (`host/app.ts`); `api/` the
|
|
172
|
-
|
|
173
|
-
|
|
200
|
+
(`api/http/define.ts`): that declaration serves the route, checks subject scopes and makes
|
|
201
|
+
the OpenAPI document. `host/` holds the listeners, the `Host`
|
|
202
|
+
check (in Node, before Hono) and the Host pipeline (`host/app.ts`); `api/` the routes of
|
|
203
|
+
both APIs (`api/http/routes/`, `api/ag-ui/`, `api/a2a/`). Only `host/` and `api/` import
|
|
204
|
+
Hono. `nylorun-operate` is `host/operate.ts`.
|
|
174
205
|
|
|
175
206
|
## Embedding and tests
|
|
176
207
|
|
|
177
208
|
Tests and ephemeral embeds use `startEphemeralRuntime()` from
|
|
178
209
|
`@nylorun/runtime/core`: private Host on port 0, temporary Host root, one Tenant,
|
|
179
|
-
returns `{ url, tenantId, applicationKey, adminKey, close() }
|
|
210
|
+
returns `{ url, tenantId, applicationKey, managementKey, adminKey, close() }`
|
|
211
|
+
(`managementKey` is the key `bootstrap`, for the Management API). Its Tenant is the
|
|
180
212
|
one Tenant of the Postgres database you pass as `database` (required): a pool, which
|
|
181
213
|
you end, or a URL, for which it opens a pool and ends it on `close()`. It creates the
|
|
182
214
|
Tenant there on first start, as a Host does (with `tenantId`, `name` and an application
|
|
@@ -198,10 +230,11 @@ The package's own tests run every Session Store on Postgres: `npm test` gives ea
|
|
|
198
230
|
test file a database on the Docker test stack (`test/stack/compose.yaml`) and starts
|
|
199
231
|
the stack when it is down; see [CONTRIBUTING.md](../CONTRIBUTING.md).
|
|
200
232
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
233
|
+
Save agents with `PUT /v1/agents/{agentId}` using the application principal (`saveAgent`
|
|
234
|
+
in `@nylorun/agents`). The Runtime runs the agent from its manifest and never calls your
|
|
235
|
+
code during a session: a definition with a tool that would (`tool({ run })`, a flow's tool
|
|
236
|
+
stage) is refused. Your services are reached as tools: HTTP tools, POSTed from the Runtime,
|
|
237
|
+
so their URLs must be reachable from it, and remote MCP servers. Model gateway
|
|
205
238
|
and sandbox backend are Tenant configuration (vault / seed), not Host process
|
|
206
239
|
env.
|
|
207
240
|
|
|
@@ -209,12 +242,10 @@ env.
|
|
|
209
242
|
|
|
210
243
|
The session-first `/v1` API is specified in
|
|
211
244
|
[HOST_CONTRACT.md](../harness/HOST_CONTRACT.md). Application tokens authorize
|
|
212
|
-
definition/session APIs.
|
|
213
|
-
delivery token authorizes only its own Action's heartbeat, result and sandbox calls.
|
|
214
|
-
Session observers cannot submit action results.
|
|
245
|
+
definition/session APIs.
|
|
215
246
|
|
|
216
247
|
Postgres transactions persist session checkpoints, command receipts, individual
|
|
217
|
-
effects
|
|
248
|
+
effects, waits and the record of session events — in the Tenant's database; history is
|
|
218
249
|
read from Durable Streams (S2). An advance owns its session through a lease with
|
|
219
250
|
an epoch; a Worker that takes over after a crash marks in-flight effects
|
|
220
251
|
`uncertain`. Vault ciphertext needs that Tenant's own KEK.
|
|
@@ -234,14 +265,25 @@ the Project link (outside a project it runs the Tenant `default`); the project's
|
|
|
234
265
|
| Symptom | What to do |
|
|
235
266
|
| --- | --- |
|
|
236
267
|
| `kek-missing` | Restore `vault-kek` in the Tenant directory |
|
|
237
|
-
| `GET /ready` is 503
|
|
268
|
+
| `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 |
|
|
238
269
|
| `corrupt` / `migration-failed` / `envelope-invalid` / `open-failed` / `open-timeout` | Follow the cause's `repair` string |
|
|
239
270
|
| `schema-too-new` | Run a Runtime at least as new as the one that migrated the database |
|
|
240
271
|
| `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 |
|
|
241
272
|
| `426 protocol_unsupported` | Upgrade clients or Host to a compatible set |
|
|
242
|
-
| `421 host_rejected` / `403 origin_rejected` | In a container, list the `Host` in `NYLORUN_ALLOWED_HOSTS`. From a browser,
|
|
273
|
+
| `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 |
|
|
274
|
+
| `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`) |
|
|
243
275
|
| `503` for a Tenant | Postgres or Restate is unreachable; `GET /ready` names which |
|
|
244
276
|
| Port in use | Change `NYLORUN_PORT` in `~/.nylorun/tenants/<name>/docker/.env` and run `nylorun start` |
|
|
245
277
|
| Logs | `nylorun logs runtime` |
|
|
246
278
|
|
|
247
279
|
Definitions have no `agent.run()`; applications use `@nylorun/agents`.
|
|
280
|
+
|
|
281
|
+
## Session reads
|
|
282
|
+
|
|
283
|
+
Hosts advertising `session-reads` serve pinned session manifests, recorded usage, model-call
|
|
284
|
+
pages and opt-in session/history/sandbox pagination. `calls-export` adds the Management API's
|
|
285
|
+
unfiltered, resumable model ledger export (`GET /v1/tenant/calls/model`, a management key) in
|
|
286
|
+
safe transaction order. Existing list/history
|
|
287
|
+
requests without `limit` retain their response shapes. These are public APIs for Studio,
|
|
288
|
+
CLI and custom clients; clients never need database access. See the
|
|
289
|
+
[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 `
|
|
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. */
|