@nylorun/runtime 0.23.0-beta → 0.25.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 +252 -0
- package/README.md +87 -28
- package/dist/adapters/execution/restate.js +1 -1
- package/dist/adapters/replication/pgoutput.d.ts +2 -0
- package/dist/adapters/replication/pgoutput.js +6 -3
- package/dist/adapters/sandbox/local.d.ts +9 -1
- package/dist/adapters/sandbox/local.js +16 -4
- package/dist/adapters/sandbox/virtual.js +4 -1
- package/dist/api/a2a/card.d.ts +11 -1
- package/dist/api/a2a/card.js +26 -2
- package/dist/api/a2a/endpoint.js +9 -3
- package/dist/api/a2a/protocol.d.ts +25 -2
- package/dist/api/a2a/protocol.js +20 -3
- package/dist/api/a2a/routes.d.ts +6 -1
- package/dist/api/a2a/routes.js +67 -9
- package/dist/api/a2a/tasks.js +2 -1
- package/dist/api/ag-ui/endpoint.js +8 -3
- package/dist/api/ag-ui/history.d.ts +6 -1
- package/dist/api/ag-ui/history.js +39 -3
- package/dist/api/ag-ui/routes.d.ts +4 -1
- package/dist/api/ag-ui/routes.js +63 -20
- package/dist/api/ag-ui/translate.js +3 -2
- package/dist/api/components.d.ts +5327 -1091
- package/dist/api/components.js +40 -16
- package/dist/api/gate/keys.d.ts +2 -1
- package/dist/api/gate/keys.js +14 -1
- package/dist/api/gate/routes.d.ts +6 -0
- package/dist/api/gate/routes.js +52 -3
- package/dist/api/http/app.js +17 -6
- package/dist/api/http/body.d.ts +3 -3
- package/dist/api/http/body.js +7 -7
- package/dist/api/http/define.d.ts +6 -0
- package/dist/api/http/define.js +13 -1
- package/dist/api/http/respond.js +1 -1
- package/dist/api/http/routes/artifacts.js +35 -8
- package/dist/api/http/routes/coverage.d.ts +9 -0
- package/dist/api/http/routes/coverage.js +34 -0
- package/dist/api/http/routes/environment-manifests.d.ts +9 -0
- package/dist/api/http/routes/environment-manifests.js +118 -0
- package/dist/api/http/routes/environments.d.ts +11 -0
- package/dist/api/http/routes/environments.js +332 -0
- package/dist/api/http/routes/mcp.d.ts +1 -1
- package/dist/api/http/routes/mcp.js +2 -2
- package/dist/api/http/routes/me.js +1 -1
- package/dist/api/http/routes/reads.d.ts +94 -9
- package/dist/api/http/routes/reads.js +54 -5
- package/dist/api/http/routes/sessions.js +24 -9
- package/dist/api/http/routes/tenant.js +65 -15
- package/dist/api/inbound-files.d.ts +65 -0
- package/dist/api/inbound-files.js +115 -0
- package/dist/api/openapi.js +48 -28
- package/dist/artifacts/disk.d.ts +59 -0
- package/dist/artifacts/disk.js +569 -0
- package/dist/artifacts/export.d.ts +1 -1
- package/dist/artifacts/export.js +2 -3
- package/dist/artifacts/folders.d.ts +6 -3
- package/dist/artifacts/folders.js +17 -12
- package/dist/artifacts/media-types.d.ts +15 -0
- package/dist/artifacts/media-types.js +56 -4
- package/dist/artifacts/parts.d.ts +12 -3
- package/dist/artifacts/parts.js +15 -4
- package/dist/artifacts/service.d.ts +2 -1
- package/dist/artifacts/service.js +6 -1
- package/dist/artifacts/workspace.d.ts +5 -5
- package/dist/artifacts/workspace.js +7 -19
- package/dist/core/flow-host.d.ts +3 -4
- package/dist/core/flow-host.js +5 -2
- package/dist/core/provider.d.ts +3 -2
- package/dist/core/provider.js +5 -37
- package/dist/core/sandbox-routes.d.ts +2 -21
- package/dist/core/sandbox-routes.js +11 -44
- package/dist/core/turn-manifest.d.ts +3 -2
- package/dist/core/turn-manifest.js +29 -5
- package/dist/execution/types.d.ts +1 -1
- package/dist/gates/contract.d.ts +3 -24
- package/dist/gates/contract.js +1 -36
- package/dist/gates/egress-credentials.d.ts +9 -0
- package/dist/gates/egress-credentials.js +11 -4
- package/dist/gates/egress.d.ts +22 -1
- package/dist/gates/egress.js +116 -10
- package/dist/gates/fixture-model.d.ts +28 -0
- package/dist/gates/fixture-model.js +92 -0
- package/dist/gates/handler.js +4 -4
- package/dist/gates/http-tool.d.ts +9 -6
- package/dist/gates/http-tool.js +11 -17
- package/dist/gates/in-process.d.ts +5 -0
- package/dist/gates/in-process.js +12 -1
- package/dist/gates/journal.d.ts +30 -0
- package/dist/gates/journal.js +51 -0
- package/dist/gates/mcp-handler.d.ts +4 -0
- package/dist/gates/mcp-handler.js +7 -4
- package/dist/gates/meter.d.ts +10 -2
- package/dist/gates/meter.js +20 -5
- package/dist/gates/policy.d.ts +49 -0
- package/dist/gates/policy.js +132 -0
- package/dist/gates/tenant-vaults.d.ts +7 -7
- package/dist/gates/tenant-vaults.js +5 -5
- package/dist/gates/tool-calls.d.ts +10 -5
- package/dist/gates/tool-calls.js +28 -10
- package/dist/gates/tool-client.d.ts +8 -0
- package/dist/gates/tool-client.js +27 -11
- package/dist/gates/tool-contract.d.ts +11 -69
- package/dist/gates/tool-contract.js +1 -85
- package/dist/gates/tool-gate.d.ts +1 -1
- package/dist/harness/calls.d.ts +14 -7
- package/dist/harness/calls.js +30 -24
- package/dist/harness/executors.js +12 -9
- package/dist/harness/main.js +24 -5
- package/dist/harness/pod.d.ts +39 -0
- package/dist/harness/pod.js +46 -0
- package/dist/harness/service.d.ts +0 -1
- package/dist/harness/service.js +17 -9
- package/dist/harness/setup.d.ts +29 -0
- package/dist/harness/setup.js +174 -0
- package/dist/harness/ws-client.js +3 -2
- package/dist/harness/ws-port.d.ts +1 -5
- package/dist/harness/ws-port.js +1 -5
- package/dist/harness-api/in-process.js +3 -3
- package/dist/harness-api/record.d.ts +15 -1
- package/dist/harness-api/record.js +180 -50
- package/dist/harness-api/redact.d.ts +3 -0
- package/dist/harness-api/redact.js +45 -0
- package/dist/harness-api/server.d.ts +35 -4
- package/dist/harness-api/server.js +130 -17
- package/dist/harness-api/start.d.ts +10 -3
- package/dist/harness-api/start.js +40 -10
- package/dist/harness-api/tool-journal.d.ts +105 -0
- package/dist/harness-api/tool-journal.js +132 -0
- package/dist/harness-api/tool-status.d.ts +13 -0
- package/dist/harness-api/tool-status.js +26 -0
- package/dist/harness-api/workspace.d.ts +12 -7
- package/dist/harness-api/workspace.js +47 -25
- package/dist/harness-api/ws-server.d.ts +11 -3
- package/dist/harness-api/ws-server.js +94 -15
- package/dist/host/gates.d.ts +2 -1
- package/dist/host/gates.js +10 -2
- package/dist/host/main.js +54 -5
- package/dist/host/operate.js +67 -5
- package/dist/host/stack-config.d.ts +64 -0
- package/dist/host/stack-config.js +62 -2
- package/dist/keys/client.js +4 -1
- package/dist/keys/keys.d.ts +13 -6
- package/dist/keys/keys.js +9 -8
- package/dist/management-openapi.json +1264 -2171
- package/dist/mcp/connect.d.ts +26 -22
- package/dist/mcp/connect.js +30 -34
- package/dist/mcp/pool.d.ts +3 -6
- package/dist/mcp/pool.js +14 -28
- package/dist/mcp/preview.d.ts +3 -3
- package/dist/mcp/preview.js +10 -21
- package/dist/mcp/snapshot.d.ts +16 -24
- package/dist/mcp/snapshot.js +33 -45
- package/dist/model/capabilities.d.ts +26 -0
- package/dist/model/capabilities.js +44 -0
- package/dist/model/catalog.d.ts +34 -3
- package/dist/model/catalog.js +38 -2
- package/dist/model/models.d.ts +2 -0
- package/dist/model/models.js +1 -1
- package/dist/model/native-blocks.d.ts +35 -0
- package/dist/model/native-blocks.js +170 -0
- package/dist/model/pi-model.js +114 -94
- package/dist/openapi.json +12822 -3943
- package/dist/reads/types.d.ts +16 -3
- package/dist/record/append.d.ts +3 -1
- package/dist/record/append.js +1 -0
- package/dist/record/envelope.d.ts +5 -1
- package/dist/record/envelope.js +7 -3
- package/dist/record/environment.d.ts +25 -0
- package/dist/record/environment.js +44 -0
- package/dist/record/index.d.ts +1 -1
- package/dist/record/index.js +1 -1
- package/dist/sandbox/disk-fs.d.ts +95 -0
- package/dist/sandbox/disk-fs.js +206 -0
- package/dist/sandbox/join.d.ts +17 -18
- package/dist/sandbox/join.js +46 -15
- package/dist/sandbox/manager.d.ts +47 -21
- package/dist/sandbox/manager.js +162 -107
- package/dist/sandbox/placement.d.ts +14 -13
- package/dist/sandbox/placement.js +31 -14
- package/dist/sandbox/pods/client.d.ts +9 -2
- package/dist/sandbox/pods/lifecycle.d.ts +36 -27
- package/dist/sandbox/pods/lifecycle.js +29 -26
- package/dist/sandbox/pods/reconcile.js +18 -12
- package/dist/sandbox/pods/spec.d.ts +15 -13
- package/dist/sandbox/pods/spec.js +17 -20
- package/dist/sandbox/records.d.ts +2 -2
- package/dist/sandbox/records.js +3 -3
- package/dist/sandbox/resolve.d.ts +37 -27
- package/dist/sandbox/resolve.js +73 -41
- package/dist/sandbox/runtime-tools.d.ts +9 -0
- package/dist/sandbox/runtime-tools.js +16 -0
- package/dist/sandbox/session-sandbox.d.ts +4 -6
- package/dist/sandbox/session-sandbox.js +47 -94
- package/dist/sandbox/setup.d.ts +64 -0
- package/dist/sandbox/setup.js +160 -0
- package/dist/sandbox/share.d.ts +21 -26
- package/dist/sandbox/share.js +36 -63
- package/dist/sandbox/skills.d.ts +8 -6
- package/dist/sandbox/skills.js +24 -23
- package/dist/sandbox/tenant-config.d.ts +12 -14
- package/dist/sandbox/tenant-config.js +12 -17
- package/dist/sandbox/types.d.ts +6 -0
- package/dist/store/postgres/drizzle/0020_environments.sql +63 -0
- package/dist/store/postgres/drizzle/0021_disk_versions.sql +7 -0
- package/dist/store/postgres/drizzle/0022_model_usage_timing.sql +5 -0
- package/dist/store/postgres/drizzle/0023_artifact_pages.sql +1 -0
- package/dist/store/postgres/drizzle/0024_flat_manifest.sql +7 -0
- package/dist/store/postgres/drizzle/0025_environment_manifests.sql +14 -0
- package/dist/store/postgres/drizzle/0026_environment_forks.sql +1 -0
- package/dist/store/postgres/drizzle/0027_environment_image_digest.sql +1 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +56 -0
- package/dist/store/postgres/reads.js +123 -17
- package/dist/store/postgres/record-writer.d.ts +4 -4
- package/dist/store/postgres/record-writer.js +9 -9
- package/dist/store/postgres/record.d.ts +7 -0
- package/dist/store/postgres/record.js +23 -2
- package/dist/store/postgres/schema.d.ts +1126 -736
- package/dist/store/postgres/schema.js +136 -73
- package/dist/store/postgres/store.js +195 -67
- package/dist/store/types.d.ts +165 -50
- package/dist/tenant/advance.d.ts +7 -6
- package/dist/tenant/advance.js +118 -42
- package/dist/tenant/artifact-tool.d.ts +1 -1
- package/dist/tenant/artifact-tool.js +46 -26
- package/dist/tenant/commands.d.ts +15 -2
- package/dist/tenant/commands.js +115 -14
- package/dist/tenant/context.d.ts +56 -24
- package/dist/tenant/context.js +4 -15
- package/dist/tenant/effects.d.ts +1 -1
- package/dist/tenant/effects.js +44 -29
- package/dist/tenant/environment-manifests.d.ts +57 -0
- package/dist/tenant/environment-manifests.js +200 -0
- package/dist/tenant/environments.d.ts +174 -0
- package/dist/tenant/environments.js +1044 -0
- package/dist/tenant/harness-tokens.d.ts +21 -0
- package/dist/tenant/harness-tokens.js +61 -0
- package/dist/tenant/host-token.d.ts +1 -1
- package/dist/tenant/host-token.js +2 -4
- package/dist/tenant/identity-file.d.ts +4 -4
- package/dist/tenant/identity-file.js +17 -8
- package/dist/tenant/issuers.js +3 -3
- package/dist/tenant/model-setting.d.ts +14 -0
- package/dist/tenant/model-setting.js +51 -0
- package/dist/tenant/principals.js +1 -1
- package/dist/tenant/reset.js +3 -3
- package/dist/tenant/runtime.d.ts +6 -1
- package/dist/tenant/runtime.js +7 -1
- package/dist/tenant/session.d.ts +3 -3
- package/dist/tenant/session.js +0 -14
- package/dist/tenant/sessions.d.ts +18 -14
- package/dist/tenant/sessions.js +99 -143
- package/dist/tenant/signing-keys.d.ts +5 -1
- package/dist/tenant/skill-tool.d.ts +3 -3
- package/dist/tenant/skill-tool.js +6 -11
- package/dist/tenant/status.js +3 -3
- package/dist/tenant/sweep.js +13 -7
- package/dist/tenant/tool-results.js +1 -1
- package/dist/tenant/tool-search.d.ts +7 -11
- package/dist/tenant/tool-search.js +8 -5
- package/dist/tenant/transcript.d.ts +245 -36
- package/dist/tenant/transcript.js +64 -12
- package/dist/tenant/turn-timing.d.ts +43 -0
- package/dist/tenant/turn-timing.js +39 -0
- package/dist/tenant/types.d.ts +2 -0
- package/dist/traces/ids.d.ts +41 -0
- package/dist/traces/ids.js +81 -0
- package/dist/traces/key.d.ts +6 -0
- package/dist/traces/key.js +37 -0
- package/dist/traces/map.d.ts +113 -0
- package/dist/traces/map.js +289 -0
- package/dist/traces/options.d.ts +7 -0
- package/dist/traces/options.js +1 -0
- package/dist/traces/otlp.d.ts +42 -0
- package/dist/traces/otlp.js +84 -0
- package/dist/traces/projector.d.ts +58 -0
- package/dist/traces/projector.js +200 -0
- package/dist/traces/read.d.ts +23 -0
- package/dist/traces/read.js +16 -0
- package/dist/vault/coverage.d.ts +26 -0
- package/dist/vault/coverage.js +62 -0
- package/dist/vault/error.d.ts +11 -1
- package/dist/vault/error.js +5 -1
- package/dist/vault/host-model.d.ts +4 -1
- package/dist/vault/host-model.js +10 -2
- package/dist/vault/service.d.ts +92 -48
- package/dist/vault/service.js +462 -376
- package/dist/vault/sources.d.ts +5 -16
- package/dist/vault/sources.js +6 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/package.json +13 -13
- package/dist/api/http/routes/sandboxes.d.ts +0 -9
- package/dist/api/http/routes/sandboxes.js +0 -153
- package/dist/api/http/routes/vaults.d.ts +0 -10
- package/dist/api/http/routes/vaults.js +0 -139
- package/dist/record/sandbox.d.ts +0 -25
- package/dist/record/sandbox.js +0 -43
- package/dist/sandbox/capability.d.ts +0 -3
- package/dist/sandbox/capability.js +0 -10
- package/dist/tenant/sandboxes.d.ts +0 -123
- package/dist/tenant/sandboxes.js +0 -566
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SessionStore } from "../store/types.js";
|
|
2
|
+
export declare const HARNESS_TOKENS_SETTING = "harness.tokens";
|
|
3
|
+
export interface HarnessTokenInfo {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly createdAt: string;
|
|
6
|
+
}
|
|
7
|
+
export type HarnessTokenRefusal = {
|
|
8
|
+
readonly reason: "invalid_id";
|
|
9
|
+
readonly message: string;
|
|
10
|
+
};
|
|
11
|
+
/** The harness id `token` is for, or undefined when it is none of the Tenant's harness tokens. */
|
|
12
|
+
export declare function harnessOfToken(store: SessionStore, token: string): Promise<string | undefined>;
|
|
13
|
+
/** Creates or rotates harness `id`'s token; the token is returned this once. */
|
|
14
|
+
export declare function putHarnessToken(store: SessionStore, id: string): Promise<{
|
|
15
|
+
id: string;
|
|
16
|
+
token: string;
|
|
17
|
+
rotated: boolean;
|
|
18
|
+
} | HarnessTokenRefusal>;
|
|
19
|
+
export declare function listHarnessTokens(store: SessionStore): Promise<HarnessTokenInfo[]>;
|
|
20
|
+
/** Deletes harness `id`'s token; whether there was one. */
|
|
21
|
+
export declare function deleteHarnessToken(store: SessionStore, id: string): Promise<boolean>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-harness tokens (R4.1): the credential a custom harness's container connects to the Harness
|
|
3
|
+
* API listener with. Each is bound to one harness id, so a harness can only say that id in
|
|
4
|
+
* `hello` and only take the sessions pinned to it. Our harness keeps the installation's
|
|
5
|
+
* `NYLORUN_HARNESS_TOKEN`, bound to `nylorun`; a pod's harness holds neither (it joins).
|
|
6
|
+
*
|
|
7
|
+
* The Tenant setting `harness.tokens` keeps each token's sha256 and when it was made, never the
|
|
8
|
+
* token: `nylorun-operate harness token put <id>` prints it once. Putting an id again rotates its
|
|
9
|
+
* token; the old one stops working at its next connection.
|
|
10
|
+
*/
|
|
11
|
+
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
12
|
+
import { DEFAULT_HARNESS, isHarnessId } from "@nylorun/core/contracts";
|
|
13
|
+
export const HARNESS_TOKENS_SETTING = "harness.tokens";
|
|
14
|
+
const sha256 = (token) => createHash("sha256").update(token).digest("hex");
|
|
15
|
+
async function read(store) {
|
|
16
|
+
const raw = await store.tx((t) => t.getSetting(HARNESS_TOKENS_SETTING));
|
|
17
|
+
return raw === undefined ? {} : JSON.parse(raw);
|
|
18
|
+
}
|
|
19
|
+
/** The harness id `token` is for, or undefined when it is none of the Tenant's harness tokens. */
|
|
20
|
+
export async function harnessOfToken(store, token) {
|
|
21
|
+
const hash = Buffer.from(sha256(token), "hex");
|
|
22
|
+
for (const [id, stored] of Object.entries(await read(store))) {
|
|
23
|
+
const candidate = Buffer.from(stored.sha256, "hex");
|
|
24
|
+
if (candidate.length === hash.length && timingSafeEqual(candidate, hash))
|
|
25
|
+
return id;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
/** Creates or rotates harness `id`'s token; the token is returned this once. */
|
|
30
|
+
export async function putHarnessToken(store, id) {
|
|
31
|
+
if (!isHarnessId(id))
|
|
32
|
+
return { reason: "invalid_id", message: `${id} is not a harness id: lowercase letters, digits and dashes, starting with a letter` };
|
|
33
|
+
if (id === DEFAULT_HARNESS)
|
|
34
|
+
return { reason: "invalid_id", message: `${DEFAULT_HARNESS} is our harness: it connects with NYLORUN_HARNESS_TOKEN` };
|
|
35
|
+
const token = randomBytes(32).toString("hex");
|
|
36
|
+
return store.tx(async (t) => {
|
|
37
|
+
const raw = await t.getSetting(HARNESS_TOKENS_SETTING);
|
|
38
|
+
const tokens = raw === undefined ? {} : JSON.parse(raw);
|
|
39
|
+
const rotated = id in tokens;
|
|
40
|
+
tokens[id] = { sha256: sha256(token), createdAt: new Date().toISOString() };
|
|
41
|
+
await t.putSetting(HARNESS_TOKENS_SETTING, JSON.stringify(tokens));
|
|
42
|
+
return { id, token, rotated };
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export async function listHarnessTokens(store) {
|
|
46
|
+
return Object.entries(await read(store))
|
|
47
|
+
.map(([id, stored]) => ({ id, createdAt: stored.createdAt }))
|
|
48
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
49
|
+
}
|
|
50
|
+
/** Deletes harness `id`'s token; whether there was one. */
|
|
51
|
+
export async function deleteHarnessToken(store, id) {
|
|
52
|
+
return store.tx(async (t) => {
|
|
53
|
+
const raw = await t.getSetting(HARNESS_TOKENS_SETTING);
|
|
54
|
+
const tokens = raw === undefined ? {} : JSON.parse(raw);
|
|
55
|
+
if (!(id in tokens))
|
|
56
|
+
return false;
|
|
57
|
+
delete tokens[id];
|
|
58
|
+
await t.putSetting(HARNESS_TOKENS_SETTING, JSON.stringify(tokens));
|
|
59
|
+
return true;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -85,7 +85,7 @@ declare const KINDS: {
|
|
|
85
85
|
export declare function verifyHostToken(store: SessionStore, tenantId: string, raw: string, kind: keyof typeof KINDS, cache?: HostTokenKeyCache): Promise<HostTokenVerdict>;
|
|
86
86
|
/**
|
|
87
87
|
* Why a host's claims are stale, or undefined while they are its sandbox's current host: the
|
|
88
|
-
* sandbox exists as a pod
|
|
88
|
+
* sandbox exists as a pod Environment, is not deleted or lost, and its epoch and pod are
|
|
89
89
|
* the token's. One indexed read of the sandbox's row.
|
|
90
90
|
*/
|
|
91
91
|
export declare function staleHost(store: SessionStore, claims: HostClaims): Promise<string | undefined>;
|
|
@@ -157,11 +157,11 @@ export async function verifyHostToken(store, tenantId, raw, kind, cache = new Ma
|
|
|
157
157
|
}
|
|
158
158
|
/**
|
|
159
159
|
* Why a host's claims are stale, or undefined while they are its sandbox's current host: the
|
|
160
|
-
* sandbox exists as a pod
|
|
160
|
+
* sandbox exists as a pod Environment, is not deleted or lost, and its epoch and pod are
|
|
161
161
|
* the token's. One indexed read of the sandbox's row.
|
|
162
162
|
*/
|
|
163
163
|
export async function staleHost(store, claims) {
|
|
164
|
-
const row = await store.tx((t) => t.
|
|
164
|
+
const row = await store.tx((t) => t.environment(claims.sandboxId));
|
|
165
165
|
const pod = row?.pod;
|
|
166
166
|
if (!row || row.kind !== "pod" || !pod)
|
|
167
167
|
return "the sandbox is gone";
|
|
@@ -169,8 +169,6 @@ export async function staleHost(store, claims) {
|
|
|
169
169
|
return "the sandbox was deleted";
|
|
170
170
|
if (pod.observed === "lost")
|
|
171
171
|
return "the sandbox was lost";
|
|
172
|
-
if (pod.observed === "expired")
|
|
173
|
-
return "the sandbox expired";
|
|
174
172
|
if (pod.hostEpoch !== claims.epoch)
|
|
175
173
|
return "another host holds the sandbox now";
|
|
176
174
|
if (pod.podUid !== claims.podUid)
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* # Optional, with their defaults:
|
|
16
16
|
* subject: "{sub}" # scalar claims only
|
|
17
17
|
* scopes: { claim: scope } # or { fixed: [sessions:own, agents:read] }
|
|
18
|
-
* allowedScopes: [agents:read, sessions:own,
|
|
18
|
+
* allowedScopes: [agents:read, sessions:own, environments:write] # add studio to grant it
|
|
19
19
|
* agents: [support] # absent reaches every agent
|
|
20
|
-
*
|
|
20
|
+
* environments: ["{org_id}/*"] # absent reaches no Environment
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
import { type KeyObject } from "node:crypto";
|
|
@@ -55,8 +55,8 @@ export interface TrustedIssuerConfig {
|
|
|
55
55
|
readonly allowedScopes: readonly IssuerScope[];
|
|
56
56
|
/** The agents its tokens reach; absent reaches all. */
|
|
57
57
|
readonly agents?: readonly string[];
|
|
58
|
-
/**
|
|
59
|
-
readonly
|
|
58
|
+
/** Environment grant templates, such as `{org_id}/*`; absent reaches no Environment. */
|
|
59
|
+
readonly environments?: readonly string[];
|
|
60
60
|
}
|
|
61
61
|
/** A malformed identity file: the message names the issuer and the field. */
|
|
62
62
|
export declare class IdentityFileError extends Error {
|
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
* # Optional, with their defaults:
|
|
16
16
|
* subject: "{sub}" # scalar claims only
|
|
17
17
|
* scopes: { claim: scope } # or { fixed: [sessions:own, agents:read] }
|
|
18
|
-
* allowedScopes: [agents:read, sessions:own,
|
|
18
|
+
* allowedScopes: [agents:read, sessions:own, environments:write] # add studio to grant it
|
|
19
19
|
* agents: [support] # absent reaches every agent
|
|
20
|
-
*
|
|
20
|
+
* environments: ["{org_id}/*"] # absent reaches no Environment
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
import { createPublicKey } from "node:crypto";
|
|
24
24
|
import { parse as parseYaml } from "yaml";
|
|
25
25
|
import { z } from "zod";
|
|
26
|
-
import { ISSUER_SCOPES,
|
|
26
|
+
import { ISSUER_SCOPES, isEnvironmentGrant, TOKEN_ENVIRONMENT_GRANTS_MAX, TOKEN_SCOPES, } from "@nylorun/core/contracts";
|
|
27
27
|
/** The JWT algorithms an issuer may sign with. */
|
|
28
28
|
export const ISSUER_ALGORITHMS = ["RS256", "ES256", "EdDSA"];
|
|
29
29
|
/** An entry's defaults: the `sub` claim, the RFC 9068 `scope` claim, every token scope but `studio`. */
|
|
@@ -119,11 +119,11 @@ const IssuerEntrySchema = z
|
|
|
119
119
|
.default(DEFAULT_SCOPES),
|
|
120
120
|
allowedScopes: z.array(IssuerScopeSchema).min(1).default([...DEFAULT_ALLOWED_SCOPES]),
|
|
121
121
|
agents: z.array(z.string().min(1)).optional(),
|
|
122
|
-
|
|
123
|
-
.array(template("
|
|
122
|
+
environments: z
|
|
123
|
+
.array(template("an Environment grant").refine(
|
|
124
124
|
// A rendered grant must be a grant: checked here with a sample value per claim.
|
|
125
|
-
(value) =>
|
|
126
|
-
.max(
|
|
125
|
+
(value) => isEnvironmentGrant(renderTemplate(value, () => "x")), "must render to an Environment id or a prefix ending in /*, as {org_id}/*"))
|
|
126
|
+
.max(TOKEN_ENVIRONMENT_GRANTS_MAX)
|
|
127
127
|
.optional(),
|
|
128
128
|
});
|
|
129
129
|
const IdentityFileSchema = z.object({ issuers: z.array(z.unknown()) });
|
|
@@ -173,6 +173,15 @@ export function parseIdentityFile(text, source = "identity file", options = {})
|
|
|
173
173
|
? entry.name
|
|
174
174
|
: `#${index + 1}`;
|
|
175
175
|
const where = `issuer ${named}`;
|
|
176
|
+
// Protocol 11 renamed these (R2d Q11): refused, never read as no grants.
|
|
177
|
+
if (entry && typeof entry === "object" && "sandboxes" in entry)
|
|
178
|
+
return fail(`${where}: sandboxes: renamed environments in protocol 11`);
|
|
179
|
+
const scopesNamed = JSON.stringify([
|
|
180
|
+
entry?.allowedScopes,
|
|
181
|
+
entry?.scopes,
|
|
182
|
+
]);
|
|
183
|
+
if (scopesNamed.includes('"sandboxes:write"'))
|
|
184
|
+
return fail(`${where}: sandboxes:write: renamed environments:write in protocol 11`);
|
|
176
185
|
const parsed = IssuerEntrySchema.safeParse(entry);
|
|
177
186
|
if (!parsed.success)
|
|
178
187
|
return fail(`${where}: ${issueText(parsed.error.issues)}`);
|
|
@@ -207,7 +216,7 @@ export function parseIdentityFile(text, source = "identity file", options = {})
|
|
|
207
216
|
scopes: value.scopes,
|
|
208
217
|
allowedScopes: [...new Set(value.allowedScopes)],
|
|
209
218
|
...(value.agents ? { agents: [...new Set(value.agents)] } : {}),
|
|
210
|
-
...(value.
|
|
219
|
+
...(value.environments ? { environments: value.environments } : {}),
|
|
211
220
|
});
|
|
212
221
|
});
|
|
213
222
|
return issuers;
|
package/dist/tenant/issuers.js
CHANGED
|
@@ -37,7 +37,7 @@ const JWKS_MAX_BYTES = 256 * 1024;
|
|
|
37
37
|
const JWKS_MAX_KEYS = 64;
|
|
38
38
|
const DEFAULT_REFETCH_MS = 60_000;
|
|
39
39
|
const DEFAULT_MAX_AGE_MS = 10 * 60_000;
|
|
40
|
-
/** A grant's claim value: one
|
|
40
|
+
/** A grant's claim value: one Environment id segment, so a claim never widens the template. */
|
|
41
41
|
const GRANT_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
42
42
|
/** The issuer's public keys: static, or its JWKS's as last fetched. */
|
|
43
43
|
class IssuerKeys {
|
|
@@ -292,7 +292,7 @@ export async function verifyIssuerToken(ctx, issuer, raw, resourceMetadata) {
|
|
|
292
292
|
const subject = renderTemplate(config.subject, (claim) => scalarClaim(payload, claim));
|
|
293
293
|
if (subject === undefined || !isSubject(subject) || RESERVED.has(subject))
|
|
294
294
|
return rejected("issuer_token_subject");
|
|
295
|
-
const
|
|
295
|
+
const environments = config.environments?.flatMap((grant) => {
|
|
296
296
|
const rendered = renderTemplate(grant, (claim) => {
|
|
297
297
|
const value = scalarClaim(payload, claim);
|
|
298
298
|
return value !== undefined && GRANT_SEGMENT.test(value) ? value : undefined;
|
|
@@ -309,7 +309,7 @@ export async function verifyIssuerToken(ctx, issuer, raw, resourceMetadata) {
|
|
|
309
309
|
subject,
|
|
310
310
|
scopes: scopesOf(config, payload),
|
|
311
311
|
agents: config.agents ? new Set(config.agents) : "*",
|
|
312
|
-
|
|
312
|
+
environments: [...new Set(environments ?? [])],
|
|
313
313
|
expiresAt: payload.exp * 1000,
|
|
314
314
|
tokenId: jti,
|
|
315
315
|
...(verdict.kid !== undefined ? { keyId: verdict.kid } : {}),
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* The Tenant's model settings: the fixture model, and the inputs the operator added to catalog
|
|
3
|
+
* models (`model.inputs`, below).
|
|
4
|
+
*
|
|
2
5
|
* The Tenant-level fixture model: Tenant setting `model.fixture`, seeded with
|
|
3
6
|
* `fixtureModel: true` (`PUT /v1/tenant/config/seed`, Host feature `tenant-fixture-model`).
|
|
4
7
|
* A Tenant with it answers every model call with the Runtime's deterministic fixture model
|
|
@@ -8,9 +11,20 @@
|
|
|
8
11
|
* The setting is read once per advance, in a transaction the advance makes anyway, so a Tenant
|
|
9
12
|
* seeded on another node takes it at its next advance.
|
|
10
13
|
*/
|
|
14
|
+
import { type ModelInput } from "@nylorun/core/contracts";
|
|
11
15
|
import type { Tx } from "../store/types.js";
|
|
12
16
|
export declare const FIXTURE_MODEL_SETTING = "model.fixture";
|
|
13
17
|
/** Whether the Tenant uses the fixture model. */
|
|
14
18
|
export declare function usesFixtureModel(t: Tx): Promise<boolean>;
|
|
15
19
|
/** Seeds the setting if absent. Returns whether it was inserted. */
|
|
16
20
|
export declare function seedFixtureModel(t: Tx): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* The inputs the operator added to catalog models (protocol 12, `PUT /v1/tenant/models/inputs`):
|
|
23
|
+
* Tenant setting `model.inputs`, JSON `{ "<provider>/<model>": ModelInput[] }`. A custom
|
|
24
|
+
* endpoint keeps its own in its `settings.inputs` instead.
|
|
25
|
+
*/
|
|
26
|
+
export declare const MODEL_INPUTS_SETTING = "model.inputs";
|
|
27
|
+
/** The added inputs by `<provider>/<model>`. Bad JSON, keys and inputs are left out: never throws. */
|
|
28
|
+
export declare function readAddedInputs(t: Pick<Tx, "getSetting">): Promise<Record<string, ModelInput[]>>;
|
|
29
|
+
/** Sets the inputs added to `<provider>/<model>`; an empty list removes its entry. */
|
|
30
|
+
export declare function writeAddedInputs(t: Pick<Tx, "getSetting" | "putSetting">, key: string, inputs: readonly ModelInput[]): Promise<void>;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Tenant's model settings: the fixture model, and the inputs the operator added to catalog
|
|
3
|
+
* models (`model.inputs`, below).
|
|
4
|
+
*
|
|
5
|
+
* The Tenant-level fixture model: Tenant setting `model.fixture`, seeded with
|
|
6
|
+
* `fixtureModel: true` (`PUT /v1/tenant/config/seed`, Host feature `tenant-fixture-model`).
|
|
7
|
+
* A Tenant with it answers every model call with the Runtime's deterministic fixture model
|
|
8
|
+
* (`core/provider.ts` `toolFixtureModel`) instead of its configured model. Smoke checks seed
|
|
9
|
+
* it (scripts/lib/stack-tenant.mjs).
|
|
10
|
+
*
|
|
11
|
+
* The setting is read once per advance, in a transaction the advance makes anyway, so a Tenant
|
|
12
|
+
* seeded on another node takes it at its next advance.
|
|
13
|
+
*/
|
|
14
|
+
import { ModelInputSchema } from "@nylorun/core/contracts";
|
|
1
15
|
export const FIXTURE_MODEL_SETTING = "model.fixture";
|
|
2
16
|
/** Whether the Tenant uses the fixture model. */
|
|
3
17
|
export async function usesFixtureModel(t) {
|
|
@@ -10,3 +24,40 @@ export async function seedFixtureModel(t) {
|
|
|
10
24
|
await t.putSetting(FIXTURE_MODEL_SETTING, "true");
|
|
11
25
|
return true;
|
|
12
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* The inputs the operator added to catalog models (protocol 12, `PUT /v1/tenant/models/inputs`):
|
|
29
|
+
* Tenant setting `model.inputs`, JSON `{ "<provider>/<model>": ModelInput[] }`. A custom
|
|
30
|
+
* endpoint keeps its own in its `settings.inputs` instead.
|
|
31
|
+
*/
|
|
32
|
+
export const MODEL_INPUTS_SETTING = "model.inputs";
|
|
33
|
+
/** The added inputs by `<provider>/<model>`. Bad JSON, keys and inputs are left out: never throws. */
|
|
34
|
+
export async function readAddedInputs(t) {
|
|
35
|
+
const raw = await t.getSetting(MODEL_INPUTS_SETTING);
|
|
36
|
+
if (raw === undefined)
|
|
37
|
+
return {};
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(raw);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
46
|
+
return {};
|
|
47
|
+
const added = {};
|
|
48
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
49
|
+
if (!key.includes("/") || !Array.isArray(value))
|
|
50
|
+
continue;
|
|
51
|
+
added[key] = value.filter((input) => ModelInputSchema.safeParse(input).success);
|
|
52
|
+
}
|
|
53
|
+
return added;
|
|
54
|
+
}
|
|
55
|
+
/** Sets the inputs added to `<provider>/<model>`; an empty list removes its entry. */
|
|
56
|
+
export async function writeAddedInputs(t, key, inputs) {
|
|
57
|
+
const added = await readAddedInputs(t);
|
|
58
|
+
if (inputs.length === 0)
|
|
59
|
+
delete added[key];
|
|
60
|
+
else
|
|
61
|
+
added[key] = [...inputs];
|
|
62
|
+
await t.putSetting(MODEL_INPUTS_SETTING, JSON.stringify(added));
|
|
63
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* `nylorun-operate keys`, `operator-keys.ts`); no other key is derived.
|
|
7
7
|
*
|
|
8
8
|
* The derivation is the one `@nylorun/admin` computes on the client side
|
|
9
|
-
* (`admin/src/derived-credentials.ts`: `deriveStudioToken`); both sides must stay byte for byte
|
|
9
|
+
* (`sdks/admin/src/derived-credentials.ts`: `deriveStudioToken`); both sides must stay byte for byte
|
|
10
10
|
* the same.
|
|
11
11
|
*/
|
|
12
12
|
import { createHmac } from "node:crypto";
|
package/dist/tenant/reset.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, renameSync, rmSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { detachAllSessions } from "./
|
|
3
|
+
import { detachAllSessions } from "./environments.js";
|
|
4
4
|
import { contentKey } from "../artifacts/folders.js";
|
|
5
5
|
/**
|
|
6
6
|
* Rename `dir` to a sibling, delete the sibling, recreate an empty `dir`.
|
|
@@ -38,14 +38,14 @@ function replaceDirectory(dir) {
|
|
|
38
38
|
*/
|
|
39
39
|
export async function resetTenant(ctx, scope) {
|
|
40
40
|
const clearSessions = scope === "sessions" || scope === "all";
|
|
41
|
-
const clearSandboxes = scope === "
|
|
41
|
+
const clearSandboxes = scope === "environments" || scope === "all";
|
|
42
42
|
const clearAll = scope === "all";
|
|
43
43
|
if (clearSandboxes) {
|
|
44
44
|
await ctx.sandbox.removeAll();
|
|
45
45
|
}
|
|
46
46
|
// The artifacts the reset deletes: their rows go in its transaction, their bytes after it.
|
|
47
47
|
const blobKeys = await ctx.store.tx(async (t) => {
|
|
48
|
-
//
|
|
48
|
+
// Environments outlive their sessions: a sessions reset only detaches them.
|
|
49
49
|
if (clearSessions && !clearSandboxes)
|
|
50
50
|
await detachAllSessions(t);
|
|
51
51
|
const scoped = clearAll ? "all" : "sessions";
|
package/dist/tenant/runtime.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { HarnessChannel, MemoryPortsOptions } from "@nylorun/core/harness-a
|
|
|
14
14
|
import { type HarnessPeer } from "../harness-api/server.js";
|
|
15
15
|
import { type HostAuthority } from "../sandbox/join.js";
|
|
16
16
|
import type { TenantPods } from "./context.js";
|
|
17
|
+
import type { TraceOptions } from "../traces/options.js";
|
|
17
18
|
/** TENANTS-CCR: test/injection hooks until TenantConfig gains them. */
|
|
18
19
|
export type TenantOpenHooks = {
|
|
19
20
|
modelProvider?: ModelProvider;
|
|
@@ -80,9 +81,11 @@ export type TenantOpenHooks = {
|
|
|
80
81
|
harnessTap?: MemoryPortsOptions["tap"];
|
|
81
82
|
/**
|
|
82
83
|
* Sandbox pods (F7.2): the sandboxes service (`NYLORUN_SANDBOXES_URL`) and the Runtime image
|
|
83
|
-
* pods copy the engine from. Without it, kind `pod` is `
|
|
84
|
+
* pods copy the engine from. Without it, kind `pod` is `environment_unavailable`.
|
|
84
85
|
*/
|
|
85
86
|
pods?: TenantPods;
|
|
87
|
+
/** How the trace route makes spans (R7.5): the Host's `OTEL_*` resource and content opt-ins. */
|
|
88
|
+
traces?: TraceOptions;
|
|
86
89
|
} & OpenedTenant;
|
|
87
90
|
export declare class TenantRuntime implements TenantHandle {
|
|
88
91
|
private readonly ctx;
|
|
@@ -97,6 +100,8 @@ export declare class TenantRuntime implements TenantHandle {
|
|
|
97
100
|
private constructor();
|
|
98
101
|
/** The Tenant's side of a sandbox pod's join (F7.2). */
|
|
99
102
|
hostAuthority(): HostAuthority | undefined;
|
|
103
|
+
/** The custom harness a per-harness token is for (R4.1), or undefined. */
|
|
104
|
+
harnessOfToken(token: string): Promise<string | undefined>;
|
|
100
105
|
static open(config: TenantConfig, hooks: TenantOpenHooks): Promise<TenantRuntime>;
|
|
101
106
|
fetch(request: Request, node: NodeBindings): Promise<Response>;
|
|
102
107
|
authorize(sessionId: string, request: {
|
package/dist/tenant/runtime.js
CHANGED
|
@@ -29,6 +29,7 @@ import { harnessStatusOf } from "./status.js";
|
|
|
29
29
|
import { startInProcessHarness, startLoopbackHarness, } from "../harness-api/in-process.js";
|
|
30
30
|
import { localWorkspace, remoteWorkspace, withPodWorkspaces, } from "../harness-api/workspace.js";
|
|
31
31
|
import { hostAuthority } from "../sandbox/join.js";
|
|
32
|
+
import { harnessOfToken } from "./harness-tokens.js";
|
|
32
33
|
import { reconcileSandbox } from "../sandbox/pods/reconcile.js";
|
|
33
34
|
import { sandboxWorkspaceReader } from "../artifacts/workspace.js";
|
|
34
35
|
import { readDefinitionFile } from "./definition-files.js";
|
|
@@ -74,6 +75,10 @@ export class TenantRuntime {
|
|
|
74
75
|
hostAuthority() {
|
|
75
76
|
return this.ctx.closing || this.ctx.closed ? undefined : this.hosts;
|
|
76
77
|
}
|
|
78
|
+
/** The custom harness a per-harness token is for (R4.1), or undefined. */
|
|
79
|
+
harnessOfToken(token) {
|
|
80
|
+
return harnessOfToken(this.ctx.store, token);
|
|
81
|
+
}
|
|
77
82
|
static async open(config, hooks) {
|
|
78
83
|
const envelope = hooks.envelope;
|
|
79
84
|
const flowLimits = validateConfig(config);
|
|
@@ -193,7 +198,7 @@ export class TenantRuntime {
|
|
|
193
198
|
store: opened,
|
|
194
199
|
logger: config.logger,
|
|
195
200
|
preference,
|
|
196
|
-
isPod: async (sandboxId) => (await opened.tx((t) => t.
|
|
201
|
+
isPod: async (sandboxId) => (await opened.tx((t) => t.environment(sandboxId)))?.kind === "pod",
|
|
197
202
|
})
|
|
198
203
|
: workspaces;
|
|
199
204
|
const useVaultModel = config.model.kind === "vault";
|
|
@@ -256,6 +261,7 @@ export class TenantRuntime {
|
|
|
256
261
|
keys,
|
|
257
262
|
blobs,
|
|
258
263
|
workspaces: sandboxWorkspaceReader(sandbox),
|
|
264
|
+
...(hooks.traces ? { traces: hooks.traces } : {}),
|
|
259
265
|
...(hooks.runGrants ? { runGrants: hooks.runGrants } : {}),
|
|
260
266
|
workerId: hooks.workerId ?? WORKER_ID,
|
|
261
267
|
ownerLeaseMs: config.ownerLeaseMs ?? DEFAULT_OWNER_LEASE_MS,
|
package/dist/tenant/session.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pure helpers over the session document: turn-manifest pins and variants
|
|
2
|
+
* Pure helpers over the session document: turn-manifest pins and variants. The engine's state
|
|
3
|
+
* is the harness's (R4.2): nothing here reads it.
|
|
3
4
|
* No store access and no I/O. (The tools of an MCP snapshot
|
|
4
5
|
* live in `mcp/snapshot.ts`.)
|
|
5
6
|
*
|
|
6
7
|
* Later waves: stable; the async store conversion (Wave 1 / A) does not change these.
|
|
7
8
|
*/
|
|
8
9
|
import type { AgentManifest } from "@nylorun/core/define";
|
|
9
|
-
import {
|
|
10
|
+
import type { TurnManifestStore } from "../core/turn-manifest.js";
|
|
10
11
|
import type { Session } from "./context.js";
|
|
11
12
|
export { manifestFor, sessionToolsOf } from "../mcp/snapshot.js";
|
|
12
13
|
/** Turn-manifest store backed by the session's `variants` map (no schema change). */
|
|
13
14
|
export declare function variantStore(session: Session): TurnManifestStore;
|
|
14
15
|
/** Manifest this turn's checkpoint is pinned to (session pin or a stored variant). */
|
|
15
16
|
export declare function turnManifestOf(session: Session): AgentManifest;
|
|
16
|
-
export declare function rebaseSessionState(session: Session, turnHash: string): void;
|
package/dist/tenant/session.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { allowedManifestHashes, rebaseTurnState, } from "../core/turn-manifest.js";
|
|
2
1
|
export { manifestFor, sessionToolsOf } from "../mcp/snapshot.js";
|
|
3
2
|
/** Turn-manifest store backed by the session's `variants` map (no schema change). */
|
|
4
3
|
export function variantStore(session) {
|
|
@@ -18,16 +17,3 @@ export function turnManifestOf(session) {
|
|
|
18
17
|
return session.manifest;
|
|
19
18
|
return session.variants?.[hash] ?? session.manifest;
|
|
20
19
|
}
|
|
21
|
-
export function rebaseSessionState(session, turnHash) {
|
|
22
|
-
const allowed = allowedManifestHashes({
|
|
23
|
-
pinnedHash: session.manifestHash,
|
|
24
|
-
variantHashes: Object.keys(session.variants ?? {}),
|
|
25
|
-
});
|
|
26
|
-
const next = rebaseTurnState({
|
|
27
|
-
state: session.state,
|
|
28
|
-
turnManifestHash: turnHash,
|
|
29
|
-
isAllowedHash: (hash) => allowed.has(hash),
|
|
30
|
-
});
|
|
31
|
-
if (next !== session.state)
|
|
32
|
-
session.state = next;
|
|
33
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session and definition resources: `PUT/GET /v1/agents`, `PUT /v1/sessions/:id` (create or
|
|
3
|
-
*
|
|
4
|
-
* queries; `PUT /v1/sessions/:id` runs in one transaction with the
|
|
2
|
+
* Session and definition resources: `PUT/GET /v1/agents`, `PUT /v1/sessions/:id` (create, or
|
|
3
|
+
* find an identical one), the session list and the session view. Reads use the store's typed
|
|
4
|
+
* queries; `PUT /v1/sessions/:id` runs in one transaction with the Environment's checks.
|
|
5
5
|
*/
|
|
6
6
|
import { type PutAgentRequest, type PutSessionRequest } from "@nylorun/core/contracts";
|
|
7
7
|
import type { Tx } from "../store/types.js";
|
|
@@ -25,10 +25,14 @@ export declare function listAgentsPublic(ctx: TenantContext, agents: ReadonlySet
|
|
|
25
25
|
description?: any;
|
|
26
26
|
}[];
|
|
27
27
|
}>;
|
|
28
|
-
export declare function putDefinition(ctx: TenantContext, agentId: string, body: PutAgentRequest
|
|
28
|
+
export declare function putDefinition(ctx: TenantContext, agentId: string, body: PutAgentRequest, options?: {
|
|
29
|
+
/** Run every check and save nothing (`?dryRun=true`, protocol 14). */
|
|
30
|
+
dryRun?: boolean;
|
|
31
|
+
}): Promise<{
|
|
29
32
|
agentId: string;
|
|
30
33
|
manifestHash: string;
|
|
31
34
|
implementationVersion: string;
|
|
35
|
+
dryRun?: boolean | undefined;
|
|
32
36
|
}>;
|
|
33
37
|
/**
|
|
34
38
|
* `access`, when the request acts for a person, limits the list to that person's sessions of
|
|
@@ -44,14 +48,14 @@ export declare function listSessions(ctx: TenantContext, agentId: string | null,
|
|
|
44
48
|
}[];
|
|
45
49
|
}>;
|
|
46
50
|
/**
|
|
47
|
-
* Create a session from its definition, or
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
+
* Create a session from its definition, or find an identical one. `access`, when the request
|
|
52
|
+
* acts for a subject, must be the session's owner: another owner's session id is the 404 of a
|
|
53
|
+
* missing one (not the 409 of a mismatch), and so is an Environment whose owner guard names
|
|
54
|
+
* another owner.
|
|
51
55
|
*
|
|
52
|
-
* The session's
|
|
53
|
-
*
|
|
54
|
-
*
|
|
56
|
+
* The session's Environment is fixed for its life: its sandbox (kinds `virtual` and `pod`) is
|
|
57
|
+
* the session's, with the spec of the Environment's applied recipe pinned now, and its vault
|
|
58
|
+
* holds the session's credentials. Without one the session has no sandbox and no credentials.
|
|
55
59
|
*/
|
|
56
60
|
export declare function putSession(ctx: TenantContext, id: string, body: PutSessionRequest, access?: SessionAccess, options?: {
|
|
57
61
|
/**
|
|
@@ -60,10 +64,10 @@ export declare function putSession(ctx: TenantContext, id: string, body: PutSess
|
|
|
60
64
|
*/
|
|
61
65
|
createOnly?: boolean;
|
|
62
66
|
/**
|
|
63
|
-
* The
|
|
64
|
-
* reaches every one. `
|
|
67
|
+
* The Environments the caller reaches (a token caller's grants, `environmentGrantsOf`);
|
|
68
|
+
* undefined reaches every one. `environment` must name one of them.
|
|
65
69
|
*/
|
|
66
|
-
|
|
70
|
+
environmentGrants?: readonly string[];
|
|
67
71
|
}): Promise<Session>;
|
|
68
72
|
/** The session resource returned by `GET`/`PUT /v1/sessions/:id`. */
|
|
69
73
|
export declare function sessionView(t: Tx, s: Session): Promise<unknown>;
|