@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
package/dist/sandbox/join.js
CHANGED
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
* which check failed.
|
|
33
33
|
*/
|
|
34
34
|
import { createHash, timingSafeEqual } from "node:crypto";
|
|
35
|
-
import {
|
|
35
|
+
import { isEnvironmentId } from "@nylorun/core/contracts";
|
|
36
|
+
import { recoverLostVolume, runPendingSeed } from "../artifacts/disk.js";
|
|
37
|
+
import { recordSetup, setupFile, setupPlanOf, setupState, } from "./setup.js";
|
|
36
38
|
import { mintHostTokens, staleHost, verifyHostToken, } from "../tenant/host-token.js";
|
|
37
39
|
/** A refused join, renewal or host connection. */
|
|
38
40
|
export class HostAuthError extends Error {
|
|
@@ -84,7 +86,7 @@ export function hostAuthority(ctx) {
|
|
|
84
86
|
return {
|
|
85
87
|
async join(request) {
|
|
86
88
|
const { sandboxId, podUid, joinToken, volumeId } = request;
|
|
87
|
-
if (!
|
|
89
|
+
if (!isEnvironmentId(sandboxId) ||
|
|
88
90
|
typeof podUid !== "string" ||
|
|
89
91
|
!POD_UID.test(podUid) ||
|
|
90
92
|
typeof joinToken !== "string" ||
|
|
@@ -107,11 +109,11 @@ export function hostAuthority(ctx) {
|
|
|
107
109
|
// A pod being stopped joins nothing: its sandbox runs again only when asked to.
|
|
108
110
|
if (pod.desired !== "running")
|
|
109
111
|
return refuse("the sandbox is stopped");
|
|
110
|
-
if (pod.observed === "lost"
|
|
111
|
-
return refuse(
|
|
112
|
+
if (pod.observed === "lost")
|
|
113
|
+
return refuse("the sandbox is lost");
|
|
112
114
|
return pod;
|
|
113
115
|
};
|
|
114
|
-
const readRow = () => ctx.store.tx((t) => t.
|
|
116
|
+
const readRow = () => ctx.store.tx((t) => t.environment(sandboxId));
|
|
115
117
|
const before = usable(await readRow());
|
|
116
118
|
let current;
|
|
117
119
|
try {
|
|
@@ -123,7 +125,7 @@ export function hostAuthority(ctx) {
|
|
|
123
125
|
if (current !== podUid)
|
|
124
126
|
refuse("the pod is not the sandbox's current pod");
|
|
125
127
|
const joined = await ctx.store.tx(async (t) => {
|
|
126
|
-
const row = await t.
|
|
128
|
+
const row = await t.environment(sandboxId, { lock: true });
|
|
127
129
|
const pod = usable(row);
|
|
128
130
|
if (pod.k8sName !== before.k8sName)
|
|
129
131
|
refuse("the sandbox was reset during the join");
|
|
@@ -132,14 +134,14 @@ export function hostAuthority(ctx) {
|
|
|
132
134
|
if (pod.volumeId !== undefined && volumeId !== pod.volumeId) {
|
|
133
135
|
// A new, empty volume under the same Sandbox: the sandbox's files are gone.
|
|
134
136
|
const reason = "The sandbox's volume was replaced: its files are gone";
|
|
135
|
-
await t.
|
|
136
|
-
await t.
|
|
137
|
+
await t.updateEnvironmentPod(sandboxId, { observed: "lost", reason, hostEpoch: epoch }, now);
|
|
138
|
+
await t.environmentEvent(sandboxId, "environment.lost", { reason });
|
|
137
139
|
// Its Sandbox is deleted; only a reset brings the sandbox back.
|
|
138
140
|
await t.signal({ type: "host.revoked", sandboxId, epoch });
|
|
139
141
|
await t.signalSandbox(sandboxId, { kind: "reconcile" });
|
|
140
142
|
return { lost: epoch };
|
|
141
143
|
}
|
|
142
|
-
await t.
|
|
144
|
+
await t.updateEnvironmentPod(sandboxId, {
|
|
143
145
|
hostEpoch: epoch,
|
|
144
146
|
podUid,
|
|
145
147
|
...(pod.volumeId === undefined && volumeId !== undefined ? { volumeId } : {}),
|
|
@@ -147,23 +149,52 @@ export function hostAuthority(ctx) {
|
|
|
147
149
|
}, now);
|
|
148
150
|
if (pod.podUid !== podUid) {
|
|
149
151
|
if (pod.podUid !== undefined)
|
|
150
|
-
await t.
|
|
152
|
+
await t.environmentEvent(sandboxId, "environment.relaunched", { hostEpoch: epoch });
|
|
151
153
|
else
|
|
152
|
-
await t.
|
|
154
|
+
await t.environmentEvent(sandboxId, "environment.running", { hostEpoch: epoch });
|
|
153
155
|
}
|
|
154
156
|
// The previous host's connection (an older epoch) serves nothing more, on any process.
|
|
155
157
|
await t.signal({ type: "host.revoked", sandboxId, epoch });
|
|
156
|
-
return
|
|
158
|
+
return {
|
|
159
|
+
epoch,
|
|
160
|
+
setup: row ? await setupPlanOf(ctx, t, row) : undefined,
|
|
161
|
+
seeded: row?.diskSeed !== undefined,
|
|
162
|
+
afterSeed: row?.diskSeed?.setup === true,
|
|
163
|
+
};
|
|
157
164
|
});
|
|
158
|
-
if (
|
|
165
|
+
if ("lost" in joined) {
|
|
166
|
+
// With a disk version, a new volume seeded from the latest one (R2d step 3).
|
|
167
|
+
void recoverLostVolume(ctx, sandboxId).catch(() => undefined);
|
|
159
168
|
return refuse("the volume was replaced: the sandbox is lost");
|
|
160
|
-
|
|
161
|
-
|
|
169
|
+
}
|
|
170
|
+
ctx.config.logger.info("sandbox host joined", { sandboxId, epoch: joined.epoch });
|
|
171
|
+
const answer = answerOf(await mintHostTokens(ctx, { sandboxId, epoch: joined.epoch, podUid }), await ctx.keys.egressCa());
|
|
172
|
+
if (joined.seeded) {
|
|
173
|
+
// The engine connects next; the seed waits for it, then writes the version.
|
|
174
|
+
void runPendingSeed(ctx, sandboxId);
|
|
175
|
+
// A fork onto other setup (Q17): the engine runs it once the version is written.
|
|
176
|
+
if (joined.afterSeed)
|
|
177
|
+
return { ...answer, seeded: true, afterSeed: true, ...(joined.setup ? { setup: joined.setup } : {}) };
|
|
178
|
+
return { ...answer, seeded: true };
|
|
179
|
+
}
|
|
180
|
+
return joined.setup ? { ...answer, setup: joined.setup } : answer;
|
|
162
181
|
},
|
|
163
182
|
async renew(hostToken) {
|
|
164
183
|
const claims = await verified(hostToken);
|
|
165
184
|
return answerOf(await mintHostTokens(ctx, claims), await ctx.keys.egressCa());
|
|
166
185
|
},
|
|
167
186
|
verify: verified,
|
|
187
|
+
async setup(hostToken) {
|
|
188
|
+
const claims = await verified(hostToken);
|
|
189
|
+
return setupState(ctx, claims.sandboxId);
|
|
190
|
+
},
|
|
191
|
+
async reportSetup(hostToken, report) {
|
|
192
|
+
const claims = await verified(hostToken);
|
|
193
|
+
await recordSetup(ctx, claims.sandboxId, claims.epoch, report);
|
|
194
|
+
},
|
|
195
|
+
async setupFile(hostToken, index, path) {
|
|
196
|
+
const claims = await verified(hostToken);
|
|
197
|
+
return setupFile(ctx, claims.sandboxId, index, path);
|
|
198
|
+
},
|
|
168
199
|
};
|
|
169
200
|
}
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
* Sandbox Manager: owns sandbox lifecycle for the Runtime. One workspace per sandbox resource
|
|
3
3
|
* (`sandbox: { id }`, keyed by the sandbox id), or per owning session for a sandbox chosen
|
|
4
4
|
* inline or by the Tenant default (keyed by the session id); created on the first sandbox tool
|
|
5
|
-
* call, stopped after its idle timeout, reattached on the next call.
|
|
6
|
-
* workspace run
|
|
5
|
+
* call, stopped after its idle timeout, reattached on the next call. Each session's calls on a
|
|
6
|
+
* workspace run in the order it sends them, and different sessions' calls run at the same time
|
|
7
|
+
* (D66): the sessions of one Environment run their turns at once. Opening, stopping and removing
|
|
8
|
+
* a workspace run alone: a stop or removal waits for the calls running, and calls that come after
|
|
9
|
+
* it wait for it.
|
|
7
10
|
*
|
|
8
11
|
* The manager keeps no timers and reaches no store: it keeps its compute records through a
|
|
9
12
|
* `SandboxRecords` port (the Tenant's `sandboxes` table in core's process, a file in a harness's)
|
|
@@ -12,17 +15,18 @@
|
|
|
12
15
|
* (after a restart); `reconcile` removes workspaces whose owner is gone. `sweep` does both, the
|
|
13
16
|
* reconcile once per process, as the Tenant sweep does in core's process.
|
|
14
17
|
*
|
|
15
|
-
* A session's skills (track R2 M4) are mounted on its workspace, read-only
|
|
16
|
-
* `/skills/<name>/`, before the first call that
|
|
17
|
-
* through the `definitionFile` port.
|
|
18
|
+
* A session's skills (track R2 M4) are mounted on its workspace, read-only, one folder per
|
|
19
|
+
* version (`/skills/<name>@<hash>/`, D66), before the first call that needs them (`skills.ts`);
|
|
20
|
+
* their bytes come through the `definitionFile` port.
|
|
18
21
|
*/
|
|
19
22
|
import type { EventPayload } from "@nylorun/core/contracts";
|
|
20
|
-
import { type AgentManifest, type
|
|
23
|
+
import { type AgentManifest, type SandboxManifest, type SandboxToolName } from "@nylorun/core/define";
|
|
21
24
|
import { type SandboxRecord, type SandboxRecords } from "./records.js";
|
|
22
25
|
import { type SandboxSelection, type SandboxSelectionReport } from "./select.js";
|
|
26
|
+
import { type DiskAnswer, type DiskOp } from "./disk-fs.js";
|
|
23
27
|
import { type SandboxToolOutcome } from "./tools.js";
|
|
24
28
|
import { type SandboxBackend, type SandboxListing } from "./types.js";
|
|
25
|
-
export {
|
|
29
|
+
export { sandboxToolSpec } from "./runtime-tools.js";
|
|
26
30
|
export type { SandboxRecord, SandboxRecords, SandboxState } from "./records.js";
|
|
27
31
|
export interface SandboxSessionRef {
|
|
28
32
|
/** The session whose log records the workspace's events: the owning session. */
|
|
@@ -33,7 +37,12 @@ export interface SandboxSessionRef {
|
|
|
33
37
|
* The sandbox resource the owning session is attached to. Its workspace is keyed by this id,
|
|
34
38
|
* so every session attached to it shares the files; absent, the workspace is the session's.
|
|
35
39
|
*/
|
|
36
|
-
readonly
|
|
40
|
+
readonly environmentId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* For a pod Environment: the host epoch it is at, so the call reaches a host that joined at
|
|
43
|
+
* that epoch or later, never one a restore or a lost volume retired.
|
|
44
|
+
*/
|
|
45
|
+
readonly hostEpoch?: number;
|
|
37
46
|
/** Variables every command of the call gets (R2c): secret names set to the sentinel, plain values. */
|
|
38
47
|
readonly environment?: Readonly<Record<string, string>>;
|
|
39
48
|
/**
|
|
@@ -55,7 +64,7 @@ export interface SandboxSweepOptions {
|
|
|
55
64
|
/** Whether a session still exists; sandboxes of deleted sessions are removed. */
|
|
56
65
|
readonly sessionExists: (sessionId: string) => boolean | Promise<boolean>;
|
|
57
66
|
/** Whether a sandbox resource still exists. Default: every one does. */
|
|
58
|
-
readonly sandboxExists?: (
|
|
67
|
+
readonly sandboxExists?: (environmentId: string) => boolean | Promise<boolean>;
|
|
59
68
|
}
|
|
60
69
|
export interface SandboxManagerOptions {
|
|
61
70
|
/** Distinguishes this Runtime's sandboxes from other Runtimes on the same machine: the Tenant id. */
|
|
@@ -77,7 +86,7 @@ export interface SandboxManagerOptions {
|
|
|
77
86
|
readonly emit: <T extends SandboxEventType>(sessionId: string, turnId: string | null, type: T, payload: EventPayload<T>, meta: SandboxEventMeta) => void | Promise<void>;
|
|
78
87
|
}
|
|
79
88
|
/** The session events a sandbox writes. */
|
|
80
|
-
export type SandboxEventType = "
|
|
89
|
+
export type SandboxEventType = "environment.state" | "environment.exec";
|
|
81
90
|
export declare class SandboxManager {
|
|
82
91
|
private readonly options;
|
|
83
92
|
private selection?;
|
|
@@ -104,19 +113,28 @@ export declare class SandboxManager {
|
|
|
104
113
|
/** Whether any sandbox was ever recorded, so startup can skip probing for agents without one. */
|
|
105
114
|
hasRecords(): Promise<boolean>;
|
|
106
115
|
keyOf(sessionId: string): string;
|
|
107
|
-
/** The workspace key of sandbox resource `
|
|
108
|
-
sandboxKeyOf(
|
|
116
|
+
/** The workspace key of sandbox resource `environmentId` (`sandboxWorkspaceKey`). */
|
|
117
|
+
sandboxKeyOf(environmentId: string): string;
|
|
109
118
|
private keyFor;
|
|
110
119
|
report(): Promise<SandboxSelectionReport & {
|
|
111
120
|
readonly defaultImage: string;
|
|
112
121
|
}>;
|
|
113
|
-
run(session: SandboxSessionRef,
|
|
122
|
+
run(session: SandboxSessionRef, sandbox: SandboxManifest | undefined, toolName: SandboxToolName, input: unknown, signal: AbortSignal): Promise<SandboxToolOutcome>;
|
|
123
|
+
/**
|
|
124
|
+
* Runs `call` in session `sessionId`'s queue on `live`: after its earlier calls, and after any
|
|
125
|
+
* stop or removal pending, beside other sessions' calls (D66).
|
|
126
|
+
*/
|
|
127
|
+
private inLane;
|
|
128
|
+
/** Runs `step` on `live` alone: after the calls running, before the calls that come after it. */
|
|
129
|
+
private alone;
|
|
130
|
+
/** The workspace's handle, opened once for the calls that need it at the same time. */
|
|
131
|
+
private handleOf;
|
|
114
132
|
/**
|
|
115
133
|
* The bytes of one file in the session's sandbox, for `save_artifact` (F8.1), in the same queue
|
|
116
134
|
* as its tool calls: `missing` when there is no such file, a failed outcome when the sandbox
|
|
117
135
|
* cannot open or the file is larger than `maxBytes`. Relative paths resolve in the workspace.
|
|
118
136
|
*/
|
|
119
|
-
readBytes(session: SandboxSessionRef,
|
|
137
|
+
readBytes(session: SandboxSessionRef, sandbox: SandboxManifest | undefined, path: string, maxBytes: number, signal: AbortSignal): Promise<{
|
|
120
138
|
kind: "read";
|
|
121
139
|
path: string;
|
|
122
140
|
bytes: Uint8Array;
|
|
@@ -131,7 +149,7 @@ export declare class SandboxManager {
|
|
|
131
149
|
* the same queue as its tool calls. `missing` when the sandbox was never created (nothing is
|
|
132
150
|
* started to look) or `dir` is not a directory. Relative paths resolve in the workspace.
|
|
133
151
|
*/
|
|
134
|
-
listFiles(session: SandboxSessionRef,
|
|
152
|
+
listFiles(session: SandboxSessionRef, sandbox: SandboxManifest | undefined, dir: string, maxEntries: number, signal: AbortSignal): Promise<{
|
|
135
153
|
kind: "listed";
|
|
136
154
|
path: string;
|
|
137
155
|
listing: SandboxListing;
|
|
@@ -141,6 +159,13 @@ export declare class SandboxManager {
|
|
|
141
159
|
} | Extract<SandboxToolOutcome, {
|
|
142
160
|
kind: "failed";
|
|
143
161
|
}>>;
|
|
162
|
+
/**
|
|
163
|
+
* One operation on the disk of the session's sandbox (R2d step 3, `sandbox/disk-fs.ts`), in the
|
|
164
|
+
* same queue as its tool calls, starting it first when it is stopped.
|
|
165
|
+
*/
|
|
166
|
+
disk(session: SandboxSessionRef, sandbox: SandboxManifest | undefined, op: DiskOp, signal: AbortSignal): Promise<DiskAnswer | Extract<SandboxToolOutcome, {
|
|
167
|
+
kind: "failed";
|
|
168
|
+
}>>;
|
|
144
169
|
/** Runs `use` on the session's sandbox in its queue, starting it first when it is stopped. */
|
|
145
170
|
private withHandle;
|
|
146
171
|
/** The session's live sandbox entry and spec, or why it cannot run here. */
|
|
@@ -148,9 +173,10 @@ export declare class SandboxManager {
|
|
|
148
173
|
private execute;
|
|
149
174
|
private executeOpen;
|
|
150
175
|
/**
|
|
151
|
-
* Mounts the session
|
|
152
|
-
* all of them, later only
|
|
153
|
-
* one
|
|
176
|
+
* Mounts the skill folders the session needs that the workspace does not hold (D66): on a
|
|
177
|
+
* handle just opened all of them, later only versions another session has not mounted. Calls
|
|
178
|
+
* that need one folder at once share its mount. A failed outcome when one cannot be mounted;
|
|
179
|
+
* the folder is not marked mounted then, so the next call tries again.
|
|
154
180
|
*/
|
|
155
181
|
private mountSkills;
|
|
156
182
|
private open;
|
|
@@ -159,16 +185,16 @@ export declare class SandboxManager {
|
|
|
159
185
|
/** The sandbox record for a session, if one was ever created. */
|
|
160
186
|
status(sessionId: string): Promise<SandboxRecord | undefined>;
|
|
161
187
|
/**
|
|
162
|
-
* Deletes sandbox resource `
|
|
188
|
+
* Deletes sandbox resource `environmentId`'s workspace, its files and its compute record, after
|
|
163
189
|
* any command queued on it. Called once the resource is deleted.
|
|
164
190
|
*/
|
|
165
|
-
removeSandbox(
|
|
191
|
+
removeSandbox(environmentId: string): Promise<void>;
|
|
166
192
|
/** Deletes the workspace `key`, its files and its record, after any command queued on it. */
|
|
167
193
|
remove(key: string): Promise<void>;
|
|
168
194
|
/**
|
|
169
195
|
* Delete workspaces this Runtime owns whose owner is gone: a session's when `sessionExists`
|
|
170
196
|
* says the session is gone, a sandbox resource's when `sandboxExists` says the resource is.
|
|
171
197
|
*/
|
|
172
|
-
reconcile(sessionExists: (sessionId: string) => boolean | Promise<boolean>, sandboxExists: (
|
|
198
|
+
reconcile(sessionExists: (sessionId: string) => boolean | Promise<boolean>, sandboxExists: (environmentId: string) => boolean | Promise<boolean>): Promise<void>;
|
|
173
199
|
close(): Promise<void>;
|
|
174
200
|
}
|