@nylorun/runtime 0.25.0-beta → 0.26.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 +39 -0
- package/README.md +9 -3
- package/dist/api/http/app.d.ts +2 -2
- package/dist/api/http/app.js +2 -2
- package/dist/api/http/define.d.ts +1 -1
- package/dist/api/http/respond.js +1 -1
- package/dist/api/http/routes/sessions.js +1 -1
- package/dist/gates/egress.js +5 -3
- package/dist/gates/http-tool.js +15 -7
- package/dist/keys/contract.d.ts +1 -1
- package/dist/keys/contract.js +1 -1
- package/dist/management-openapi.json +1 -1
- package/dist/mcp/preview.d.ts +1 -1
- package/dist/mcp/preview.js +1 -1
- package/dist/openapi.json +44 -16
- package/dist/store/postgres/migrate.js +1 -1
- package/dist/tenant/environments.js +5 -2
- package/dist/tenant/ephemeral.d.ts +1 -1
- package/dist/tenant/host-token.js +1 -1
- package/dist/tenant/identity-file.d.ts +1 -1
- package/dist/tenant/identity-file.js +1 -1
- package/dist/tenant/outbound.d.ts +6 -5
- package/dist/tenant/outbound.js +8 -6
- package/dist/tenant/types.d.ts +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.26.0-beta
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a0cf8b2: **HTTP tools take `GET` and `DELETE`, and URL path parameters.**
|
|
8
|
+
|
|
9
|
+
- `method` is `GET`, `POST` (default), `PUT`, `PATCH` or `DELETE`. `POST`, `PUT` and `PATCH` send the input as the JSON body, as before. `GET` and `DELETE` send no body: the input becomes the query string, after any query string written in the URL. An array repeats its name (`tag=a&tag=b`) and a `null` is left out.
|
|
10
|
+
- The URL's path may name input fields as `{field}`, as in `https://api.example.com/orders/{orderId}`. Each value is percent-encoded into the path and is not sent again in the body or query string. A value that is empty, `.` or `..`, or not a string, number or boolean is refused before the call is sent (`tool.invalid-input`).
|
|
11
|
+
- `http()` and the manifest contract check a tool against its input schema. Each `{field}` must be a required scalar property. For `GET` and `DELETE`, a property must not be an object and must not repeat a query parameter the URL already sets.
|
|
12
|
+
- An HTTP verifier still takes only `POST`, `PUT` or `PATCH` and a URL without `{field}` parameters, because it is sent `{ input, output, iteration }` as a body. A credential with `via` cannot serve a tool with `{field}` parameters (`http.credential`).
|
|
13
|
+
- core exports `httpToolRequest`, which maps a call's input to the request, and `httpPathParameters`. The Runtime's outbound `post()` is now `send()`, which can send a request without a body.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 620072d: **Docs and schemas match what the CLI and the Runtime do.**
|
|
18
|
+
|
|
19
|
+
- `@nylorun/core`: the environment manifest's JSON Schema (`@nylorun/core/schemas/environment-manifest.json`) takes the CLI's `{ path, from }` `files` entry, so an editor no longer flags a manifest that `nylorun environments manifests save` accepts. The Runtime's own schema is unchanged: the CLI turns the folder into `{ path, files }` before saving. `manifest_changed` says to save without `If-Match` (`--if-match`, `ifMatch`); no command takes `--force`.
|
|
20
|
+
- Tool names, skill names and MCP server names are each unique within their kind, as the builder and the Runtime check; a tool, a skill and a server may share a name. The docs said they were unique across kinds.
|
|
21
|
+
- `harness_mismatch` is described as what it is since protocol 14: an Environment's harness is fixed for its life (fork onto a manifest version to run another), and a session's turn is refused when its Environment id was deleted and made again with another harness, or an Environment changed in place before protocol 14 applies that change.
|
|
22
|
+
- `@nylorun/agents`: the README names `nylorun environments list | delete`, not `nylorun local sandbox ls | rm`.
|
|
23
|
+
- MIGRATION.md no longer offers a tool's `approval`, removed in protocol 11, as a replacement for step middleware.
|
|
24
|
+
|
|
25
|
+
- 71edf68: egress-gate's `environment.egress` names the turns its one read saw as the connection opened: the read starts as the name resolves and the tunnel never waits for it, as the docs now say. The egress-gate event test waits for that read before it moves a turn, so it no longer fails on a slow runner.
|
|
26
|
+
- 000ff75: **READMEs and help text match protocol 14.**
|
|
27
|
+
|
|
28
|
+
- `nylorun --help` lists `environments fork`, `manifests` and `delete-version`. The package description no longer offers `nylo` as the Runtime client, and the README says nylorun depends on `@nylorun/agents` too.
|
|
29
|
+
- The READMEs name the current commands: `nylorun tenant keys`, `nylorun tenant mcp inspect`, `nylorun local logs` and `nylorun local reset`. `@nylorun/admin` says it speaks protocol 14.
|
|
30
|
+
- `@nylorun/agents`: a lost MCP or HTTP tool call is sent again with its key, then fails to the model as `tool.interrupted` (it is not left `uncertain`). Every manifest is v7. A2A takes `raw` files. A delegated agent cannot pause.
|
|
31
|
+
- `@nylorun/runtime`: the README describes protocol 14, `PUT /v1/sessions/{id}` says it answers an identical session (vaults are no longer attached), and the database-layout error names `nylorun local reset`.
|
|
32
|
+
- `@nylorun/create-agent`: `nylorun start` writes the project's keys (no key is derived any more).
|
|
33
|
+
|
|
34
|
+
- Pin core to the tested release.
|
|
35
|
+
- Pin harness to the tested release.
|
|
36
|
+
- Updated dependencies [620072d]
|
|
37
|
+
- Updated dependencies [a0cf8b2]
|
|
38
|
+
- Updated dependencies
|
|
39
|
+
- @nylorun/core@0.22.0-beta
|
|
40
|
+
- @nylorun/harness@0.27.1-beta
|
|
41
|
+
|
|
3
42
|
## 0.25.0-beta
|
|
4
43
|
|
|
5
44
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -172,7 +172,13 @@ are refused from browsers before they are looked up. The Runtime sends no CORS h
|
|
|
172
172
|
`OPTIONS` with `204` and `Allow` only: the operator's reverse proxy answers preflights
|
|
173
173
|
([DEPLOYMENT.md](../../guides/DEPLOYMENT.md#calling-the-runtime-from-browsers-and-apps)). Missing or
|
|
174
174
|
unsupported protocol → `426` before authentication, unless the request sends neither
|
|
175
|
-
`Nylorun-Protocol` nor `Authorization` (the Host serves protocol
|
|
175
|
+
`Nylorun-Protocol` nor `Authorization` (the Host serves protocol 14 only; protocol 14 adds
|
|
176
|
+
environment manifests (`/v1/environment-manifests/{name}`): an Environment is made from one
|
|
177
|
+
version and never changes what it runs (a new version reaches it through
|
|
178
|
+
`POST /v1/environments/{id}/fork`), a manifest's `secrets` declare slots and an agent's
|
|
179
|
+
`requires` is checked when a session opens; sessions on one Environment run their turns in
|
|
180
|
+
parallel, and egress connections are `environment.egress` events on the Environment's stream,
|
|
181
|
+
in no session log or trace; protocol 13 makes the
|
|
176
182
|
manifest flat, manifest 7: no `capabilities`, tools known by name, the Runtime's own tools in the
|
|
177
183
|
pinned manifest's `runtime` block and no `capabilityId` on events, tool call rows or the Harness
|
|
178
184
|
API, now 3; it closes every session opened before it; protocol 12 adds
|
|
@@ -268,7 +274,7 @@ stage) is refused. Your services are reached as tools: HTTP tools, POSTed from t
|
|
|
268
274
|
so their URLs must be reachable from it, and remote MCP servers. Each URL gets a
|
|
269
275
|
credential in the vault of the Environment a session names (`PUT
|
|
270
276
|
/v1/environments/{id}/secrets/{name}`), the operator previews an MCP server's tools
|
|
271
|
-
(`nylorun mcp inspect --environment <id>`),
|
|
277
|
+
(`nylorun tenant mcp inspect --environment <id>`),
|
|
272
278
|
and the manifest says which tools are enabled or deferred
|
|
273
279
|
([DEPLOYMENT.md](../../guides/DEPLOYMENT.md#mcp-servers-and-http-tools)). Which calls wait for a
|
|
274
280
|
person, or are refused, is the Tenant's tool policy
|
|
@@ -315,7 +321,7 @@ the Project link (outside a project it runs the Tenant `default`); the project's
|
|
|
315
321
|
| `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`) |
|
|
316
322
|
| `503` for a Tenant | Postgres or Restate is unreachable; `GET /ready` names which |
|
|
317
323
|
| Port in use | Change `NYLORUN_PORT` in `~/.nylorun/tenants/<name>/docker/.env` and run `nylorun start` |
|
|
318
|
-
| Logs | `nylorun logs runtime` |
|
|
324
|
+
| Logs | `nylorun local logs runtime` |
|
|
319
325
|
|
|
320
326
|
Definitions have no `agent.run()`; applications use `@nylorun/agents`.
|
|
321
327
|
|
package/dist/api/http/app.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The Runtime and Management APIs as one Hono app: one for every open Tenant, which arrives with each request as
|
|
3
3
|
* the `tenant` binding. Every route is declared once (`define.ts`) in `routes/`, `../ag-ui/`
|
|
4
4
|
* and `../a2a/`. A request no route matches exactly is authenticated like any other, then
|
|
5
5
|
* answered `404 Route not found`.
|
|
@@ -18,7 +18,7 @@ export type TenantEnv = {
|
|
|
18
18
|
scope: AuthScope;
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
-
/** The
|
|
21
|
+
/** The Runtime and Management APIs' app, built on first use. */
|
|
22
22
|
export declare function tenantApi(): OpenAPIHono<TenantEnv>;
|
|
23
23
|
/** Who may call `method` on a Tenant path (its decoded segments), if it is a route. */
|
|
24
24
|
export declare function findTenantRoute(method: string, segments: readonly string[]): RouteAccess | undefined;
|
package/dist/api/http/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The Runtime and Management APIs as one Hono app: one for every open Tenant, which arrives with each request as
|
|
3
3
|
* the `tenant` binding. Every route is declared once (`define.ts`) in `routes/`, `../ag-ui/`
|
|
4
4
|
* and `../a2a/`. A request no route matches exactly is authenticated like any other, then
|
|
5
5
|
* answered `404 Route not found`.
|
|
@@ -23,7 +23,7 @@ import { tenantRoutes } from "./routes/tenant.js";
|
|
|
23
23
|
import { coverageRoutes } from "./routes/coverage.js";
|
|
24
24
|
import { mcpRoutes } from "./routes/mcp.js";
|
|
25
25
|
let app;
|
|
26
|
-
/** The
|
|
26
|
+
/** The Runtime and Management APIs' app, built on first use. */
|
|
27
27
|
export function tenantApi() {
|
|
28
28
|
return (app ??= build());
|
|
29
29
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* How a
|
|
2
|
+
* How a Runtime or Management API route is declared: once, with who may call it, for serving and for the
|
|
3
3
|
* OpenAPI document.
|
|
4
4
|
*
|
|
5
5
|
* `RouteAccess` says which credentials a route takes and which subject scopes reach it: the one
|
package/dist/api/http/respond.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* How the
|
|
2
|
+
* How the Runtime and Management APIs answer: JSON with an explicit length, and the one mapping from what a
|
|
3
3
|
* route throws to the rejection a client sees. The Hono routes and the router they replace
|
|
4
4
|
* (`routes.ts`) both answer through here, so a route answers the same wherever it runs.
|
|
5
5
|
*/
|
|
@@ -121,7 +121,7 @@ export function sessionRoutes(api) {
|
|
|
121
121
|
path: "/v1/sessions/{sessionId}",
|
|
122
122
|
tags: ["Sessions"],
|
|
123
123
|
summary: "Open a session",
|
|
124
|
-
description: "Creates the session, or
|
|
124
|
+
description: "Creates the session, or answers the one already opened with the same agent, owner, info and Environment. Its Environment (its sandbox and vault) is chosen now and fixed for its life.",
|
|
125
125
|
request: { params: sessionId, body: body(PutSessionRequest) },
|
|
126
126
|
responses: {
|
|
127
127
|
200: json(SessionView, "The session"),
|
package/dist/gates/egress.js
CHANGED
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
* Every connection to a named host on a live token is recorded once (R7.3, D67), when it closes
|
|
28
28
|
* or at once when the gate refuses it, as `environment.egress` on the Environment's own stream:
|
|
29
29
|
* the connection is the Environment's, since its token names the pod and turns run in parallel
|
|
30
|
-
* (D66). `runningTurns` lists the turns active on the Environment as it opened
|
|
31
|
-
*
|
|
30
|
+
* (D66). `runningTurns` lists the turns active on the Environment as it opened, as context and
|
|
31
|
+
* never as an owner: one read, started as the name resolves and never waited for, so a turn that
|
|
32
|
+
* moves while it is in flight may show either way. Host, port, outcome, bytes, duration and, for a
|
|
32
33
|
* credential host, the request count and credential ids; never a header value, a path or a body. A refusal
|
|
33
34
|
* before that (no token, a stale one, no `host:port`) stays a log line, and a client that hangs up
|
|
34
35
|
* before the gate answers leaves nothing. A write never holds the tunnel up, and a failed one is
|
|
@@ -260,7 +261,8 @@ export async function startEgressGate(options) {
|
|
|
260
261
|
return refuse(403, "not_a_host_name", { sandboxId }, `${host} is not a host name; IP literals are refused`);
|
|
261
262
|
if (!egressAllows(host, sandbox.allow))
|
|
262
263
|
return refuse(403, "host_not_allowed", { sandboxId }, `${host} is not in this sandbox's network.allow`);
|
|
263
|
-
// The turns running on the Environment as the connection opens
|
|
264
|
+
// The turns running on the Environment as the connection opens: the read starts as the
|
|
265
|
+
// name resolves, and the 200 does not wait for it.
|
|
264
266
|
record.opened();
|
|
265
267
|
let mine = open.get(sandboxId);
|
|
266
268
|
if (!mine)
|
package/dist/gates/http-tool.js
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
* The loop names the tool; the gate finds its URL, method and credential in the session's pinned
|
|
4
4
|
* manifest, as it finds a remote MCP server, so the loop never chooses a URL or a credential.
|
|
5
5
|
*
|
|
6
|
-
* `callHttpTarget` is the request and its answer, for any declared HTTP target: the input as
|
|
7
|
-
*
|
|
6
|
+
* `callHttpTarget` is the request and its answer, for any declared HTTP target: the input as
|
|
7
|
+
* core's `httpToolRequest` maps it (path parameters in the URL, the rest as a JSON body or, for
|
|
8
|
+
* `GET` and `DELETE`, the query string) under the Host's address policy (`tenant/outbound.ts`),
|
|
9
|
+
* a 2xx answer as the output
|
|
8
10
|
* (JSON, or text when the answer is not JSON and no output schema asks for JSON), and every other
|
|
9
11
|
* answer, a timeout or a refused address as a failed outcome the model sees. `runHttpTool` adds
|
|
10
12
|
* what a tool call needs: the declaration, the vault credential and the identity headers.
|
|
@@ -14,9 +16,9 @@
|
|
|
14
16
|
* `Nylorun-Agent-Id` is the flow agent's.
|
|
15
17
|
*/
|
|
16
18
|
import { AGENT_ID_HEADER, SESSION_ID_HEADER, TURN_ID_HEADER, } from "@nylorun/core/compatibility";
|
|
17
|
-
import { HTTP_TOOL_DEFAULT_TIMEOUT_MS, delegateManifest, flowHttpTarget, isWorkflowManifest, schemaFromJSON, } from "@nylorun/core/define";
|
|
19
|
+
import { HTTP_TOOL_DEFAULT_TIMEOUT_MS, delegateManifest, flowHttpTarget, httpPathParameters, httpToolRequest, isWorkflowManifest, schemaFromJSON, } from "@nylorun/core/define";
|
|
18
20
|
import { scrubValues } from "../redact.js";
|
|
19
|
-
import { MAX_RESPONSE_BYTES,
|
|
21
|
+
import { MAX_RESPONSE_BYTES, send } from "../tenant/outbound.js";
|
|
20
22
|
import { credentialSecrets } from "../vault/headers.js";
|
|
21
23
|
/** How much of a failed answer's body the model sees. */
|
|
22
24
|
export const HTTP_ERROR_BODY_CHARS = 2_000;
|
|
@@ -61,11 +63,14 @@ export function httpToolRefOf(request) {
|
|
|
61
63
|
* the request is an outcome. Rejects only when `signal` aborts, with its reason.
|
|
62
64
|
*/
|
|
63
65
|
export async function callHttpTarget(target, input, options) {
|
|
66
|
+
const request = httpToolRequest(target, input);
|
|
67
|
+
if ("issue" in request)
|
|
68
|
+
return failed("tool.invalid-input", request.issue);
|
|
64
69
|
const timeoutMs = target.timeoutMs ?? HTTP_TOOL_DEFAULT_TIMEOUT_MS;
|
|
65
70
|
const timeout = AbortSignal.timeout(timeoutMs);
|
|
66
|
-
const result = await
|
|
71
|
+
const result = await send(request.url, request.body, { ...options.headers }, {
|
|
67
72
|
policy: options.policy,
|
|
68
|
-
method:
|
|
73
|
+
method: request.method,
|
|
69
74
|
signal: AbortSignal.any([options.signal, timeout]),
|
|
70
75
|
});
|
|
71
76
|
if (options.signal.aborted)
|
|
@@ -170,7 +175,10 @@ export async function runHttpTool(tenant, call, options) {
|
|
|
170
175
|
return failed("http.credential", `The session's Environment holds no credential '${http.credential}' for ${authorized.url}`);
|
|
171
176
|
credential = authorized.headers;
|
|
172
177
|
identity = authorized.identity;
|
|
173
|
-
// A credential with `via` sends the call there, a gateway (R2b C2, Q9)
|
|
178
|
+
// A credential with `via` sends the call there, a gateway (R2b C2, Q9): to its one URL, so
|
|
179
|
+
// it has no place for the tool's URL parameters.
|
|
180
|
+
if (authorized.via !== undefined && httpPathParameters(http.url).length > 0)
|
|
181
|
+
return failed("http.credential", `The credential '${http.credential}' sends calls to its via URL, which cannot take the tool's {field} URL parameters`);
|
|
174
182
|
if (authorized.via !== undefined)
|
|
175
183
|
target = { ...http, url: authorized.via };
|
|
176
184
|
}
|
package/dist/keys/contract.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* gates token. Internal: only core calls it, so it is not in the published OpenAPI documents.
|
|
5
5
|
*
|
|
6
6
|
* `200 {result}` when the operation succeeded, `200 {error}` when it refused: a vault error or
|
|
7
|
-
* a
|
|
7
|
+
* a Runtime or Management API error with its status, code and details, so the route that called it answers
|
|
8
8
|
* exactly what it answered when the operation ran in its own process.
|
|
9
9
|
*/
|
|
10
10
|
export declare const KEYS_PATH = "/nylorun/v1/keys";
|
package/dist/keys/contract.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* gates token. Internal: only core calls it, so it is not in the published OpenAPI documents.
|
|
5
5
|
*
|
|
6
6
|
* `200 {result}` when the operation succeeded, `200 {error}` when it refused: a vault error or
|
|
7
|
-
* a
|
|
7
|
+
* a Runtime or Management API error with its status, code and details, so the route that called it answers
|
|
8
8
|
* exactly what it answered when the operation ran in its own process.
|
|
9
9
|
*/
|
|
10
10
|
export const KEYS_PATH = "/nylorun/v1/keys";
|
package/dist/mcp/preview.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A remote MCP server's tools before an agent names it (R2b C12, `POST /v1/tenant/mcp/preview`,
|
|
3
|
-
* `nylorun mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
|
|
3
|
+
* `nylorun tenant mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
|
|
4
4
|
* the keys service (`keys/keys.ts`, `previewMcp`), in the gateway or in process.
|
|
5
5
|
*
|
|
6
6
|
* One connection: `initialize` and `tools/list` with the Environment's credential for the
|
package/dist/mcp/preview.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A remote MCP server's tools before an agent names it (R2b C12, `POST /v1/tenant/mcp/preview`,
|
|
3
|
-
* `nylorun mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
|
|
3
|
+
* `nylorun tenant mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
|
|
4
4
|
* the keys service (`keys/keys.ts`, `previewMcp`), in the gateway or in process.
|
|
5
5
|
*
|
|
6
6
|
* One connection: `initialize` and `tools/list` with the Environment's credential for the
|
package/dist/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.2.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Nylorun Runtime API",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.26.0-beta",
|
|
6
6
|
"x-nylorun-protocol": {
|
|
7
7
|
"min": 14,
|
|
8
8
|
"max": 14,
|
|
@@ -6508,9 +6508,11 @@
|
|
|
6508
6508
|
"method": {
|
|
6509
6509
|
"type": "string",
|
|
6510
6510
|
"enum": [
|
|
6511
|
+
"GET",
|
|
6511
6512
|
"POST",
|
|
6512
6513
|
"PUT",
|
|
6513
|
-
"PATCH"
|
|
6514
|
+
"PATCH",
|
|
6515
|
+
"DELETE"
|
|
6514
6516
|
]
|
|
6515
6517
|
},
|
|
6516
6518
|
"credential": {
|
|
@@ -6791,9 +6793,11 @@
|
|
|
6791
6793
|
"method": {
|
|
6792
6794
|
"type": "string",
|
|
6793
6795
|
"enum": [
|
|
6796
|
+
"GET",
|
|
6794
6797
|
"POST",
|
|
6795
6798
|
"PUT",
|
|
6796
|
-
"PATCH"
|
|
6799
|
+
"PATCH",
|
|
6800
|
+
"DELETE"
|
|
6797
6801
|
]
|
|
6798
6802
|
},
|
|
6799
6803
|
"credential": {
|
|
@@ -6948,9 +6952,11 @@
|
|
|
6948
6952
|
"method": {
|
|
6949
6953
|
"type": "string",
|
|
6950
6954
|
"enum": [
|
|
6955
|
+
"GET",
|
|
6951
6956
|
"POST",
|
|
6952
6957
|
"PUT",
|
|
6953
|
-
"PATCH"
|
|
6958
|
+
"PATCH",
|
|
6959
|
+
"DELETE"
|
|
6954
6960
|
]
|
|
6955
6961
|
},
|
|
6956
6962
|
"credential": {
|
|
@@ -7231,9 +7237,11 @@
|
|
|
7231
7237
|
"method": {
|
|
7232
7238
|
"type": "string",
|
|
7233
7239
|
"enum": [
|
|
7240
|
+
"GET",
|
|
7234
7241
|
"POST",
|
|
7235
7242
|
"PUT",
|
|
7236
|
-
"PATCH"
|
|
7243
|
+
"PATCH",
|
|
7244
|
+
"DELETE"
|
|
7237
7245
|
]
|
|
7238
7246
|
},
|
|
7239
7247
|
"credential": {
|
|
@@ -7387,9 +7395,11 @@
|
|
|
7387
7395
|
"method": {
|
|
7388
7396
|
"type": "string",
|
|
7389
7397
|
"enum": [
|
|
7398
|
+
"GET",
|
|
7390
7399
|
"POST",
|
|
7391
7400
|
"PUT",
|
|
7392
|
-
"PATCH"
|
|
7401
|
+
"PATCH",
|
|
7402
|
+
"DELETE"
|
|
7393
7403
|
]
|
|
7394
7404
|
},
|
|
7395
7405
|
"credential": {
|
|
@@ -7670,9 +7680,11 @@
|
|
|
7670
7680
|
"method": {
|
|
7671
7681
|
"type": "string",
|
|
7672
7682
|
"enum": [
|
|
7683
|
+
"GET",
|
|
7673
7684
|
"POST",
|
|
7674
7685
|
"PUT",
|
|
7675
|
-
"PATCH"
|
|
7686
|
+
"PATCH",
|
|
7687
|
+
"DELETE"
|
|
7676
7688
|
]
|
|
7677
7689
|
},
|
|
7678
7690
|
"credential": {
|
|
@@ -7961,9 +7973,11 @@
|
|
|
7961
7973
|
"method": {
|
|
7962
7974
|
"type": "string",
|
|
7963
7975
|
"enum": [
|
|
7976
|
+
"GET",
|
|
7964
7977
|
"POST",
|
|
7965
7978
|
"PUT",
|
|
7966
|
-
"PATCH"
|
|
7979
|
+
"PATCH",
|
|
7980
|
+
"DELETE"
|
|
7967
7981
|
]
|
|
7968
7982
|
},
|
|
7969
7983
|
"credential": {
|
|
@@ -8244,9 +8258,11 @@
|
|
|
8244
8258
|
"method": {
|
|
8245
8259
|
"type": "string",
|
|
8246
8260
|
"enum": [
|
|
8261
|
+
"GET",
|
|
8247
8262
|
"POST",
|
|
8248
8263
|
"PUT",
|
|
8249
|
-
"PATCH"
|
|
8264
|
+
"PATCH",
|
|
8265
|
+
"DELETE"
|
|
8250
8266
|
]
|
|
8251
8267
|
},
|
|
8252
8268
|
"credential": {
|
|
@@ -8467,9 +8483,11 @@
|
|
|
8467
8483
|
"method": {
|
|
8468
8484
|
"type": "string",
|
|
8469
8485
|
"enum": [
|
|
8486
|
+
"GET",
|
|
8470
8487
|
"POST",
|
|
8471
8488
|
"PUT",
|
|
8472
|
-
"PATCH"
|
|
8489
|
+
"PATCH",
|
|
8490
|
+
"DELETE"
|
|
8473
8491
|
]
|
|
8474
8492
|
},
|
|
8475
8493
|
"credential": {
|
|
@@ -8750,9 +8768,11 @@
|
|
|
8750
8768
|
"method": {
|
|
8751
8769
|
"type": "string",
|
|
8752
8770
|
"enum": [
|
|
8771
|
+
"GET",
|
|
8753
8772
|
"POST",
|
|
8754
8773
|
"PUT",
|
|
8755
|
-
"PATCH"
|
|
8774
|
+
"PATCH",
|
|
8775
|
+
"DELETE"
|
|
8756
8776
|
]
|
|
8757
8777
|
},
|
|
8758
8778
|
"credential": {
|
|
@@ -8872,9 +8892,11 @@
|
|
|
8872
8892
|
"method": {
|
|
8873
8893
|
"type": "string",
|
|
8874
8894
|
"enum": [
|
|
8895
|
+
"GET",
|
|
8875
8896
|
"POST",
|
|
8876
8897
|
"PUT",
|
|
8877
|
-
"PATCH"
|
|
8898
|
+
"PATCH",
|
|
8899
|
+
"DELETE"
|
|
8878
8900
|
]
|
|
8879
8901
|
},
|
|
8880
8902
|
"credential": {
|
|
@@ -9055,9 +9077,11 @@
|
|
|
9055
9077
|
"method": {
|
|
9056
9078
|
"type": "string",
|
|
9057
9079
|
"enum": [
|
|
9080
|
+
"GET",
|
|
9058
9081
|
"POST",
|
|
9059
9082
|
"PUT",
|
|
9060
|
-
"PATCH"
|
|
9083
|
+
"PATCH",
|
|
9084
|
+
"DELETE"
|
|
9061
9085
|
]
|
|
9062
9086
|
},
|
|
9063
9087
|
"credential": {
|
|
@@ -9331,9 +9355,11 @@
|
|
|
9331
9355
|
"method": {
|
|
9332
9356
|
"type": "string",
|
|
9333
9357
|
"enum": [
|
|
9358
|
+
"GET",
|
|
9334
9359
|
"POST",
|
|
9335
9360
|
"PUT",
|
|
9336
|
-
"PATCH"
|
|
9361
|
+
"PATCH",
|
|
9362
|
+
"DELETE"
|
|
9337
9363
|
]
|
|
9338
9364
|
},
|
|
9339
9365
|
"credential": {
|
|
@@ -9614,9 +9640,11 @@
|
|
|
9614
9640
|
"method": {
|
|
9615
9641
|
"type": "string",
|
|
9616
9642
|
"enum": [
|
|
9643
|
+
"GET",
|
|
9617
9644
|
"POST",
|
|
9618
9645
|
"PUT",
|
|
9619
|
-
"PATCH"
|
|
9646
|
+
"PATCH",
|
|
9647
|
+
"DELETE"
|
|
9620
9648
|
]
|
|
9621
9649
|
},
|
|
9622
9650
|
"credential": {
|
|
@@ -23476,7 +23504,7 @@
|
|
|
23476
23504
|
"Sessions API"
|
|
23477
23505
|
],
|
|
23478
23506
|
"summary": "Open a session",
|
|
23479
|
-
"description": "Creates the session, or
|
|
23507
|
+
"description": "Creates the session, or answers the one already opened with the same agent, owner, info and Environment. Its Environment (its sandbox and vault) is chosen now and fixed for its life.",
|
|
23480
23508
|
"security": [
|
|
23481
23509
|
{
|
|
23482
23510
|
"applicationKey": []
|
|
@@ -96,7 +96,7 @@ export async function assertCurrentLayout(q) {
|
|
|
96
96
|
if (row?.versioned)
|
|
97
97
|
throw openError("database-layout-old", "The database was created by a pre-release build of one Tenant per database, whose " +
|
|
98
98
|
"migrations this release replaces. It is never changed: point the Runtime at a new " +
|
|
99
|
-
"database (locally, `nylorun reset` and then `nylorun start`).");
|
|
99
|
+
"database (locally, `nylorun local reset` and then `nylorun start`).");
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
102
|
* The database's schema version: the number of migrations its journal records, or undefined
|
|
@@ -935,11 +935,14 @@ export async function checkEnvironmentTurn(t, session, scope, ctx) {
|
|
|
935
935
|
code: "environment_owner_mismatch",
|
|
936
936
|
});
|
|
937
937
|
// The harness the turn would run on (R4.1, Q9): a pod about to wake runs its recipe's. A
|
|
938
|
-
// session never moves to another harness: its state is that harness's.
|
|
938
|
+
// session never moves to another harness: its state is that harness's. An Environment's
|
|
939
|
+
// harness never changes since protocol 14, so this refuses a session whose Environment id was
|
|
940
|
+
// deleted and made again with another harness, and an Environment changed in place before
|
|
941
|
+
// protocol 14 whose recipe (a pod's, at its wake) names another harness than it applied.
|
|
939
942
|
const waking = environment.pod !== undefined && (environment.pod.desired !== "running" || environment.pod.observed === "failed");
|
|
940
943
|
const runs = waking ? environment.recipe.harness : environment.applied.harness;
|
|
941
944
|
if (!isWorkflowManifest(session.manifest) && runs !== harnessOf(session))
|
|
942
|
-
fail(409, `Environment ${id}
|
|
945
|
+
fail(409, `Environment ${id} runs the ${runs} harness, and this session runs ${harnessOf(session)}: open a new session to run on it.`, {
|
|
943
946
|
code: "harness_mismatch",
|
|
944
947
|
details: { harness: harnessOf(session), environmentHarness: runs },
|
|
945
948
|
});
|
|
@@ -31,7 +31,7 @@ export interface StartEphemeralRuntimeOptions {
|
|
|
31
31
|
/** When true, close() leaves hostRoot on disk. */
|
|
32
32
|
retainRoot?: boolean;
|
|
33
33
|
/**
|
|
34
|
-
* Trusted issuers whose JWTs the
|
|
34
|
+
* Trusted issuers whose JWTs the Runtime API accepts (Host feature `trusted-issuers`): the
|
|
35
35
|
* issuers of an identity file (`parseIdentityFile`), or ones already built with
|
|
36
36
|
* `createTrustedIssuers`. Default none.
|
|
37
37
|
*/
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*
|
|
17
17
|
* The host token is accepted only by the Harness API listener (a connection serving that one
|
|
18
18
|
* sandbox, and `host.renew`); the egress token only by egress-gate, as the proxy credential
|
|
19
|
-
* (`Proxy-Authorization`). Neither is a bearer anywhere else: the
|
|
19
|
+
* (`Proxy-Authorization`). Neither is a bearer anywhere else: the Runtime API's bearer check
|
|
20
20
|
* accepts trusted issuers' tokens only, and the gates run tokens only.
|
|
21
21
|
*
|
|
22
22
|
* Verification reads the key row on every call (a revoked key refuses at once) and, with
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The identity file (Host feature `trusted-issuers`, F9 I2): the YAML file
|
|
3
|
-
* `NYLORUN_IDENTITY_FILE` names, listing the issuers whose JWTs the
|
|
3
|
+
* `NYLORUN_IDENTITY_FILE` names, listing the issuers whose JWTs the Runtime API accepts as
|
|
4
4
|
* bearers. Read once at boot (`host/main.ts`); a change takes a restart. A malformed file stops
|
|
5
5
|
* the boot with a message naming the issuer and the field. A key the file does not define is
|
|
6
6
|
* ignored with a warning (`maxLifetime`, gone in protocol 9, among them), so an older file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The identity file (Host feature `trusted-issuers`, F9 I2): the YAML file
|
|
3
|
-
* `NYLORUN_IDENTITY_FILE` names, listing the issuers whose JWTs the
|
|
3
|
+
* `NYLORUN_IDENTITY_FILE` names, listing the issuers whose JWTs the Runtime API accepts as
|
|
4
4
|
* bearers. Read once at boot (`host/main.ts`); a change takes a restart. A malformed file stops
|
|
5
5
|
* the boot with a message naming the issuer and the field. A key the file does not define is
|
|
6
6
|
* ignored with a warning (`maxLifetime`, gone in protocol 9, among them), so an older file
|
|
@@ -37,14 +37,15 @@ export declare function isPrivateAddress(address: string): boolean;
|
|
|
37
37
|
/** Why the Host refuses `url`, or `undefined` when it may be called. */
|
|
38
38
|
export declare function refusal(url: URL, policy: OutboundPolicy): string | undefined;
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Sends one request to `url` under `policy`: with `method` (default `POST`) and the JSON `body`,
|
|
41
|
+
* or with no body (and no `content-type`) when `body` is undefined, as for a `GET`. Never
|
|
41
42
|
* throws; `signal` aborts the request.
|
|
42
43
|
*/
|
|
43
|
-
export declare function
|
|
44
|
+
export declare function send(target: string, body: string | undefined, headers: Record<string, string>, options: {
|
|
44
45
|
policy: OutboundPolicy;
|
|
45
46
|
signal: AbortSignal;
|
|
46
47
|
maxResponseBytes?: number;
|
|
47
|
-
method?: "POST" | "PUT" | "PATCH";
|
|
48
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
48
49
|
}): Promise<OutboundResult>;
|
|
49
50
|
/**
|
|
50
51
|
* A refusal of `guardedFetch`: the Host's policy forbids the URL or every address it resolves
|
|
@@ -59,13 +60,13 @@ export declare class OutboundRefused extends Error {
|
|
|
59
60
|
export declare class OutboundFailed extends Error {
|
|
60
61
|
readonly code: string;
|
|
61
62
|
/**
|
|
62
|
-
* The request was sent in full before it failed, as `
|
|
63
|
+
* The request was sent in full before it failed, as `send()`'s `lost` (R2b C7): the server
|
|
63
64
|
* may have acted on it. False for a failure to resolve or connect.
|
|
64
65
|
*/
|
|
65
66
|
readonly sent: boolean;
|
|
66
67
|
constructor(message: string, code: string,
|
|
67
68
|
/**
|
|
68
|
-
* The request was sent in full before it failed, as `
|
|
69
|
+
* The request was sent in full before it failed, as `send()`'s `lost` (R2b C7): the server
|
|
69
70
|
* may have acted on it. False for a failure to resolve or connect.
|
|
70
71
|
*/
|
|
71
72
|
sent?: boolean);
|
package/dist/tenant/outbound.js
CHANGED
|
@@ -76,10 +76,11 @@ function guardedLookup(policy) {
|
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
|
-
*
|
|
79
|
+
* Sends one request to `url` under `policy`: with `method` (default `POST`) and the JSON `body`,
|
|
80
|
+
* or with no body (and no `content-type`) when `body` is undefined, as for a `GET`. Never
|
|
80
81
|
* throws; `signal` aborts the request.
|
|
81
82
|
*/
|
|
82
|
-
export async function
|
|
83
|
+
export async function send(target, body, headers, options) {
|
|
83
84
|
const { policy, signal } = options;
|
|
84
85
|
const limit = options.maxResponseBytes ?? MAX_RESPONSE_BYTES;
|
|
85
86
|
const url = new URL(target);
|
|
@@ -108,8 +109,9 @@ export async function post(target, body, headers, options) {
|
|
|
108
109
|
headers: {
|
|
109
110
|
...headers,
|
|
110
111
|
host: originalHost,
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
...(body === undefined
|
|
113
|
+
? {}
|
|
114
|
+
: { "content-type": "application/json", "content-length": String(Buffer.byteLength(body)) }),
|
|
113
115
|
},
|
|
114
116
|
lookup: lookup,
|
|
115
117
|
signal,
|
|
@@ -156,7 +158,7 @@ export class OutboundFailed extends Error {
|
|
|
156
158
|
sent;
|
|
157
159
|
constructor(message, code,
|
|
158
160
|
/**
|
|
159
|
-
* The request was sent in full before it failed, as `
|
|
161
|
+
* The request was sent in full before it failed, as `send()`'s `lost` (R2b C7): the server
|
|
160
162
|
* may have acted on it. False for a failure to resolve or connect.
|
|
161
163
|
*/
|
|
162
164
|
sent = false) {
|
|
@@ -223,7 +225,7 @@ export function guardedFetch(policy, options = {}) {
|
|
|
223
225
|
outgoing["content-length"] = String(body.byteLength);
|
|
224
226
|
return await new Promise((resolve, reject) => {
|
|
225
227
|
let settled = false;
|
|
226
|
-
// Set when the request is fully sent, as `
|
|
228
|
+
// Set when the request is fully sent, as `send()` does: a failure after it may follow
|
|
227
229
|
// the server acting on the request.
|
|
228
230
|
let delivered = false;
|
|
229
231
|
const settle = (fn) => {
|
package/dist/tenant/types.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export interface TenantConfig {
|
|
|
75
75
|
*/
|
|
76
76
|
flowEnv?: Readonly<Record<string, string | undefined>>;
|
|
77
77
|
/**
|
|
78
|
-
* The trusted issuers whose JWTs the
|
|
78
|
+
* The trusted issuers whose JWTs the Runtime API accepts (Host feature `trusted-issuers`), from
|
|
79
79
|
* the identity file (`NYLORUN_IDENTITY_FILE`). Absent: none.
|
|
80
80
|
*/
|
|
81
81
|
issuers?: import("./issuers.js").TrustedIssuers;
|
|
@@ -107,7 +107,7 @@ export interface TenantHandle {
|
|
|
107
107
|
/** The handlers Durable Session Execution calls for this Tenant (`worker.ts`). */
|
|
108
108
|
readonly worker?: TenantWorker;
|
|
109
109
|
/**
|
|
110
|
-
* A
|
|
110
|
+
* A Runtime or Management API request whose headers the Host has validated: authenticates, authorizes,
|
|
111
111
|
* dispatches. A response already written to `node.outgoing` is `RESPONSE_ALREADY_SENT`.
|
|
112
112
|
*/
|
|
113
113
|
fetch(request: Request, node: NodeBindings): Promise<Response>;
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const RUNTIME_VERSION = "0.
|
|
1
|
+
export declare const RUNTIME_VERSION = "0.26.0-beta";
|
package/dist/version.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Kept in step with package.json by runtime/server/scripts/check-package.mjs, which runs in npm run check.
|
|
2
2
|
// release:prepare also rewrites this when it bumps @nylorun/runtime.
|
|
3
|
-
export const RUNTIME_VERSION = "0.
|
|
3
|
+
export const RUNTIME_VERSION = "0.26.0-beta";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nylorun/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0-beta",
|
|
4
4
|
"description": "Nylorun Runtime: the agent execution Host on Postgres, Restate and S2, and model providers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"@hono/node-server": "^2.1.3",
|
|
66
66
|
"@hono/zod-openapi": "^1.6.3",
|
|
67
67
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
68
|
-
"@nylorun/core": "0.
|
|
69
|
-
"@nylorun/harness": "0.27.
|
|
68
|
+
"@nylorun/core": "0.22.0-beta",
|
|
69
|
+
"@nylorun/harness": "0.27.1-beta",
|
|
70
70
|
"@restatedev/restate-sdk": "1.17.2",
|
|
71
71
|
"@restatedev/restate-sdk-clients": "1.17.2",
|
|
72
72
|
"@s2-dev/streamstore": "0.28.0",
|