@nylorun/runtime 0.19.1-beta → 0.21.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.
Files changed (137) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +22 -13
  3. package/dist/adapters/streams/s2.js +5 -11
  4. package/dist/api/components.d.ts +326 -205
  5. package/dist/api/components.js +3 -3
  6. package/dist/api/http/app.js +2 -0
  7. package/dist/api/http/define.d.ts +3 -2
  8. package/dist/api/http/define.js +10 -11
  9. package/dist/api/http/routes/mcp.d.ts +9 -0
  10. package/dist/api/http/routes/mcp.js +32 -0
  11. package/dist/api/http/routes/vaults.d.ts +1 -9
  12. package/dist/api/http/routes/vaults.js +3 -103
  13. package/dist/api/openapi.js +37 -6
  14. package/dist/artifacts/media-types.d.ts +2 -0
  15. package/dist/artifacts/media-types.js +5 -0
  16. package/dist/execution/types.d.ts +1 -1
  17. package/dist/gates/http-tool.d.ts +7 -0
  18. package/dist/gates/http-tool.js +34 -3
  19. package/dist/gates/mcp-handler.d.ts +4 -1
  20. package/dist/gates/mcp-handler.js +64 -8
  21. package/dist/gates/tenant-vaults.d.ts +9 -15
  22. package/dist/gates/tenant-vaults.js +9 -17
  23. package/dist/gates/tool-client.js +36 -17
  24. package/dist/gates/tool-contract.d.ts +19 -3
  25. package/dist/gates/tool-contract.js +9 -3
  26. package/dist/gates/tool-gate.d.ts +2 -2
  27. package/dist/harness/calls.d.ts +2 -0
  28. package/dist/harness/calls.js +13 -3
  29. package/dist/harness-api/record.d.ts +7 -6
  30. package/dist/harness-api/record.js +99 -17
  31. package/dist/harness-api/server.js +35 -27
  32. package/dist/harness-api/start.js +2 -1
  33. package/dist/host/app.d.ts +3 -0
  34. package/dist/host/app.js +33 -4
  35. package/dist/host/config-for.d.ts +0 -2
  36. package/dist/host/config-for.js +0 -1
  37. package/dist/host/create-host.d.ts +6 -0
  38. package/dist/host/create-host.js +1 -0
  39. package/dist/host/gates.js +0 -1
  40. package/dist/host/main.js +24 -7
  41. package/dist/host/stack-config.d.ts +5 -8
  42. package/dist/host/stack-config.js +9 -20
  43. package/dist/index.d.ts +0 -1
  44. package/dist/infra/index.d.ts +2 -1
  45. package/dist/infra/index.js +0 -1
  46. package/dist/infra/readiness.d.ts +6 -6
  47. package/dist/infra/readiness.js +2 -5
  48. package/dist/keys/client.js +1 -9
  49. package/dist/keys/keys.d.ts +11 -13
  50. package/dist/keys/keys.js +5 -7
  51. package/dist/management-openapi.json +671 -378
  52. package/dist/mcp/connect.d.ts +159 -13
  53. package/dist/mcp/connect.js +538 -55
  54. package/dist/mcp/pool.d.ts +11 -2
  55. package/dist/mcp/pool.js +74 -27
  56. package/dist/mcp/preview.d.ts +35 -0
  57. package/dist/mcp/preview.js +215 -0
  58. package/dist/mcp/snapshot.d.ts +79 -5
  59. package/dist/mcp/snapshot.js +145 -27
  60. package/dist/model/catalog.d.ts +14 -0
  61. package/dist/model/catalog.js +14 -1
  62. package/dist/model/pi-model.js +36 -2
  63. package/dist/openapi.json +644 -266
  64. package/dist/redact.d.ts +19 -1
  65. package/dist/redact.js +42 -13
  66. package/dist/sandbox/session-sandbox.d.ts +7 -0
  67. package/dist/sandbox/session-sandbox.js +89 -28
  68. package/dist/store/postgres/connect.d.ts +10 -0
  69. package/dist/store/postgres/connect.js +30 -3
  70. package/dist/store/postgres/control.d.ts +14 -0
  71. package/dist/store/postgres/control.js +187 -0
  72. package/dist/store/postgres/drizzle/0015_control_signals.sql +11 -0
  73. package/dist/store/postgres/drizzle/0016_mcp_oauth_removed.sql +5 -0
  74. package/dist/store/postgres/drizzle/meta/_journal.json +14 -0
  75. package/dist/store/postgres/schema.d.ts +122 -261
  76. package/dist/store/postgres/schema.js +22 -36
  77. package/dist/store/postgres/store.js +16 -18
  78. package/dist/store/postgres/tenant.d.ts +14 -0
  79. package/dist/store/postgres/tenant.js +22 -2
  80. package/dist/store/types.d.ts +42 -8
  81. package/dist/streams/types.d.ts +6 -29
  82. package/dist/streams/types.js +5 -4
  83. package/dist/tenant/artifact-tool.d.ts +9 -1
  84. package/dist/tenant/artifact-tool.js +113 -9
  85. package/dist/tenant/auth.d.ts +16 -6
  86. package/dist/tenant/auth.js +41 -17
  87. package/dist/tenant/commands.js +10 -6
  88. package/dist/tenant/context.d.ts +9 -6
  89. package/dist/tenant/control.d.ts +26 -0
  90. package/dist/tenant/control.js +35 -0
  91. package/dist/tenant/effects.d.ts +2 -2
  92. package/dist/tenant/effects.js +20 -5
  93. package/dist/tenant/ephemeral.d.ts +0 -6
  94. package/dist/tenant/ephemeral.js +1 -1
  95. package/dist/tenant/http.d.ts +4 -2
  96. package/dist/tenant/http.js +4 -2
  97. package/dist/tenant/identity-file.d.ts +16 -12
  98. package/dist/tenant/identity-file.js +41 -29
  99. package/dist/tenant/issuers.d.ts +4 -3
  100. package/dist/tenant/issuers.js +22 -16
  101. package/dist/tenant/outbound.d.ts +14 -5
  102. package/dist/tenant/outbound.js +21 -9
  103. package/dist/tenant/reset.d.ts +2 -2
  104. package/dist/tenant/reset.js +8 -2
  105. package/dist/tenant/resource-server.d.ts +56 -0
  106. package/dist/tenant/resource-server.js +62 -0
  107. package/dist/tenant/runtime.d.ts +1 -1
  108. package/dist/tenant/runtime.js +16 -15
  109. package/dist/tenant/scheduler.d.ts +1 -1
  110. package/dist/tenant/scheduler.js +1 -1
  111. package/dist/tenant/sessions.js +20 -3
  112. package/dist/tenant/store-pg.js +9 -0
  113. package/dist/tenant/streams.d.ts +16 -22
  114. package/dist/tenant/streams.js +7 -87
  115. package/dist/tenant/sweep.js +9 -1
  116. package/dist/tenant/tool-results.d.ts +57 -0
  117. package/dist/tenant/tool-results.js +298 -0
  118. package/dist/tenant/tool-search.d.ts +43 -0
  119. package/dist/tenant/tool-search.js +100 -0
  120. package/dist/tenant/transcript.d.ts +108 -0
  121. package/dist/tenant/transcript.js +13 -0
  122. package/dist/tenant/types.d.ts +0 -14
  123. package/dist/vault/crypto.d.ts +0 -7
  124. package/dist/vault/crypto.js +0 -16
  125. package/dist/vault/headers.d.ts +17 -0
  126. package/dist/vault/headers.js +61 -0
  127. package/dist/vault/service.d.ts +11 -68
  128. package/dist/vault/service.js +83 -438
  129. package/dist/vault/sources.d.ts +20 -48
  130. package/dist/vault/sources.js +25 -189
  131. package/dist/version.d.ts +1 -1
  132. package/dist/version.js +1 -1
  133. package/package.json +3 -3
  134. package/dist/streams/control.d.ts +0 -13
  135. package/dist/streams/control.js +0 -25
  136. package/dist/vault/oauth.d.ts +0 -55
  137. package/dist/vault/oauth.js +0 -186
package/CHANGELOG.md CHANGED
@@ -1,5 +1,95 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.21.0-beta
4
+
5
+ ### Major Changes
6
+
7
+ - 50e2f7e: **Protocol 10: MCP credentials come from a session's vaults only.** Nylorun no longer signs the installation in to MCP servers with OAuth and no longer asks a credential resolver. Upgrade every package together; MIGRATION.md has the details.
8
+
9
+ - **Breaking (`@nylorun/runtime`): the MCP OAuth connect is gone.** `POST /v1/tenant/vaults/{vaultId}/oauth/start` and `GET /v1/oauth/callback` answer `404`. The vault credential type `oauth` and its refresh are gone: a credential is a `bearer` token or a `headers` map bound to a URL. Migration `0016_mcp_oauth_removed` drops the table of pending connects and deletes every `oauth` credential, writing one audit row each (actor `migration`); the Runtime logs `oauth_credential_removed` once for each, naming its vault, id and URL.
10
+ - **Breaking (`@nylorun/runtime`): the credential resolver is gone.** The gateway no longer asks the operator's resolver for a person's credential when the session's vaults hold none. A process that still sets a `NYLORUN_RESOLVER_*` variable logs `resolver_removed` and ignores it. Keep a person's own keys in their user vault and attach it to their sessions (`vaultIds`). `TenantConfig.resolver`, `TenantConfig.publicUrl`, `TenantConfig.vaultFetch`, `startEphemeralRuntime({ resolver })`, the `ResolverConfig` export and `VaultService`'s `fetch` option are removed; `NYLORUN_PUBLIC_URL` still sets the protected resource metadata's `resource`.
11
+ - **Breaking (`@nylorun/core`):** `PROTOCOL_VERSION` is 10 and `HOST_PROTOCOL` 4–10. `StartOAuthRequest`, `StartOAuthResponse`, the `oauth` variants of `CreateCredentialRequest` and `RotateCredentialRequest`, `oauth` in `CredentialInfo.type` and `CredentialInfo.expiresAt` are removed, and `ERROR_CODES` drops `oauth_client_required`, `oauth_state_invalid` and `oauth_failed`. `@nylorun/agents` and `@nylorun/cli` send protocol 10.
12
+ - **Breaking (`@nylorun/admin`):** `admin.vaults` loses its OAuth start method.
13
+ - **Breaking (`nylorun`):** the `connect` subcommand of `nylorun mcp` is removed (`nylorun mcp inspect` lists a server's tools instead), and the gateway's Compose service no longer passes the `NYLORUN_RESOLVER_*` variables.
14
+ - `@nylorun/studio`: the Credentials page loses the OAuth type, the Expires column and the OAuth connect hint.
15
+
16
+ ### Minor Changes
17
+
18
+ - e0e39ff: **Header map, gateway and identity header credentials; `credential_rejected` on a `401`** (R2b C1, C2). For remote MCP servers and HTTP tools alike, in installation and user vaults. MIGRATION.md (protocol 10, "Header and gateway credentials" and "Tool errors the model sees") has the details.
19
+
20
+ - `@nylorun/core`: `CreateCredentialRequest` and `RotateCredentialRequest` gain `type: "headers"` with a `headers` map, and optional `via` (where requests go, such as a gateway: `https`, or `http` to a loopback host, with no userinfo, query string or fragment) and `identity: { header }` on both kinds; a rotation may change them, and `null` removes one. `CredentialInfo` gains `headers` in its type, `headerNames`, `via` and `identity`, never a value. `ERROR_CODES` gains `credential_rejected`, and `tool.completed`'s `error` documents `server` and `vault`. The admin client's vault methods take the new bodies through these types.
21
+ - `@nylorun/runtime`: a `headers` credential is sealed like a token and sends every header in its map; the transport's headers, `Idempotency-Key` and `Nylorun-*` are refused (`400`), and a credential header replaces a manifest header of the same name. A credential with `via` sends the server's requests there, while the manifest's URL still picks the credential and names the tools. An identity header carries the session owner's subject from the session record, and is left out for a session owned by `installation`. A `401` from an MCP server or HTTP tool is a failed tool call with code `credential_rejected` that the model sees, never retried and never `uncertain`. `via`, `identity` and the header names are stored unsealed in the credential's binding: no migration.
22
+ - `@nylorun/studio`: the Credentials page adds Bearer or Headers credentials (name and value rows), with an optional gateway URL and identity header, and shows them without values.
23
+
24
+ - 18f9a2f: **Model-safe MCP tool names, coded MCP tool errors and credential scrubbing** (R2b C6, C7, C8). MIGRATION.md (protocol 10, "Tool and MCP server names" and "Tool errors the model sees") has the details.
25
+
26
+ - `@nylorun/core`: a declared tool's name and an MCP server's name must match `^[A-Za-z0-9_-]{1,64}$` (`AgentManifestSchema`, so `PUT /v1/agents/{id}` refuses others). `mcp.discovered`'s server outcomes gain `renamed: [{ serverToolName, name }]`; `tool.completed` gains `redacted` and its `error` gains `retryable`. A failed `ToolOutcome` and `ToolResult` may carry `retryable`.
27
+ - `@nylorun/harness`: a failed tool result keeps the outcome's `retryable`, and the model sees it beside `code` and `message`.
28
+ - `@nylorun/runtime`: the model knows an MCP tool by `server__tool` with characters outside `[A-Za-z0-9_-]` replaced by `_`, shortened to 64 with an 8-hex SHA-256 suffix (also given to a renamed tool that collides); the server is still called by its own name. A failed MCP tool call is a failed tool result the model sees, with code `mcp.unreachable` (never sent; retryable), `credential_rejected` (`401`), `mcp.forbidden` (`403`), `mcp.error` (a JSON-RPC error) or `mcp.status` (another HTTP status); a call whose answer was lost after it was sent is `mcp.lost` for a `readOnlyHint` or `idempotentHint` tool and stays `uncertain` otherwise, as does a call lost with a gateway restart. A pooled connection whose server ended its session (`404` to its `Mcp-Session-Id`) or whose credential's `via` moved is dropped, opened again, and the call sent once more, since the tool never saw it. The credential values sent on a call (at least 8 characters, and a `Bearer` value's token) are replaced with `[redacted]` in MCP and HTTP tool results and errors before the gate records or returns them; no other field is touched.
29
+
30
+ - da93711: **Preview an MCP server's tools** (R2b C12). MIGRATION.md (protocol 10, "Previewing a server's tools") has the details.
31
+
32
+ - `@nylorun/core`: `McpPreviewRequestSchema` and `McpPreviewSchema` (`McpPreviewTool`), and the error code `mcp_preview_failed`.
33
+ - `@nylorun/runtime`: `POST /v1/tenant/mcp/preview` (the Management API) connects to a remote MCP server with the installation vault's credential for its URL (headers and `via`, no identity header), under the Host's address policy and within 15 s, and answers its server info, instructions, tools (model names, annotations, schema sizes) and renames; a `401` is `authRequired`, with the server's RFC 9728 protected-resource metadata. It runs in the keys service (`Keys.previewMcp`), which holds the plaintext, and calls no tool. Both OpenAPI documents list it.
34
+ - `@nylorun/admin`: `admin.mcp.preview({ url, type?, name?, vaultId? })`.
35
+ - `nylorun`: `nylorun mcp inspect <url> [--server <name>] [--vault <id>] [--sse] [--json]` prints the running Tenant's preview: a table of tools, the renames, or that the server needs a person's sign-in. Its `connect` subcommand still says it was removed, and now points to `inspect`.
36
+ - `@nylorun/studio`: **Preview tools** on each credential of the Credentials page lists the tools behind its URL.
37
+
38
+ - 90a817d: **MCP and HTTP tool results that fit** (R2b C11). MIGRATION.md (protocol 10, "Tool results that fit") has the details.
39
+
40
+ - `@nylorun/core`: a completed `ToolOutcome` may carry `files` (`ToolResultFile`: a media type and the host's reference) and `truncated`; a completed `ToolResult` carries the `files`. `artifactsCapabilityManifest({ save, read })` adds the built-in `read_artifact` (`READ_ARTIFACT_TOOL`, `READ_ARTIFACT_MAX_BYTES`), and `codeToolsOf` leaves it alone. `SessionView` gains `definitionHash`, the definition the session was opened from. Transcript edits are split at 48 KiB, down from 256 KiB, so each `transcript.updated` event stays under 64 KiB when no entry is larger.
41
+ - `@nylorun/harness`: a tool result's files go to the model after its output, as media parts; an outcome marked `truncated` is not checked against the tool's output schema.
42
+ - `@nylorun/runtime`: an agent's remote MCP or HTTP tool result past 32 KiB is stored as a file artifact of the session, and the model gets `{ truncated: true, artifactId, size, preview }` (the first 4 KiB and the last 1 KiB). Image, audio and blob resource parts become artifacts too, an image also shown to a model that reads images (a note for one that does not); each part of a mixed result is shaped alone, and a `resource_link` stays a link. One step's results share a 256 KiB budget, so many parallel results never make an event near S2's 1 MiB record: past it, a result is a stub naming its artifact. When an artifact cannot be stored, the preview stays and `dropped` says why. An MCP answer past 8 MiB is `mcp.too-large`. `read_artifact { artifactId, offset?, length? }` reads 32 KiB of the session's own artifact a call, with or without a sandbox: a session gets it for each agent with an MCP server or an HTTP tool. The session view names its `definitionHash`.
43
+ - `@nylorun/studio`: a session is shown as running an older manifest only when the definition it was opened from is not the registered one, not because the Runtime pinned its own tools (a sandbox's, `save_artifact`, `read_artifact`) beside it.
44
+
45
+ - b8d10cb: **Per-tool MCP settings (manifest v6) and deferred tools** (R2b C9, C10). MIGRATION.md (protocol 10, "Per-tool settings and manifest v6" and "Deferred tools") has the details.
46
+
47
+ - `@nylorun/core`: an MCP server takes `tools` (`McpToolSettings` by the server's own tool name, `"*"` for the rest: `enabled`, `approval`, `deferred`) and `deferred`, in manifest v6. `mcp()` and `Agent.mcp()` accept them, and the builder writes v6 only for a manifest that uses them, so other manifests keep their hashes; `AgentManifestSchema` accepts v5 unchanged and refuses the fields in v5. `mcpToolSettings` resolves a tool's settings, `manifestVersionFor` says which version a definition needs. `isVariantOf` lets a turn variant disable an MCP tool or require its approval, and nothing else. `TOOLS_CAPABILITY_ID`, `TOOL_SEARCH_TOOL`, `TOOL_CALL_TOOL`, `deferredToolsTools` and `deferredToolsInstructions` describe `tool_search` and `tool_call`. A session tool may carry instructions, read with its capability's. `mcp.discovered` gains `deferred`, `disabled` and `unknownTools` per server.
48
+ - `@nylorun/harness`: a session tool marked `deferred` stays out of the model's tool list; `tool_call` runs it as its own call, after checking the arguments against its `inputSchema`, and asks for approval when it needs it.
49
+ - `@nylorun/runtime`: discovery leaves out the tools a server's settings disable and names keys that match no tool. A session of an agent with a remote MCP server pins an empty `nylorun.tools` capability; when the agent's MCP tools pass a tenth of the model's context window (or settings say so), they are deferred for the session's life, and the model gets `tool_search` (BM25 over the deferred tools' names and descriptions, served by core) and `tool_call`, with a note naming each server and its instructions. Approval resolves per tool, and a turn variant's tightening applies to its turn. The gate's `mcp/connect` answers the server's instructions.
50
+
51
+ ### Patch Changes
52
+
53
+ - fed5e58: **Docs: reaching a person's accounts** (R2b C5). The READMEs describe MCP credentials as protocol 10 has them (a `bearer` token or a `headers` map per URL, with `via` and an identity header for an MCP gateway), and point to "MCP servers and HTTP tools" in DEPLOYMENT.md: the operator's flow from credential to preview, tool settings, deferral, stored results and the error codes a model sees, with gateway recipes for Arcade, ToolHive, Obot and Nylorun Cloud and the proxy pattern for gateways that mint per person. `HttpToolTarget.credential`'s doc (`@nylorun/core`) no longer names the removed credential resolver.
54
+ - Pin core to the tested release.
55
+ - Pin harness to the tested release.
56
+ - Updated dependencies [50e2f7e]
57
+ - Updated dependencies [e0e39ff]
58
+ - Updated dependencies [fed5e58]
59
+ - Updated dependencies [18f9a2f]
60
+ - Updated dependencies [da93711]
61
+ - Updated dependencies [90a817d]
62
+ - Updated dependencies [b8d10cb]
63
+ - Updated dependencies
64
+ - @nylorun/core@0.17.0-beta
65
+ - @nylorun/harness@0.24.0-beta
66
+
67
+ ## 0.20.0-beta
68
+
69
+ ### Major Changes
70
+
71
+ - cf5eb9c: **Protocol 9: the Runtime API is an OAuth 2.1 resource server for your identity provider's tokens.** Nylorun is still never the authorization server. Upgrade every package together; MIGRATION.md has the details.
72
+
73
+ - **Breaking (`@nylorun/runtime`): a refused credential is `401`, not the opaque `404`.** No `Authorization` is `401 credential_required`; an unknown key, or a token no trusted issuer signed or that fails a check, is `401 credential_invalid`. Each carries `WWW-Authenticate: Bearer` (OAuth 2.1 §5.3), naming the protected resource metadata (`resource_metadata`) on the Runtime API when the Runtime has trusted issuers; the Management API's challenge is a bare `Bearer`. `token_expired` and `issuer_unavailable` gain the challenge too. Another Tenant named, a Tenant that could not open and an unsigned capability link stay the opaque `404`.
74
+ - **Breaking (`@nylorun/runtime`): a request with neither `Nylorun-Protocol` nor `Authorization`** on an API route gets that route's `401` challenge instead of `426`, so a generic OAuth client learns where to sign in.
75
+ - `@nylorun/runtime`: a token without a route's scope still gets `403 scope_required`, now with `WWW-Authenticate: Bearer error="insufficient_scope", scope="…"`. The `Bearer` scheme is matched in any case (RFC 9110).
76
+ - `@nylorun/runtime`: `GET /.well-known/oauth-protected-resource` (RFC 9728) serves the resource (`NYLORUN_PUBLIC_URL`, else the request's origin), the identity file's issuers in order and their scopes, with no key or protocol; `404` without an identity file.
77
+ - **Breaking (`@nylorun/runtime`): the identity file drops `maxLifetime`.** The issuer sets its tokens' lifetimes; `exp` is required, `iat` no longer is. A key the file does not define, `maxLifetime` included, is ignored and logged (`identity_file_key_ignored`) instead of stopping the boot. `subject` defaults to `{sub}`, `scopes` to `{ claim: scope }` and `allowedScopes` to every token scope but `studio`.
78
+ - `@nylorun/core`: `PROTOCOL_VERSION` is 9 and `HOST_PROTOCOL` 4–9, with the required feature `resource-server`; `ERROR_CODES` adds `credential_required` and `credential_invalid`. `@nylorun/agents`, `@nylorun/admin` and `@nylorun/cli` send protocol 9.
79
+
80
+ ### Patch Changes
81
+
82
+ - 6711320: Cancels and sessions resets reach the other Runtime processes over a control bus on Postgres, not S2's `tenant/control` stream, which is gone: nothing inside the Runtime depends on S2 any more. A cancel writes a `session.cancel` signal in its own transaction and Postgres notifies every process at commit (`LISTEN`/`NOTIFY` on `nylorun_control`), so a cancel aborts the Worker's model or tool call even while S2 is down. Each process holds one `LISTEN` connection of its own and reads recent signals back every 5 s and after a reconnect; connect the Runtime to Postgres directly or through a pooler in session mode. Migration `0015_control_signals` adds `nylorun.control_signals`; the Tenant sweep deletes signals older than an hour. While processes of the previous beta still run beside new ones, a cancel between them is stopped by the Session Store check before the next effect, as when a signal was lost.
83
+ - 6711320: `/ready` no longer checks S2: its `checks` cover the listener, the Tenant, Postgres and Restate, and an unreachable S2 leaves it `200`. S2 only serves API listeners (history, SSE, AG-UI and A2A), so an outage degrades those reads and never makes the Runtime unready. S2's reachability stays in the Tenant's status (`GET /v1/tenant`, `streams.reachable`).
84
+ - 2ed5fe0: The event source `sandboxd` is now `sandboxes`, the name the sandbox lifecycle service took on 3 Oct, matching core, loop, gates, keys, egress and harness. Nothing emits it yet, so no stored event changes; the OpenAPI document's `EventSourceKind` enum shows the new name, and `--service sandboxes` is the blueprint service this release refuses as not yet shipped.
85
+ - Pin core to the tested release.
86
+ - Pin harness to the tested release.
87
+ - Updated dependencies [cf5eb9c]
88
+ - Updated dependencies [2ed5fe0]
89
+ - Updated dependencies
90
+ - @nylorun/core@0.16.0-beta
91
+ - @nylorun/harness@0.23.1-beta
92
+
3
93
  ## 0.19.1-beta
4
94
 
5
95
  ### Patch Changes
package/README.md CHANGED
@@ -86,11 +86,13 @@ is refused with `409 run_stale`. A `gates` process needs only
86
86
  `NYLORUN_DATABASE_URL`, `NYLORUN_GATES_TOKEN`, its listener
87
87
  (`NYLORUN_GATES_LISTEN_HOST`, `NYLORUN_GATES_LISTEN_PORT`, default 4100, and
88
88
  `NYLORUN_GATES_ALLOWED_HOSTS`) and the Host's `tenant/` directory, which it
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`
89
+ never writes; it serves the database's one Tenant. A session's MCP servers and
90
+ HTTP tools get their credentials from its attached vaults only: a `bearer` token
91
+ or a `headers` map per URL, sent to an MCP gateway instead when it has `via`,
92
+ with the session owner in its identity header
93
+ ([DEPLOYMENT.md](../DEPLOYMENT.md#mcp-servers-and-http-tools)); the credential resolver is gone
94
+ (protocol 10), and a process that still sets a `NYLORUN_RESOLVER_*` variable logs
95
+ `resolver_removed` and ignores it. With `egress`
94
96
  (`--service gates,keys,egress`, for pod sandboxes) the same process runs
95
97
  egress-gate on `NYLORUN_EGRESS_LISTEN_HOST`:`NYLORUN_EGRESS_LISTEN_PORT`
96
98
  (default `0.0.0.0:4200`): a CONNECT proxy that admits a pod's egress token and
@@ -136,14 +138,12 @@ The Host root is `NYLORUN_HOME` or `~/.nylorun` (for a local Tenant,
136
138
  | Route | Auth | Notes |
137
139
  | --- | --- | --- |
138
140
  | `GET /health` | none | `service: "nylorun-runtime"`, `hostId`, protocol `{min,max,features}`, pid |
139
- | `GET /ready` | none | Listener up, the Tenant open, and Postgres, Restate and S2 answer (`checks`); `harness: { mode, connected }` while the Tenant is open |
141
+ | `GET /ready` | none | Listener up, the Tenant open, and Postgres and Restate answer (`checks`). S2 is not checked: its health is in `GET /v1/tenant` (`streams.reachable`); `harness: { mode, connected }` while the Tenant is open |
140
142
  | `GET /openapi/runtime.json` | none | The Runtime API's OpenAPI 3.2 document (below); alias `GET /openapi.json`. Refuses an `Origin` |
141
143
  | `GET /openapi/management.json` | none | The Management API's OpenAPI 3.2 document. Refuses an `Origin` |
142
144
  | `/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
145
  | `/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
146
  | `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 |
147
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 |
148
148
 
149
149
  Every route checks `Host` first (`421 host_rejected`) and rejects non-JSON bodies
@@ -154,15 +154,21 @@ presents a trusted issuer's token; keys (application and management)
154
154
  are refused from browsers before they are looked up. The Runtime sends no CORS headers, and answers
155
155
  `OPTIONS` with `204` and `Allow` only: the operator's reverse proxy answers preflights
156
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
157
+ unsupported protocol → `426` before authentication, unless the request sends neither
158
+ `Nylorun-Protocol` nor `Authorization` (the Host serves protocols 4 to 10; protocol 10 removes
159
+ the MCP OAuth connect, the vault's `oauth` credentials and the credential resolver, and adds
160
+ `headers` credentials, `via` and the identity header, manifest v6 and
161
+ `POST /v1/tenant/mcp/preview`; protocol 9 makes the Runtime API an OAuth 2.1 resource server: a missing or rejected credential is `401
162
+ credential_required` or `credential_invalid` with a `WWW-Authenticate: Bearer` challenge, a
163
+ token without a route's scope gets `error="insufficient_scope"`, and
164
+ `/.well-known/oauth-protected-resource` lists the trusted issuers (RFC 9728); protocol 8 gives keys roles, moves vaults and signing keys under `/v1/tenant` and removes
159
165
  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
166
  derived principals, whose routes answer `404`; protocol 6 adds file and folder artifacts and message `parts`; at each turn's end the
161
167
  Runtime exports `/workspace/outputs` of the session's sandbox as a version of its
162
168
  `outputs` folder, read at `/v1/artifacts/{id}/versions/{n|latest}/tree`, `/files/{path}`,
163
169
  `/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
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`
170
+ another Tenant (or malformed) and a Tenant that
171
+ could not be opened → opaque `404` with identical body. A path or method no route serves is `404 Route not found`
166
172
  once the caller is known.
167
173
 
168
174
  ## API reference (OpenAPI)
@@ -235,7 +241,10 @@ Save agents with `PUT /v1/agents/{agentId}` using the application principal (`sa
235
241
  in `@nylorun/agents`). The Runtime runs the agent from its manifest and never calls your
236
242
  code during a session: a definition with a tool that would (`tool({ run })`, a flow's tool
237
243
  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
244
+ so their URLs must be reachable from it, and remote MCP servers. The operator gives
245
+ each URL a vault credential, previews an MCP server's tools (`nylorun mcp inspect`),
246
+ and the manifest says which tools are enabled, need approval or are deferred
247
+ ([DEPLOYMENT.md](../DEPLOYMENT.md#mcp-servers-and-http-tools)). Model gateway
239
248
  and sandbox backend are Tenant configuration (vault / seed), not Host process
240
249
  env.
241
250
 
@@ -8,10 +8,9 @@
8
8
  * - One basin per Tenant basin generation, named by `tenantBasinName` (`streams/basin.ts`):
9
9
  * `<basinPrefix>tn-<ulid>` for a Tenant id `tn_<ulid>`, `…-<g base36>` for generation g.
10
10
  * - The basin is created with `createStreamOnAppend` and `createStreamOnRead`, so
11
- * `sessions/<id>` and `tenant/control` come into existence on first use. Its
12
- * default stream config sets infinite retention, which session streams
13
- * keep; the control stream is created with a one-day
14
- * age-based retention instead (signals are latency hints, not history).
11
+ * `sessions/<id>` come into existence on first use. Its default stream config
12
+ * sets infinite retention, which session streams keep. There are no other
13
+ * streams: signals between processes go over Postgres (D48).
15
14
  * - Bodies are JSON text in string records. Record timestamps are S2 arrival
16
15
  * times.
17
16
  * - Appends use `appendRetryPolicy: "noSideEffects"`: the SDK retries only
@@ -27,7 +26,7 @@
27
26
  * explicit `{ infinite: {} }` retention to keep session history; this adapter
28
27
  * sets it as the basin default, and s2-lite honours it (a new stream reports
29
28
  * `infinite`). A `streamConfig` sent with an append that creates the stream
30
- * is honoured too (used for the control stream). `deleteOnEmpty`
29
+ * is honoured too. `deleteOnEmpty`
31
30
  * defaults to disabled (`minAgeSecs: 0`).
32
31
  * - **Stream deletion** is immediate for our purposes: right after `DELETE`,
33
32
  * `checkTail` and reads return 404 `stream_not_found` (new read sessions
@@ -59,9 +58,7 @@
59
58
  */
60
59
  import { AppendInput, AppendRecord, RangeNotSatisfiableError, S2, S2Error, SeqNumMismatchError, } from "@s2-dev/streamstore";
61
60
  import { parseBasin, tenantBasinName, validateBasinPrefix } from "../../streams/basin.js";
62
- import { CONTROL_STREAM, } from "../../streams/types.js";
63
- /** Retention of the control signal stream. */
64
- const SIGNAL_RETENTION_SECS = 24 * 60 * 60;
61
+ import {} from "../../streams/types.js";
65
62
  /** Records per unary read while reading history. */
66
63
  const HISTORY_PAGE = 1000;
67
64
  const RETRY_MIN_MS = 100;
@@ -99,9 +96,6 @@ class S2Streams {
99
96
  return AppendRecord.string({ body });
100
97
  }), {
101
98
  ...(options.matchSeq !== undefined ? { matchSeqNum: options.matchSeq } : {}),
102
- ...(stream === CONTROL_STREAM
103
- ? { streamConfig: { retentionPolicy: { ageSecs: SIGNAL_RETENTION_SECS } } }
104
- : {}),
105
99
  });
106
100
  const handle = this.handle(tenantId, stream);
107
101
  let delay = RETRY_MIN_MS / 4;