@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
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* head).
|
|
33
33
|
* 2. A transaction that touches several sessions locks them in ascending id
|
|
34
34
|
* order, with `lockSessions` (`./locking.ts`), before writing any of them.
|
|
35
|
-
* 3.
|
|
35
|
+
* 3. An Environment's row (`environment(id, { lock: true })`, which orders its
|
|
36
36
|
* lifecycle stream) is locked after every session row the transaction locks, never
|
|
37
37
|
* before one.
|
|
38
38
|
*
|
|
@@ -50,15 +50,15 @@
|
|
|
50
50
|
*/
|
|
51
51
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
52
52
|
import { randomUUID } from "node:crypto";
|
|
53
|
-
import { and, count, eq, getTableColumns, gte, gt, inArray, isNotNull, isNull, lt, lte, ne, or, sql, } from "drizzle-orm";
|
|
54
|
-
import {
|
|
53
|
+
import { and, count, desc, eq, getTableColumns, gte, gt, inArray, isNotNull, isNull, lt, lte, ne, or, sql, } from "drizzle-orm";
|
|
54
|
+
import { appendEnvironmentEvent, appendEvent } from "../../record/index.js";
|
|
55
55
|
import { OwnershipLostError, PrincipalRoleConflict } from "../ownership.js";
|
|
56
56
|
import { followControlSignals, pruneSignals, writeSignal } from "./control.js";
|
|
57
57
|
import { database, driverError } from "./db.js";
|
|
58
58
|
import { expectedSchemaVersion, readSchemaVersion } from "./migrate.js";
|
|
59
59
|
import { createPostgresRecordReader } from "./record.js";
|
|
60
|
-
import {
|
|
61
|
-
import { artifacts, artifactVersions, artifactContent, definitionFiles, definitionFileUses, commands, definitions, effects, links, modelBudgets, modelUsage, principals, sandboxes,
|
|
60
|
+
import { postgresEnvironmentRecordWriter, postgresRecordWriter } from "./record-writer.js";
|
|
61
|
+
import { artifacts, artifactVersions, artifactContent, definitionFiles, definitionFileUses, commands, definitions, effects, links, modelBudgets, modelUsage, principals, sandboxes, environmentEvents, environments, environmentManifests, sessionEvents, sessionLogHeads, sessions, toJson, toolCrossings, signingKeys, tenant, tenantSettings, vaultAudit, vaultCredentials, vaultIdempotency, vaults, sandboxSignals, wakes, } from "./schema.js";
|
|
62
62
|
export function createPostgresSessionStore(options) {
|
|
63
63
|
return new PostgresSessionStore(options);
|
|
64
64
|
}
|
|
@@ -240,14 +240,25 @@ function ownership(row) {
|
|
|
240
240
|
ownerExpiresAt: row.ownerExpiresAt?.toISOString() ?? null,
|
|
241
241
|
};
|
|
242
242
|
}
|
|
243
|
-
function
|
|
243
|
+
function environmentOf(row) {
|
|
244
244
|
return {
|
|
245
245
|
id: row.id,
|
|
246
246
|
kind: row.kind,
|
|
247
|
-
spec: row.spec,
|
|
248
247
|
labels: row.labels,
|
|
248
|
+
recipe: row.recipe,
|
|
249
|
+
applied: row.applied,
|
|
250
|
+
version: row.version,
|
|
251
|
+
appliedVersion: row.appliedVersion,
|
|
252
|
+
...(row.ownerUserId !== null ? { ownerUserId: row.ownerUserId } : {}),
|
|
253
|
+
lastUsedAt: new Date(row.lastUsedAt).toISOString(),
|
|
249
254
|
createdAt: row.createdAt,
|
|
250
255
|
updatedAt: row.updatedAt,
|
|
256
|
+
...(row.diskOp ? { diskOp: row.diskOp } : {}),
|
|
257
|
+
...(row.diskSeed ? { diskSeed: row.diskSeed } : {}),
|
|
258
|
+
...(row.manifestName !== null ? { manifestName: row.manifestName } : {}),
|
|
259
|
+
...(row.manifestVersion !== null ? { manifestVersion: row.manifestVersion } : {}),
|
|
260
|
+
...(row.manifestHash !== null ? { manifestHash: row.manifestHash } : {}),
|
|
261
|
+
...(row.forkedFrom ? { forkedFrom: row.forkedFrom } : {}),
|
|
251
262
|
...(row.k8sName !== null && row.desired !== null && row.observed !== null
|
|
252
263
|
? {
|
|
253
264
|
pod: {
|
|
@@ -260,16 +271,26 @@ function sandboxResourceOf(row) {
|
|
|
260
271
|
...(row.joinTokenHash !== null ? { joinTokenHash: row.joinTokenHash } : {}),
|
|
261
272
|
rev: row.rev,
|
|
262
273
|
...(row.lastActiveAt ? { lastActiveAt: row.lastActiveAt.toISOString() } : {}),
|
|
263
|
-
...(row.expiresAt ? { expiresAt: row.expiresAt.toISOString() } : {}),
|
|
264
274
|
...(row.startedAt ? { startedAt: row.startedAt.toISOString() } : {}),
|
|
265
275
|
...(row.reason !== null ? { reason: row.reason } : {}),
|
|
266
276
|
...(row.retiring !== null ? { retiring: row.retiring } : {}),
|
|
267
277
|
...(row.volumeId !== null ? { volumeId: row.volumeId } : {}),
|
|
278
|
+
...(row.imageDigest !== null ? { imageDigest: row.imageDigest } : {}),
|
|
268
279
|
},
|
|
269
280
|
}
|
|
270
281
|
: {}),
|
|
271
282
|
};
|
|
272
283
|
}
|
|
284
|
+
function environmentManifestOf(row) {
|
|
285
|
+
return {
|
|
286
|
+
name: row.name,
|
|
287
|
+
version: row.version,
|
|
288
|
+
body: row.body,
|
|
289
|
+
hash: row.hash,
|
|
290
|
+
savedBy: row.savedBy,
|
|
291
|
+
createdAt: row.createdAt,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
273
294
|
/** A pod patch as column values: ISO times become dates, `null` clears. */
|
|
274
295
|
function podColumns(patch) {
|
|
275
296
|
const date = (value) => value === undefined ? undefined : value === null ? null : new Date(value);
|
|
@@ -283,11 +304,11 @@ function podColumns(patch) {
|
|
|
283
304
|
joinTokenHash: patch.joinTokenHash,
|
|
284
305
|
rev: patch.rev,
|
|
285
306
|
lastActiveAt: date(patch.lastActiveAt),
|
|
286
|
-
expiresAt: date(patch.expiresAt),
|
|
287
307
|
startedAt: date(patch.startedAt),
|
|
288
308
|
reason: patch.reason,
|
|
289
309
|
retiring: patch.retiring,
|
|
290
310
|
volumeId: patch.volumeId,
|
|
311
|
+
imageDigest: patch.imageDigest,
|
|
291
312
|
};
|
|
292
313
|
return Object.fromEntries(Object.entries(columns).filter(([, value]) => value !== undefined));
|
|
293
314
|
}
|
|
@@ -389,7 +410,7 @@ class PostgresTx {
|
|
|
389
410
|
const [row] = await this.sessions().where(eq(sessions.id, id)).for("update");
|
|
390
411
|
return row && storedSession(row);
|
|
391
412
|
}
|
|
392
|
-
async event(sessionId, turnId, type, payload) {
|
|
413
|
+
async event(sessionId, turnId, type, payload, writer) {
|
|
393
414
|
this.check();
|
|
394
415
|
const db = this.db;
|
|
395
416
|
// The session row lock orders the session's events; the log head allocates under it.
|
|
@@ -408,6 +429,7 @@ class PostgresTx {
|
|
|
408
429
|
time: this.now(),
|
|
409
430
|
type,
|
|
410
431
|
payload,
|
|
432
|
+
...(writer ? { writer } : {}),
|
|
411
433
|
});
|
|
412
434
|
this.events.push(event);
|
|
413
435
|
this.generations.push(generation);
|
|
@@ -612,88 +634,151 @@ class PostgresTx {
|
|
|
612
634
|
this.check();
|
|
613
635
|
return this.bodies(sandboxes);
|
|
614
636
|
}
|
|
615
|
-
// ---
|
|
616
|
-
async
|
|
637
|
+
// --- Environments ----------------------------------------------------------
|
|
638
|
+
async environment(id, options = {}) {
|
|
617
639
|
this.check();
|
|
618
|
-
const query = this.db.select().from(
|
|
640
|
+
const query = this.db.select().from(environments).where(eq(environments.id, id));
|
|
619
641
|
const [row] = options.lock ? await query.for("update") : await query;
|
|
620
|
-
return row &&
|
|
642
|
+
return row && environmentOf(row);
|
|
621
643
|
}
|
|
622
|
-
async
|
|
644
|
+
async createEnvironment(row, limit) {
|
|
623
645
|
this.check();
|
|
624
646
|
// Every create takes this lock, so two never both see room for one more.
|
|
625
|
-
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext('nylorun.
|
|
647
|
+
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext('nylorun.environments'))`);
|
|
626
648
|
const [found] = await this.db
|
|
627
|
-
.select({ id:
|
|
628
|
-
.from(
|
|
629
|
-
.where(eq(
|
|
649
|
+
.select({ id: environments.id })
|
|
650
|
+
.from(environments)
|
|
651
|
+
.where(eq(environments.id, row.id));
|
|
630
652
|
if (found)
|
|
631
653
|
return "exists";
|
|
632
|
-
const [counted] = await this.db.select({ n: count() }).from(
|
|
654
|
+
const [counted] = await this.db.select({ n: count() }).from(environments);
|
|
633
655
|
if ((counted?.n ?? 0) >= limit)
|
|
634
656
|
return "limit";
|
|
635
|
-
const { pod, ...
|
|
636
|
-
await this.db.insert(
|
|
657
|
+
const { pod, ownerUserId, diskOp, diskSeed, manifestName, manifestVersion, manifestHash, forkedFrom, ...environment } = row;
|
|
658
|
+
await this.db.insert(environments).values({
|
|
659
|
+
...environment,
|
|
660
|
+
ownerUserId: ownerUserId ?? null,
|
|
661
|
+
diskOp: diskOp ?? null,
|
|
662
|
+
diskSeed: diskSeed ?? null,
|
|
663
|
+
manifestName: manifestName ?? null,
|
|
664
|
+
manifestVersion: manifestVersion ?? null,
|
|
665
|
+
manifestHash: manifestHash ?? null,
|
|
666
|
+
forkedFrom: forkedFrom ?? null,
|
|
667
|
+
...(pod ? podColumns(pod) : {}),
|
|
668
|
+
});
|
|
637
669
|
return "created";
|
|
638
670
|
}
|
|
639
|
-
async
|
|
640
|
-
this.check();
|
|
641
|
-
await this.db.update(sandboxResources).set({ spec, updatedAt }).where(eq(sandboxResources.id, id));
|
|
642
|
-
}
|
|
643
|
-
async updateSandboxPod(id, patch, updatedAt) {
|
|
671
|
+
async updateEnvironment(id, patch, updatedAt) {
|
|
644
672
|
this.check();
|
|
673
|
+
const columns = Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== undefined));
|
|
645
674
|
await this.db
|
|
646
|
-
.update(
|
|
647
|
-
.set({ ...
|
|
648
|
-
.where(eq(
|
|
675
|
+
.update(environments)
|
|
676
|
+
.set({ ...columns, updatedAt })
|
|
677
|
+
.where(eq(environments.id, id));
|
|
649
678
|
}
|
|
650
|
-
async
|
|
679
|
+
async updateEnvironmentPod(id, patch, updatedAt) {
|
|
651
680
|
this.check();
|
|
652
681
|
await this.db
|
|
653
|
-
.update(
|
|
654
|
-
.set({
|
|
655
|
-
.where(eq(
|
|
682
|
+
.update(environments)
|
|
683
|
+
.set({ ...podColumns(patch), updatedAt })
|
|
684
|
+
.where(eq(environments.id, id));
|
|
656
685
|
}
|
|
657
|
-
async
|
|
686
|
+
async deleteEnvironment(id) {
|
|
658
687
|
this.check();
|
|
659
|
-
|
|
688
|
+
// Its vault and credentials go with it (ON DELETE CASCADE).
|
|
689
|
+
await this.db.delete(environments).where(eq(environments.id, id));
|
|
660
690
|
}
|
|
661
|
-
async
|
|
691
|
+
async listEnvironments(filter = {}) {
|
|
662
692
|
this.check();
|
|
663
693
|
const labels = filter.labels;
|
|
664
694
|
const rows = await this.db
|
|
665
695
|
.select()
|
|
666
|
-
.from(
|
|
696
|
+
.from(environments)
|
|
667
697
|
.where(labels === undefined || Object.keys(labels).length === 0
|
|
668
698
|
? undefined
|
|
669
|
-
: sql `nylorun.doc(${
|
|
670
|
-
.orderBy(
|
|
671
|
-
return rows.map(
|
|
699
|
+
: sql `nylorun.doc(${environments.labels}) @> ${toJson(labels)}::jsonb`)
|
|
700
|
+
.orderBy(environments.id);
|
|
701
|
+
return rows.map(environmentOf);
|
|
702
|
+
}
|
|
703
|
+
// --- Environment manifests (D63) -----------------------------------------------
|
|
704
|
+
async lockEnvironmentManifest(name) {
|
|
705
|
+
this.check();
|
|
706
|
+
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext(${`nylorun.environment_manifests:${name}`}))`);
|
|
707
|
+
}
|
|
708
|
+
async environmentManifest(name, version) {
|
|
709
|
+
this.check();
|
|
710
|
+
const [row] = await this.db
|
|
711
|
+
.select()
|
|
712
|
+
.from(environmentManifests)
|
|
713
|
+
.where(version === undefined
|
|
714
|
+
? eq(environmentManifests.name, name)
|
|
715
|
+
: and(eq(environmentManifests.name, name), eq(environmentManifests.version, version)))
|
|
716
|
+
.orderBy(desc(environmentManifests.version))
|
|
717
|
+
.limit(1);
|
|
718
|
+
return row && environmentManifestOf(row);
|
|
719
|
+
}
|
|
720
|
+
async insertEnvironmentManifest(row) {
|
|
721
|
+
this.check();
|
|
722
|
+
await this.db.insert(environmentManifests).values(row);
|
|
672
723
|
}
|
|
673
|
-
async
|
|
724
|
+
async listEnvironmentManifests() {
|
|
725
|
+
this.check();
|
|
726
|
+
const rows = await this.db
|
|
727
|
+
.selectDistinctOn([environmentManifests.name])
|
|
728
|
+
.from(environmentManifests)
|
|
729
|
+
.orderBy(environmentManifests.name, desc(environmentManifests.version));
|
|
730
|
+
return rows.map(environmentManifestOf);
|
|
731
|
+
}
|
|
732
|
+
async environmentManifestVersions(name) {
|
|
733
|
+
this.check();
|
|
734
|
+
const rows = await this.db
|
|
735
|
+
.select()
|
|
736
|
+
.from(environmentManifests)
|
|
737
|
+
.where(eq(environmentManifests.name, name))
|
|
738
|
+
.orderBy(desc(environmentManifests.version));
|
|
739
|
+
return rows.map(environmentManifestOf);
|
|
740
|
+
}
|
|
741
|
+
async deleteEnvironmentManifest(name) {
|
|
742
|
+
this.check();
|
|
743
|
+
const deleted = await this.db
|
|
744
|
+
.delete(environmentManifests)
|
|
745
|
+
.where(eq(environmentManifests.name, name))
|
|
746
|
+
.returning({ version: environmentManifests.version });
|
|
747
|
+
return deleted.length;
|
|
748
|
+
}
|
|
749
|
+
async environmentsOfManifest(name) {
|
|
750
|
+
this.check();
|
|
751
|
+
const rows = await this.db
|
|
752
|
+
.select({ version: environments.manifestVersion, n: count() })
|
|
753
|
+
.from(environments)
|
|
754
|
+
.where(eq(environments.manifestName, name))
|
|
755
|
+
.groupBy(environments.manifestVersion);
|
|
756
|
+
return new Map(rows.filter((row) => row.version !== null).map((row) => [row.version, row.n]));
|
|
757
|
+
}
|
|
758
|
+
async sessionsOnEnvironment(environmentId) {
|
|
674
759
|
this.check();
|
|
675
760
|
const rows = await this.sessions()
|
|
676
|
-
.where(eq(sessions.
|
|
761
|
+
.where(eq(sessions.environmentId, environmentId))
|
|
677
762
|
.orderBy(sessions.id);
|
|
678
763
|
return rows.map((row) => storedSession(row));
|
|
679
764
|
}
|
|
680
|
-
async
|
|
765
|
+
async environmentEvent(environmentId, type, payload) {
|
|
681
766
|
this.check();
|
|
682
|
-
return
|
|
767
|
+
return appendEnvironmentEvent(postgresEnvironmentRecordWriter(this.db), {
|
|
683
768
|
tenantId: this.tenantId,
|
|
684
|
-
|
|
769
|
+
environmentId,
|
|
685
770
|
time: this.now(),
|
|
686
771
|
type,
|
|
687
772
|
payload,
|
|
688
773
|
});
|
|
689
774
|
}
|
|
690
|
-
async
|
|
775
|
+
async environmentEvents(environmentId, options = {}) {
|
|
691
776
|
this.check();
|
|
692
777
|
const rows = await this.db
|
|
693
|
-
.select({ body:
|
|
694
|
-
.from(
|
|
695
|
-
.where(and(eq(
|
|
696
|
-
.orderBy(
|
|
778
|
+
.select({ body: environmentEvents.body })
|
|
779
|
+
.from(environmentEvents)
|
|
780
|
+
.where(and(eq(environmentEvents.environmentId, environmentId), options.fromSeq === undefined ? undefined : gte(environmentEvents.seq, options.fromSeq), options.types === undefined ? undefined : inArray(environmentEvents.type, [...options.types]), options.since === undefined ? undefined : gte(environmentEvents.committedAt, options.since), options.until === undefined ? undefined : lt(environmentEvents.committedAt, options.until)))
|
|
781
|
+
.orderBy(environmentEvents.seq)
|
|
697
782
|
.limit(options.limit ?? 1000);
|
|
698
783
|
return rows.map((row) => row.body);
|
|
699
784
|
}
|
|
@@ -831,21 +916,13 @@ class PostgresTx {
|
|
|
831
916
|
const [row] = await this.db.select().from(vaults).where(eq(vaults.id, id));
|
|
832
917
|
return row;
|
|
833
918
|
}
|
|
834
|
-
async
|
|
835
|
-
this.check();
|
|
836
|
-
return this.db
|
|
837
|
-
.select()
|
|
838
|
-
.from(vaults)
|
|
839
|
-
.where(and(eq(vaults.ownerUserId, ownerUserId), eq(vaults.scope, "user")))
|
|
840
|
-
.orderBy(vaults.createdAt, vaults.id);
|
|
841
|
-
}
|
|
842
|
-
async installationVaults() {
|
|
919
|
+
async vaultOfEnvironment(environmentId) {
|
|
843
920
|
this.check();
|
|
844
|
-
|
|
921
|
+
const [row] = await this.db
|
|
845
922
|
.select()
|
|
846
923
|
.from(vaults)
|
|
847
|
-
.where(eq(vaults.
|
|
848
|
-
|
|
924
|
+
.where(eq(vaults.environmentId, environmentId));
|
|
925
|
+
return row;
|
|
849
926
|
}
|
|
850
927
|
async updateVaultMetadata(id, metadataJson) {
|
|
851
928
|
this.check();
|
|
@@ -868,6 +945,14 @@ class PostgresTx {
|
|
|
868
945
|
.where(eq(vaultCredentials.id, id));
|
|
869
946
|
return row;
|
|
870
947
|
}
|
|
948
|
+
async credentialByName(vaultId, name) {
|
|
949
|
+
this.check();
|
|
950
|
+
const [row] = await this.db
|
|
951
|
+
.select()
|
|
952
|
+
.from(vaultCredentials)
|
|
953
|
+
.where(and(eq(vaultCredentials.vaultId, vaultId), eq(vaultCredentials.name, name)));
|
|
954
|
+
return row;
|
|
955
|
+
}
|
|
871
956
|
async credentialsForVault(vaultId, filter = {}) {
|
|
872
957
|
this.check();
|
|
873
958
|
return this.db
|
|
@@ -976,6 +1061,16 @@ class PostgresTx {
|
|
|
976
1061
|
.returning();
|
|
977
1062
|
return inserted;
|
|
978
1063
|
}
|
|
1064
|
+
async modelUsageOf(effectKey) {
|
|
1065
|
+
this.check();
|
|
1066
|
+
const [row] = await this.db
|
|
1067
|
+
.select()
|
|
1068
|
+
.from(modelUsage)
|
|
1069
|
+
.where(and(eq(modelUsage.effectKey, effectKey), eq(modelUsage.duplicate, false)))
|
|
1070
|
+
.orderBy(modelUsage.createdAt, modelUsage.id)
|
|
1071
|
+
.limit(1);
|
|
1072
|
+
return row;
|
|
1073
|
+
}
|
|
979
1074
|
async modelUsageTotals(query) {
|
|
980
1075
|
this.check();
|
|
981
1076
|
const [row] = await this.db
|
|
@@ -1016,6 +1111,15 @@ class PostgresTx {
|
|
|
1016
1111
|
.returning({ key: toolCrossings.key });
|
|
1017
1112
|
return inserted.length === 1;
|
|
1018
1113
|
}
|
|
1114
|
+
async restartToolCrossing(row) {
|
|
1115
|
+
this.check();
|
|
1116
|
+
const restarted = await this.db
|
|
1117
|
+
.update(toolCrossings)
|
|
1118
|
+
.set({ startedAt: row.startedAt })
|
|
1119
|
+
.where(and(eq(toolCrossings.key, row.key), eq(toolCrossings.hash, row.hash), isNull(toolCrossings.settledAt)))
|
|
1120
|
+
.returning({ key: toolCrossings.key });
|
|
1121
|
+
return restarted.length === 1;
|
|
1122
|
+
}
|
|
1019
1123
|
async settleToolCrossing(key, answer, settledAt) {
|
|
1020
1124
|
this.check();
|
|
1021
1125
|
await this.db
|
|
@@ -1038,6 +1142,12 @@ class PostgresTx {
|
|
|
1038
1142
|
const [row] = options.lock ? await query.for("update") : await query;
|
|
1039
1143
|
return row;
|
|
1040
1144
|
}
|
|
1145
|
+
async diskArtifact(environmentId, options = {}) {
|
|
1146
|
+
this.check();
|
|
1147
|
+
const query = this.db.select().from(artifacts).where(eq(artifacts.environmentId, environmentId));
|
|
1148
|
+
const [row] = options.lock ? await query.for("update") : await query;
|
|
1149
|
+
return row;
|
|
1150
|
+
}
|
|
1041
1151
|
async listArtifacts(filter = {}) {
|
|
1042
1152
|
this.check();
|
|
1043
1153
|
return this.db
|
|
@@ -1088,6 +1198,24 @@ class PostgresTx {
|
|
|
1088
1198
|
await this.db.delete(artifacts).where(eq(artifacts.id, id));
|
|
1089
1199
|
return deleted.map((row) => row.blobKey);
|
|
1090
1200
|
}
|
|
1201
|
+
async deleteArtifactVersion(artifactId, version) {
|
|
1202
|
+
this.check();
|
|
1203
|
+
const [deleted] = await this.db
|
|
1204
|
+
.delete(artifactVersions)
|
|
1205
|
+
.where(and(eq(artifactVersions.artifactId, artifactId), eq(artifactVersions.version, version)))
|
|
1206
|
+
.returning({ blobKey: artifactVersions.blobKey });
|
|
1207
|
+
if (!deleted)
|
|
1208
|
+
return undefined;
|
|
1209
|
+
const [left] = await this.db
|
|
1210
|
+
.select({ latest: sql `max(${artifactVersions.version})` })
|
|
1211
|
+
.from(artifactVersions)
|
|
1212
|
+
.where(eq(artifactVersions.artifactId, artifactId));
|
|
1213
|
+
await this.db
|
|
1214
|
+
.update(artifacts)
|
|
1215
|
+
.set({ latestVersion: Number(left?.latest ?? 0), updatedAt: new Date().toISOString() })
|
|
1216
|
+
.where(eq(artifacts.id, artifactId));
|
|
1217
|
+
return deleted.blobKey;
|
|
1218
|
+
}
|
|
1091
1219
|
async lockArtifactQuota() {
|
|
1092
1220
|
this.check();
|
|
1093
1221
|
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext('nylorun.artifacts'))`);
|
|
@@ -1228,10 +1356,11 @@ class PostgresTx {
|
|
|
1228
1356
|
basinGeneration: sql `${tenant.basinGeneration} + 1`,
|
|
1229
1357
|
});
|
|
1230
1358
|
}
|
|
1231
|
-
if (scope === "
|
|
1359
|
+
if (scope === "environments" || scope === "all") {
|
|
1232
1360
|
await db.delete(sandboxes);
|
|
1233
|
-
|
|
1234
|
-
await db.delete(
|
|
1361
|
+
// Their vaults and credentials go with them (ON DELETE CASCADE).
|
|
1362
|
+
await db.delete(environments);
|
|
1363
|
+
await db.delete(environmentEvents);
|
|
1235
1364
|
await db.delete(sandboxSignals);
|
|
1236
1365
|
}
|
|
1237
1366
|
if (scope === "all") {
|
|
@@ -1241,7 +1370,6 @@ class PostgresTx {
|
|
|
1241
1370
|
await db.delete(modelUsage);
|
|
1242
1371
|
await db.delete(modelBudgets);
|
|
1243
1372
|
await db.delete(artifacts);
|
|
1244
|
-
await db.delete(vaults).where(ne(vaults.scope, "host"));
|
|
1245
1373
|
}
|
|
1246
1374
|
}
|
|
1247
1375
|
}
|