@nylorun/runtime 0.26.0-beta → 0.28.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 +171 -0
- package/README.md +18 -14
- package/dist/adapters/execution/restate.d.ts +15 -18
- package/dist/adapters/execution/restate.js +31 -27
- package/dist/adapters/replication/pgoutput.d.ts +1 -1
- package/dist/adapters/replication/pgoutput.js +3 -2
- package/dist/adapters/sandbox/local.js +8 -5
- package/dist/adapters/sandbox/virtual.js +2 -2
- package/dist/adapters/streams/s2.d.ts +1 -1
- package/dist/adapters/streams/s2.js +18 -14
- package/dist/api/a2a/card.d.ts +4 -3
- package/dist/api/a2a/card.js +4 -4
- package/dist/api/a2a/endpoint.js +3 -4
- package/dist/api/a2a/protocol.js +4 -0
- package/dist/api/a2a/routes.d.ts +2 -6
- package/dist/api/a2a/routes.js +30 -25
- package/dist/api/ag-ui/endpoint.js +2 -3
- package/dist/api/ag-ui/routes.js +8 -11
- package/dist/api/components.d.ts +6789 -3405
- package/dist/api/components.js +43 -30
- package/dist/api/gate/keys.js +7 -4
- package/dist/api/gate/routes.d.ts +6 -2
- package/dist/api/gate/routes.js +15 -11
- package/dist/api/http/app.js +9 -4
- package/dist/api/http/body.d.ts +17 -3
- package/dist/api/http/body.js +35 -7
- package/dist/api/http/respond.js +6 -2
- package/dist/api/http/routes/access.js +5 -4
- package/dist/api/http/routes/agent-manifests.d.ts +10 -0
- package/dist/api/http/routes/agent-manifests.js +135 -0
- package/dist/api/http/routes/agents.d.ts +11 -0
- package/dist/api/http/routes/agents.js +418 -0
- package/dist/api/http/routes/artifacts.js +21 -9
- package/dist/api/http/routes/coverage.d.ts +4 -4
- package/dist/api/http/routes/coverage.js +13 -7
- package/dist/api/http/routes/files.d.ts +2 -1
- package/dist/api/http/routes/files.js +31 -5
- package/dist/api/http/routes/mcp.js +3 -3
- package/dist/api/http/routes/me.d.ts +1 -1
- package/dist/api/http/routes/me.js +1 -2
- package/dist/api/http/routes/memories.d.ts +9 -0
- package/dist/api/http/routes/memories.js +152 -0
- package/dist/api/http/routes/reads.d.ts +10 -111
- package/dist/api/http/routes/reads.js +51 -29
- package/dist/api/http/routes/sessions.js +26 -54
- package/dist/api/http/routes/tenant.d.ts +2 -2
- package/dist/api/http/routes/tenant.js +77 -24
- package/dist/api/http/routes/triggers.d.ts +10 -0
- package/dist/api/http/routes/triggers.js +180 -0
- package/dist/api/inbound-files.d.ts +3 -9
- package/dist/api/inbound-files.js +18 -24
- package/dist/api/openapi.js +73 -47
- package/dist/artifacts/disk.d.ts +10 -14
- package/dist/artifacts/disk.js +99 -95
- package/dist/artifacts/files.d.ts +13 -4
- package/dist/artifacts/files.js +27 -9
- package/dist/artifacts/folder-upload.d.ts +75 -0
- package/dist/artifacts/folder-upload.js +263 -0
- package/dist/artifacts/folders.d.ts +14 -8
- package/dist/artifacts/folders.js +19 -11
- package/dist/artifacts/links.js +7 -6
- package/dist/artifacts/parts.d.ts +9 -14
- package/dist/artifacts/parts.js +11 -9
- package/dist/artifacts/pipe.d.ts +15 -0
- package/dist/artifacts/pipe.js +71 -0
- package/dist/artifacts/quota.d.ts +36 -0
- package/dist/artifacts/quota.js +44 -0
- package/dist/artifacts/service.d.ts +25 -1
- package/dist/artifacts/service.js +72 -27
- package/dist/blob/fs.js +2 -1
- package/dist/blob/s3.d.ts +6 -2
- package/dist/blob/s3.js +9 -7
- package/dist/blob/types.d.ts +1 -1
- package/dist/blob/types.js +1 -1
- package/dist/core/flow-host.d.ts +0 -1
- package/dist/core/limits.d.ts +11 -35
- package/dist/core/limits.js +5 -73
- package/dist/core/sandbox-routes.js +0 -1
- package/dist/core/turn-manifest.d.ts +1 -2
- package/dist/core/turn-manifest.js +4 -28
- package/dist/execution/memory.d.ts +8 -5
- package/dist/execution/memory.js +8 -6
- package/dist/execution/types.d.ts +1 -6
- package/dist/execution/types.js +0 -5
- package/dist/gates/contract.d.ts +3 -2
- package/dist/gates/contract.js +1 -1
- package/dist/gates/egress-credentials.js +5 -4
- package/dist/gates/egress.d.ts +13 -13
- package/dist/gates/egress.js +19 -21
- package/dist/gates/fixture-model.js +13 -2
- package/dist/gates/handler.d.ts +1 -3
- package/dist/gates/handler.js +4 -3
- package/dist/gates/http-client.d.ts +4 -3
- package/dist/gates/http-client.js +5 -7
- package/dist/gates/http-tool.d.ts +24 -4
- package/dist/gates/http-tool.js +41 -13
- package/dist/gates/in-process.d.ts +2 -1
- package/dist/gates/in-process.js +17 -9
- package/dist/gates/inflight.d.ts +2 -2
- package/dist/gates/inflight.js +3 -2
- package/dist/gates/journal.js +5 -7
- package/dist/gates/mcp-handler.d.ts +4 -3
- package/dist/gates/mcp-handler.js +15 -5
- package/dist/gates/meter.js +6 -5
- package/dist/gates/model-gate.d.ts +11 -2
- package/dist/gates/policy.d.ts +34 -6
- package/dist/gates/policy.js +66 -18
- package/dist/gates/provider-gate.d.ts +22 -0
- package/dist/gates/provider-gate.js +30 -0
- package/dist/gates/tool-calls.d.ts +1 -3
- package/dist/gates/tool-calls.js +2 -3
- package/dist/gates/tool-client.d.ts +1 -1
- package/dist/gates/tool-client.js +5 -6
- package/dist/gates/tool-contract.d.ts +8 -5
- package/dist/gates/tool-contract.js +1 -1
- package/dist/gates/tool-gate.d.ts +18 -7
- package/dist/gates/tool-gate.js +49 -7
- package/dist/harness/calls.d.ts +27 -25
- package/dist/harness/calls.js +40 -46
- package/dist/harness/executors.d.ts +10 -3
- package/dist/harness/executors.js +53 -23
- package/dist/harness/main.js +2 -2
- package/dist/harness/pod.d.ts +2 -2
- package/dist/harness/pod.js +7 -6
- package/dist/harness/run-tokens.d.ts +4 -1
- package/dist/harness/run-tokens.js +6 -2
- package/dist/harness/service.d.ts +17 -14
- package/dist/harness/service.js +21 -35
- package/dist/harness/setup.d.ts +0 -2
- package/dist/harness/setup.js +21 -15
- package/dist/harness/ws-client.d.ts +2 -2
- package/dist/harness/ws-client.js +7 -5
- package/dist/harness/ws-port.d.ts +3 -4
- package/dist/harness/ws-port.js +3 -4
- package/dist/harness-api/artifacts.d.ts +20 -0
- package/dist/harness-api/artifacts.js +478 -0
- package/dist/harness-api/in-process.d.ts +2 -2
- package/dist/harness-api/in-process.js +18 -16
- package/dist/harness-api/record.d.ts +10 -9
- package/dist/harness-api/record.js +113 -157
- package/dist/harness-api/renew.d.ts +1 -1
- package/dist/harness-api/renew.js +2 -2
- package/dist/harness-api/server.d.ts +1 -16
- package/dist/harness-api/server.js +86 -73
- package/dist/harness-api/start.d.ts +27 -5
- package/dist/harness-api/start.js +102 -19
- package/dist/harness-api/tool-journal.d.ts +15 -10
- package/dist/harness-api/tool-journal.js +26 -24
- package/dist/harness-api/workspace.d.ts +0 -4
- package/dist/harness-api/workspace.js +4 -47
- package/dist/harness-api/ws-server.js +10 -10
- package/dist/host/create-host.js +2 -3
- package/dist/host/execution.js +2 -3
- package/dist/host/gates.d.ts +2 -9
- package/dist/host/gates.js +15 -12
- package/dist/host/http.d.ts +2 -4
- package/dist/host/http.js +5 -29
- package/dist/host/main.js +10 -3
- package/dist/host/operate.js +12 -3
- package/dist/host/stack-config.d.ts +11 -0
- package/dist/host/stack-config.js +21 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/infra/index.js +2 -1
- package/dist/infra/readiness.d.ts +0 -2
- package/dist/infra/readiness.js +4 -3
- package/dist/keys/client.d.ts +1 -0
- package/dist/keys/client.js +2 -3
- package/dist/keys/contract.d.ts +0 -2
- package/dist/keys/contract.js +0 -2
- package/dist/keys/egress-ca.d.ts +0 -2
- package/dist/keys/egress-ca.js +2 -3
- package/dist/keys/keys.d.ts +15 -4
- package/dist/keys/keys.js +22 -1
- package/dist/keys/webhooks.d.ts +25 -0
- package/dist/keys/webhooks.js +62 -0
- package/dist/keys/x509.d.ts +8 -4
- package/dist/keys/x509.js +14 -5
- package/dist/management-openapi.json +3043 -1954
- package/dist/mcp/connect.d.ts +35 -26
- package/dist/mcp/connect.js +112 -141
- package/dist/mcp/pool.d.ts +27 -22
- package/dist/mcp/pool.js +34 -48
- package/dist/mcp/preview.d.ts +12 -5
- package/dist/mcp/preview.js +43 -26
- package/dist/mcp/snapshot.d.ts +35 -86
- package/dist/mcp/snapshot.js +93 -135
- package/dist/memory/service.d.ts +97 -0
- package/dist/memory/service.js +335 -0
- package/dist/memory/tool.d.ts +36 -0
- package/dist/memory/tool.js +84 -0
- package/dist/model/auth-store.js +5 -3
- package/dist/model/capabilities.d.ts +1 -1
- package/dist/model/catalog.d.ts +9 -36
- package/dist/model/catalog.js +6 -33
- package/dist/model/descriptor.d.ts +51 -0
- package/dist/model/descriptor.js +83 -0
- package/dist/model/models.d.ts +0 -3
- package/dist/model/models.js +3 -5
- package/dist/model/native-blocks.js +1 -1
- package/dist/model/pi-model.d.ts +16 -5
- package/dist/model/pi-model.js +86 -105
- package/dist/openapi.json +13653 -9986
- package/dist/reads/cursor.js +3 -1
- package/dist/reads/types.d.ts +3 -3
- package/dist/record/agent.d.ts +27 -0
- package/dist/record/agent.js +46 -0
- package/dist/record/append.d.ts +34 -2
- package/dist/record/append.js +50 -1
- package/dist/record/index.d.ts +2 -2
- package/dist/record/index.js +2 -2
- package/dist/redact.d.ts +1 -1
- package/dist/redact.js +3 -2
- package/dist/sandbox/egress-token.d.ts +3 -3
- package/dist/sandbox/egress-token.js +3 -3
- package/dist/sandbox/join.js +8 -7
- package/dist/sandbox/manager.d.ts +41 -41
- package/dist/sandbox/manager.js +112 -44
- package/dist/sandbox/placement.d.ts +2 -2
- package/dist/sandbox/placement.js +7 -10
- package/dist/sandbox/pods/client.d.ts +1 -10
- package/dist/sandbox/pods/client.js +8 -4
- package/dist/sandbox/pods/lifecycle.d.ts +25 -17
- package/dist/sandbox/pods/lifecycle.js +51 -29
- package/dist/sandbox/pods/network-gate.d.ts +4 -5
- package/dist/sandbox/pods/network-gate.js +7 -7
- package/dist/sandbox/pods/reconcile.js +14 -3
- package/dist/sandbox/pods/spec.js +8 -5
- package/dist/sandbox/policy.d.ts +7 -1
- package/dist/sandbox/policy.js +10 -3
- package/dist/sandbox/resolve.d.ts +11 -6
- package/dist/sandbox/resolve.js +19 -9
- package/dist/sandbox/setup.d.ts +6 -2
- package/dist/sandbox/setup.js +47 -14
- package/dist/sandbox/share.d.ts +5 -14
- package/dist/sandbox/share.js +5 -34
- package/dist/sandbox/skills.d.ts +7 -13
- package/dist/sandbox/skills.js +16 -31
- package/dist/sandbox/tenant-config.d.ts +2 -2
- package/dist/sandbox/tenant-config.js +4 -3
- package/dist/sandbox/tools.d.ts +7 -1
- package/dist/sandbox/tools.js +26 -26
- package/dist/sandbox/types.d.ts +10 -3
- package/dist/sandbox/types.js +9 -0
- package/dist/store/postgres/connect.d.ts +6 -5
- package/dist/store/postgres/connect.js +14 -11
- package/dist/store/postgres/control.js +13 -13
- package/dist/store/postgres/drizzle/0028_artifact_write_keys.sql +2 -0
- package/dist/store/postgres/drizzle/0029_protocol_15.sql +11 -0
- package/dist/store/postgres/drizzle/0030_protocol_15_runtime_block.sql +11 -0
- package/dist/store/postgres/drizzle/0031_protocol_15_mcp_snapshot.sql +8 -0
- package/dist/store/postgres/drizzle/0032_agents.sql +54 -0
- package/dist/store/postgres/drizzle/0033_agent_versions.sql +7 -0
- package/dist/store/postgres/drizzle/0034_protocol_17_session_queue.sql +13 -0
- package/dist/store/postgres/drizzle/0035_t4_triggers.sql +41 -0
- package/dist/store/postgres/drizzle/0036_t5_memories.sql +30 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +63 -0
- package/dist/store/postgres/reads.js +17 -82
- package/dist/store/postgres/record-writer.d.ts +4 -4
- package/dist/store/postgres/record-writer.js +9 -9
- package/dist/store/postgres/schema.d.ts +1382 -151
- package/dist/store/postgres/schema.js +191 -37
- package/dist/store/postgres/store.js +384 -105
- package/dist/store/postgres/tenant.js +1 -2
- package/dist/store/types.d.ts +172 -57
- package/dist/store/types.js +0 -1
- package/dist/streams/relay/core.d.ts +3 -3
- package/dist/streams/relay/core.js +9 -10
- package/dist/tenant/advance.js +41 -39
- package/dist/tenant/agent-manifests.d.ts +72 -0
- package/dist/tenant/agent-manifests.js +359 -0
- package/dist/tenant/agent-versions.d.ts +126 -0
- package/dist/tenant/agent-versions.js +389 -0
- package/dist/tenant/agents.d.ts +230 -0
- package/dist/tenant/{environments.js → agents.js} +493 -328
- package/dist/tenant/auth.d.ts +1 -1
- package/dist/tenant/auth.js +3 -3
- package/dist/tenant/commands.d.ts +63 -2
- package/dist/tenant/commands.js +240 -90
- package/dist/tenant/context.d.ts +57 -33
- package/dist/tenant/context.js +6 -2
- package/dist/tenant/definition-files.d.ts +25 -4
- package/dist/tenant/definition-files.js +85 -47
- package/dist/tenant/effects.js +15 -51
- package/dist/tenant/ephemeral.js +2 -1
- package/dist/tenant/history.d.ts +1 -1
- package/dist/tenant/history.js +1 -1
- package/dist/tenant/host-token.d.ts +3 -3
- package/dist/tenant/host-token.js +11 -10
- package/dist/tenant/http.d.ts +5 -8
- package/dist/tenant/http.js +9 -0
- package/dist/tenant/identity-file.d.ts +29 -6
- package/dist/tenant/identity-file.js +45 -15
- package/dist/tenant/issuers.d.ts +5 -5
- package/dist/tenant/issuers.js +34 -26
- package/dist/tenant/jwt.d.ts +8 -2
- package/dist/tenant/jwt.js +10 -2
- package/dist/tenant/limits.d.ts +87 -0
- package/dist/tenant/limits.js +172 -0
- package/dist/tenant/memories.d.ts +38 -0
- package/dist/tenant/memories.js +119 -0
- package/dist/tenant/module.d.ts +4 -1
- package/dist/tenant/module.js +9 -8
- package/dist/tenant/outbound.d.ts +11 -14
- package/dist/tenant/outbound.js +10 -15
- package/dist/tenant/reset.js +2 -2
- package/dist/tenant/run-grants.d.ts +6 -0
- package/dist/tenant/run-grants.js +7 -2
- package/dist/tenant/run-token.d.ts +0 -4
- package/dist/tenant/run-token.js +6 -11
- package/dist/tenant/runtime-limits.d.ts +24 -0
- package/dist/tenant/runtime-limits.js +27 -0
- package/dist/tenant/runtime.d.ts +1 -1
- package/dist/tenant/runtime.js +38 -43
- package/dist/tenant/session-streams.js +7 -6
- package/dist/tenant/session.d.ts +1 -1
- package/dist/tenant/session.js +1 -1
- package/dist/tenant/sessions.d.ts +28 -45
- package/dist/tenant/sessions.js +89 -209
- package/dist/tenant/signing-keys.d.ts +1 -1
- package/dist/tenant/signing-keys.js +5 -6
- package/dist/tenant/status.js +10 -10
- package/dist/tenant/streams.js +18 -20
- package/dist/tenant/sweep.d.ts +1 -21
- package/dist/tenant/sweep.js +51 -51
- package/dist/tenant/transcript.d.ts +70 -23
- package/dist/tenant/transcript.js +28 -22
- package/dist/tenant/triggers.d.ts +143 -0
- package/dist/tenant/triggers.js +715 -0
- package/dist/tenant/turn-timing.d.ts +11 -1
- package/dist/tenant/turn-timing.js +3 -1
- package/dist/tenant/types.d.ts +9 -14
- package/dist/tenant/worker.d.ts +4 -10
- package/dist/tenant/worker.js +10 -14
- package/dist/traces/ids.js +5 -1
- package/dist/traces/map.d.ts +10 -7
- package/dist/traces/map.js +16 -12
- package/dist/traces/otlp.d.ts +3 -3
- package/dist/traces/otlp.js +5 -3
- package/dist/traces/projector.d.ts +9 -4
- package/dist/traces/projector.js +13 -7
- package/dist/traces/read.js +6 -1
- package/dist/tuning.d.ts +390 -0
- package/dist/tuning.js +677 -0
- package/dist/vault/headers.js +4 -2
- package/dist/vault/service.d.ts +13 -8
- package/dist/vault/service.js +61 -17
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +13 -12
- package/dist/api/http/routes/environment-manifests.d.ts +0 -9
- package/dist/api/http/routes/environment-manifests.js +0 -118
- package/dist/api/http/routes/environments.d.ts +0 -11
- package/dist/api/http/routes/environments.js +0 -332
- package/dist/artifacts/export.d.ts +0 -8
- package/dist/artifacts/export.js +0 -204
- package/dist/artifacts/media-types.d.ts +0 -30
- package/dist/artifacts/media-types.js +0 -137
- package/dist/artifacts/workspace.d.ts +0 -60
- package/dist/artifacts/workspace.js +0 -45
- package/dist/media.d.ts +0 -10
- package/dist/media.js +0 -58
- package/dist/record/environment.d.ts +0 -25
- package/dist/record/environment.js +0 -44
- package/dist/sandbox/runtime-tools.d.ts +0 -9
- package/dist/sandbox/runtime-tools.js +0 -16
- package/dist/sandbox/session-sandbox.d.ts +0 -16
- package/dist/sandbox/session-sandbox.js +0 -77
- package/dist/tenant/artifact-tool.d.ts +0 -13
- package/dist/tenant/artifact-tool.js +0 -243
- package/dist/tenant/environment-manifests.d.ts +0 -57
- package/dist/tenant/environment-manifests.js +0 -200
- package/dist/tenant/environments.d.ts +0 -174
- package/dist/tenant/skill-tool.d.ts +0 -20
- package/dist/tenant/skill-tool.js +0 -67
- package/dist/tenant/tool-results.d.ts +0 -57
- package/dist/tenant/tool-results.js +0 -298
- package/dist/tenant/tool-search.d.ts +0 -39
- package/dist/tenant/tool-search.js +0 -103
|
@@ -51,22 +51,23 @@
|
|
|
51
51
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
52
52
|
import { randomUUID } from "node:crypto";
|
|
53
53
|
import { and, count, desc, eq, getTableColumns, gte, gt, inArray, isNotNull, isNull, lt, lte, ne, or, sql, } from "drizzle-orm";
|
|
54
|
-
import {
|
|
54
|
+
import { appendAgentEvent, appendEvent } from "../../record/index.js";
|
|
55
|
+
import { readRuntimeLimits } from "../../tenant/runtime-limits.js";
|
|
55
56
|
import { OwnershipLostError, PrincipalRoleConflict } from "../ownership.js";
|
|
56
57
|
import { followControlSignals, pruneSignals, writeSignal } from "./control.js";
|
|
57
58
|
import { database, driverError } from "./db.js";
|
|
58
59
|
import { expectedSchemaVersion, readSchemaVersion } from "./migrate.js";
|
|
60
|
+
import { hostTuning } from "../../tuning.js";
|
|
59
61
|
import { createPostgresRecordReader } from "./record.js";
|
|
60
|
-
import {
|
|
61
|
-
import { artifacts, artifactVersions, artifactContent, definitionFiles, definitionFileUses, commands,
|
|
62
|
+
import { postgresAgentRecordWriter, postgresRecordWriter } from "./record-writer.js";
|
|
63
|
+
import { artifacts, artifactVersions, artifactContent, definitionFiles, definitionFileUses, commands, effects, links, modelBudgets, modelUsage, principals, sandboxes, agentEvents, agents, agentManifests, sessionEvents, sessionLogHeads, sessions, sessionQueue, agentTriggers, triggerRuns, memories, memoryVersions, toJson, toolCrossings, signingKeys, tenant, tenantSettings, vaultAudit, vaultCredentials, vaultIdempotency, vaults, sandboxSignals, wakes, } from "./schema.js";
|
|
62
64
|
export function createPostgresSessionStore(options) {
|
|
63
65
|
return new PostgresSessionStore(options);
|
|
64
66
|
}
|
|
65
67
|
const OPEN_SESSION = ["running", "runnable"];
|
|
66
|
-
/** Rows per statement when a folder version names many files. */
|
|
67
|
-
const
|
|
68
|
+
/** Rows per statement when a folder version or a definition names many files (Host tuning). */
|
|
69
|
+
const contentBatch = () => hostTuning().postgres.contentBatchRows;
|
|
68
70
|
const DOCUMENTS = {
|
|
69
|
-
definitions,
|
|
70
71
|
sessions: sessions,
|
|
71
72
|
commands,
|
|
72
73
|
effects: effects,
|
|
@@ -255,10 +256,15 @@ function environmentOf(row) {
|
|
|
255
256
|
updatedAt: row.updatedAt,
|
|
256
257
|
...(row.diskOp ? { diskOp: row.diskOp } : {}),
|
|
257
258
|
...(row.diskSeed ? { diskSeed: row.diskSeed } : {}),
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
259
|
+
manifestName: row.manifestName,
|
|
260
|
+
manifestVersion: row.manifestVersion,
|
|
261
|
+
manifestRef: row.manifestRef,
|
|
262
|
+
manifestHash: row.manifestHash,
|
|
263
|
+
desiredState: row.desiredState,
|
|
261
264
|
...(row.forkedFrom ? { forkedFrom: row.forkedFrom } : {}),
|
|
265
|
+
...(row.targetVersion !== null ? { targetVersion: row.targetVersion } : {}),
|
|
266
|
+
...(row.failedVersion !== null ? { failedVersion: row.failedVersion } : {}),
|
|
267
|
+
...(row.startCheck ? { startCheck: row.startCheck } : {}),
|
|
262
268
|
...(row.k8sName !== null && row.desired !== null && row.observed !== null
|
|
263
269
|
? {
|
|
264
270
|
pod: {
|
|
@@ -281,7 +287,7 @@ function environmentOf(row) {
|
|
|
281
287
|
: {}),
|
|
282
288
|
};
|
|
283
289
|
}
|
|
284
|
-
function
|
|
290
|
+
function agentManifestOf(row) {
|
|
285
291
|
return {
|
|
286
292
|
name: row.name,
|
|
287
293
|
version: row.version,
|
|
@@ -320,7 +326,7 @@ const SIGNING_KEY_STAMP = {
|
|
|
320
326
|
};
|
|
321
327
|
/** The audit columns a row has (`ord` only orders them). */
|
|
322
328
|
const { ord: _ord, ...AUDIT } = getTableColumns(vaultAudit);
|
|
323
|
-
const SESSION_TABLES = [sessions, commands, effects, links, wakes];
|
|
329
|
+
const SESSION_TABLES = [sessions, commands, effects, links, wakes, sessionQueue];
|
|
324
330
|
/**
|
|
325
331
|
* The outbox's tables, by the kind of request each holds. Their delivery columns (`id`,
|
|
326
332
|
* `created_at`, `attempts`, `retry_at`, `parked_at`) are the same.
|
|
@@ -430,6 +436,7 @@ class PostgresTx {
|
|
|
430
436
|
type,
|
|
431
437
|
payload,
|
|
432
438
|
...(writer ? { writer } : {}),
|
|
439
|
+
maxEntryBytes: await this.maxEntryBytes(),
|
|
433
440
|
});
|
|
434
441
|
this.events.push(event);
|
|
435
442
|
this.generations.push(generation);
|
|
@@ -626,44 +633,40 @@ class PostgresTx {
|
|
|
626
633
|
const rows = await this.db.select({ body: table.body }).from(table).orderBy(table.id);
|
|
627
634
|
return rows.map((row) => row.body);
|
|
628
635
|
}
|
|
629
|
-
async listDefinitions() {
|
|
630
|
-
this.check();
|
|
631
|
-
return this.bodies(definitions);
|
|
632
|
-
}
|
|
633
636
|
async listSandboxes() {
|
|
634
637
|
this.check();
|
|
635
638
|
return this.bodies(sandboxes);
|
|
636
639
|
}
|
|
637
|
-
// ---
|
|
640
|
+
// --- Agents ----------------------------------------------------------------
|
|
638
641
|
async environment(id, options = {}) {
|
|
639
642
|
this.check();
|
|
640
|
-
const query = this.db.select().from(
|
|
643
|
+
const query = this.db.select().from(agents).where(eq(agents.id, id));
|
|
641
644
|
const [row] = options.lock ? await query.for("update") : await query;
|
|
642
645
|
return row && environmentOf(row);
|
|
643
646
|
}
|
|
644
647
|
async createEnvironment(row, limit) {
|
|
645
648
|
this.check();
|
|
646
649
|
// Every create takes this lock, so two never both see room for one more.
|
|
647
|
-
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext('nylorun.
|
|
650
|
+
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext('nylorun.agents'))`);
|
|
648
651
|
const [found] = await this.db
|
|
649
|
-
.select({ id:
|
|
650
|
-
.from(
|
|
651
|
-
.where(eq(
|
|
652
|
+
.select({ id: agents.id })
|
|
653
|
+
.from(agents)
|
|
654
|
+
.where(eq(agents.id, row.id));
|
|
652
655
|
if (found)
|
|
653
656
|
return "exists";
|
|
654
|
-
const [counted] = await this.db.select({ n: count() }).from(
|
|
657
|
+
const [counted] = await this.db.select({ n: count() }).from(agents);
|
|
655
658
|
if ((counted?.n ?? 0) >= limit)
|
|
656
659
|
return "limit";
|
|
657
|
-
const { pod, ownerUserId, diskOp, diskSeed,
|
|
658
|
-
await this.db.insert(
|
|
660
|
+
const { pod, ownerUserId, diskOp, diskSeed, forkedFrom, targetVersion, failedVersion, startCheck, ...environment } = row;
|
|
661
|
+
await this.db.insert(agents).values({
|
|
659
662
|
...environment,
|
|
660
663
|
ownerUserId: ownerUserId ?? null,
|
|
661
664
|
diskOp: diskOp ?? null,
|
|
662
665
|
diskSeed: diskSeed ?? null,
|
|
663
|
-
manifestName: manifestName ?? null,
|
|
664
|
-
manifestVersion: manifestVersion ?? null,
|
|
665
|
-
manifestHash: manifestHash ?? null,
|
|
666
666
|
forkedFrom: forkedFrom ?? null,
|
|
667
|
+
targetVersion: targetVersion ?? null,
|
|
668
|
+
failedVersion: failedVersion ?? null,
|
|
669
|
+
startCheck: startCheck ?? null,
|
|
667
670
|
...(pod ? podColumns(pod) : {}),
|
|
668
671
|
});
|
|
669
672
|
return "created";
|
|
@@ -672,88 +675,88 @@ class PostgresTx {
|
|
|
672
675
|
this.check();
|
|
673
676
|
const columns = Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== undefined));
|
|
674
677
|
await this.db
|
|
675
|
-
.update(
|
|
678
|
+
.update(agents)
|
|
676
679
|
.set({ ...columns, updatedAt })
|
|
677
|
-
.where(eq(
|
|
680
|
+
.where(eq(agents.id, id));
|
|
678
681
|
}
|
|
679
682
|
async updateEnvironmentPod(id, patch, updatedAt) {
|
|
680
683
|
this.check();
|
|
681
684
|
await this.db
|
|
682
|
-
.update(
|
|
685
|
+
.update(agents)
|
|
683
686
|
.set({ ...podColumns(patch), updatedAt })
|
|
684
|
-
.where(eq(
|
|
687
|
+
.where(eq(agents.id, id));
|
|
685
688
|
}
|
|
686
689
|
async deleteEnvironment(id) {
|
|
687
690
|
this.check();
|
|
688
691
|
// Its vault and credentials go with it (ON DELETE CASCADE).
|
|
689
|
-
await this.db.delete(
|
|
692
|
+
await this.db.delete(agents).where(eq(agents.id, id));
|
|
690
693
|
}
|
|
691
694
|
async listEnvironments(filter = {}) {
|
|
692
695
|
this.check();
|
|
693
696
|
const labels = filter.labels;
|
|
694
697
|
const rows = await this.db
|
|
695
698
|
.select()
|
|
696
|
-
.from(
|
|
699
|
+
.from(agents)
|
|
697
700
|
.where(labels === undefined || Object.keys(labels).length === 0
|
|
698
701
|
? undefined
|
|
699
|
-
: sql `nylorun.doc(${
|
|
700
|
-
.orderBy(
|
|
702
|
+
: sql `nylorun.doc(${agents.labels}) @> ${toJson(labels)}::jsonb`)
|
|
703
|
+
.orderBy(agents.id);
|
|
701
704
|
return rows.map(environmentOf);
|
|
702
705
|
}
|
|
703
|
-
// ---
|
|
704
|
-
async
|
|
706
|
+
// --- Agent manifests (protocol 16) ---------------------------------------------
|
|
707
|
+
async lockAgentManifest(name) {
|
|
705
708
|
this.check();
|
|
706
|
-
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext(${`nylorun.
|
|
709
|
+
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext(${`nylorun.agent_manifests:${name}`}))`);
|
|
707
710
|
}
|
|
708
|
-
async
|
|
711
|
+
async agentManifest(name, version) {
|
|
709
712
|
this.check();
|
|
710
713
|
const [row] = await this.db
|
|
711
714
|
.select()
|
|
712
|
-
.from(
|
|
715
|
+
.from(agentManifests)
|
|
713
716
|
.where(version === undefined
|
|
714
|
-
? eq(
|
|
715
|
-
: and(eq(
|
|
716
|
-
.orderBy(desc(
|
|
717
|
+
? eq(agentManifests.name, name)
|
|
718
|
+
: and(eq(agentManifests.name, name), eq(agentManifests.version, version)))
|
|
719
|
+
.orderBy(desc(agentManifests.version))
|
|
717
720
|
.limit(1);
|
|
718
|
-
return row &&
|
|
721
|
+
return row && agentManifestOf(row);
|
|
719
722
|
}
|
|
720
|
-
async
|
|
723
|
+
async insertAgentManifest(row) {
|
|
721
724
|
this.check();
|
|
722
|
-
await this.db.insert(
|
|
725
|
+
await this.db.insert(agentManifests).values(row);
|
|
723
726
|
}
|
|
724
|
-
async
|
|
727
|
+
async listAgentManifests() {
|
|
725
728
|
this.check();
|
|
726
729
|
const rows = await this.db
|
|
727
|
-
.selectDistinctOn([
|
|
728
|
-
.from(
|
|
729
|
-
.orderBy(
|
|
730
|
-
return rows.map(
|
|
730
|
+
.selectDistinctOn([agentManifests.name])
|
|
731
|
+
.from(agentManifests)
|
|
732
|
+
.orderBy(agentManifests.name, desc(agentManifests.version));
|
|
733
|
+
return rows.map(agentManifestOf);
|
|
731
734
|
}
|
|
732
|
-
async
|
|
735
|
+
async agentManifestVersions(name) {
|
|
733
736
|
this.check();
|
|
734
737
|
const rows = await this.db
|
|
735
738
|
.select()
|
|
736
|
-
.from(
|
|
737
|
-
.where(eq(
|
|
738
|
-
.orderBy(desc(
|
|
739
|
-
return rows.map(
|
|
739
|
+
.from(agentManifests)
|
|
740
|
+
.where(eq(agentManifests.name, name))
|
|
741
|
+
.orderBy(desc(agentManifests.version));
|
|
742
|
+
return rows.map(agentManifestOf);
|
|
740
743
|
}
|
|
741
|
-
async
|
|
744
|
+
async deleteAgentManifest(name) {
|
|
742
745
|
this.check();
|
|
743
746
|
const deleted = await this.db
|
|
744
|
-
.delete(
|
|
745
|
-
.where(eq(
|
|
746
|
-
.returning({ version:
|
|
747
|
+
.delete(agentManifests)
|
|
748
|
+
.where(eq(agentManifests.name, name))
|
|
749
|
+
.returning({ version: agentManifests.version });
|
|
747
750
|
return deleted.length;
|
|
748
751
|
}
|
|
749
|
-
async
|
|
752
|
+
async agentsOfManifest(name) {
|
|
750
753
|
this.check();
|
|
751
754
|
const rows = await this.db
|
|
752
|
-
.select({ version:
|
|
753
|
-
.from(
|
|
754
|
-
.where(eq(
|
|
755
|
-
.groupBy(
|
|
756
|
-
return new Map(rows.
|
|
755
|
+
.select({ version: agents.manifestVersion, n: count() })
|
|
756
|
+
.from(agents)
|
|
757
|
+
.where(eq(agents.manifestName, name))
|
|
758
|
+
.groupBy(agents.manifestVersion);
|
|
759
|
+
return new Map(rows.map((row) => [row.version, row.n]));
|
|
757
760
|
}
|
|
758
761
|
async sessionsOnEnvironment(environmentId) {
|
|
759
762
|
this.check();
|
|
@@ -762,24 +765,30 @@ class PostgresTx {
|
|
|
762
765
|
.orderBy(sessions.id);
|
|
763
766
|
return rows.map((row) => storedSession(row));
|
|
764
767
|
}
|
|
765
|
-
async
|
|
768
|
+
async agentEvent(agentId, type, payload) {
|
|
766
769
|
this.check();
|
|
767
|
-
return
|
|
770
|
+
return appendAgentEvent(postgresAgentRecordWriter(this.db), {
|
|
768
771
|
tenantId: this.tenantId,
|
|
769
|
-
|
|
772
|
+
agentId,
|
|
770
773
|
time: this.now(),
|
|
771
774
|
type,
|
|
772
775
|
payload,
|
|
776
|
+
maxEntryBytes: await this.maxEntryBytes(),
|
|
773
777
|
});
|
|
774
778
|
}
|
|
775
|
-
|
|
779
|
+
/** The Tenant's Runtime limit `recordEntryBytes`, read in this transaction for each write. */
|
|
780
|
+
async maxEntryBytes() {
|
|
781
|
+
return (await readRuntimeLimits(this)).recordEntryBytes;
|
|
782
|
+
}
|
|
783
|
+
async agentEvents(agentId, options = {}) {
|
|
776
784
|
this.check();
|
|
777
|
-
const
|
|
778
|
-
.select({ body:
|
|
779
|
-
.from(
|
|
780
|
-
.where(and(eq(
|
|
781
|
-
.orderBy(
|
|
782
|
-
|
|
785
|
+
const query = this.db
|
|
786
|
+
.select({ body: agentEvents.body })
|
|
787
|
+
.from(agentEvents)
|
|
788
|
+
.where(and(eq(agentEvents.agentId, agentId), options.fromSeq === undefined ? undefined : gte(agentEvents.seq, options.fromSeq), options.types === undefined ? undefined : inArray(agentEvents.type, [...options.types]), options.since === undefined ? undefined : gte(agentEvents.committedAt, options.since), options.until === undefined ? undefined : lt(agentEvents.committedAt, options.until)))
|
|
789
|
+
.orderBy(agentEvents.seq)
|
|
790
|
+
.$dynamic();
|
|
791
|
+
const rows = await (options.limit === undefined ? query : query.limit(options.limit));
|
|
783
792
|
return rows.map((row) => row.body);
|
|
784
793
|
}
|
|
785
794
|
async effectBodies(where) {
|
|
@@ -827,13 +836,13 @@ class PostgresTx {
|
|
|
827
836
|
WHERE ${sessions.status} IN ('running', 'runnable'))::int AS running,
|
|
828
837
|
(SELECT count(*) FROM ${effects} WHERE ${effects.status} = 'uncertain')::int AS uncertain,
|
|
829
838
|
(SELECT count(*) FROM ${sandboxes})::int AS sandboxes,
|
|
830
|
-
(SELECT count(*) FROM ${
|
|
839
|
+
(SELECT count(*) FROM ${agentManifests})::int AS manifests`);
|
|
831
840
|
return {
|
|
832
841
|
sessions: row.sessions,
|
|
833
842
|
runningSessions: row.running,
|
|
834
843
|
uncertainEffects: row.uncertain,
|
|
835
844
|
sandboxes: row.sandboxes,
|
|
836
|
-
|
|
845
|
+
agentManifests: row.manifests,
|
|
837
846
|
};
|
|
838
847
|
}
|
|
839
848
|
// --- control bus (D21) ---------------------------------------------------
|
|
@@ -1080,7 +1089,7 @@ class PostgresTx {
|
|
|
1080
1089
|
costUsd: sql `coalesce(sum(${modelUsage.costUsd}), 0)::double precision`.mapWith(Number),
|
|
1081
1090
|
})
|
|
1082
1091
|
.from(modelUsage)
|
|
1083
|
-
.where(and(query.scope === "
|
|
1092
|
+
.where(and(query.scope === "manifest" ? eq(modelUsage.manifestName, query.id ?? "") : undefined, query.scope === "turn" ? eq(modelUsage.turnId, query.id ?? "") : undefined, query.since !== undefined ? gte(modelUsage.createdAt, query.since) : undefined));
|
|
1084
1093
|
return row;
|
|
1085
1094
|
}
|
|
1086
1095
|
async listModelBudgets() {
|
|
@@ -1096,6 +1105,249 @@ class PostgresTx {
|
|
|
1096
1105
|
if (rows.length > 0)
|
|
1097
1106
|
await this.db.insert(modelBudgets).values([...rows]);
|
|
1098
1107
|
}
|
|
1108
|
+
// --- session queues (protocol 17) -------------------------------------------
|
|
1109
|
+
async enqueueMessage(row) {
|
|
1110
|
+
this.check();
|
|
1111
|
+
const [last] = await this.db
|
|
1112
|
+
.select({ seq: sql `max(${sessionQueue.seq})` })
|
|
1113
|
+
.from(sessionQueue)
|
|
1114
|
+
.where(eq(sessionQueue.sessionId, row.sessionId));
|
|
1115
|
+
const seq = Number(last?.seq ?? 0) + 1;
|
|
1116
|
+
await this.db.insert(sessionQueue).values({ ...row, seq });
|
|
1117
|
+
return seq;
|
|
1118
|
+
}
|
|
1119
|
+
async queuedMessages(sessionId) {
|
|
1120
|
+
this.check();
|
|
1121
|
+
return this.db
|
|
1122
|
+
.select()
|
|
1123
|
+
.from(sessionQueue)
|
|
1124
|
+
.where(eq(sessionQueue.sessionId, sessionId))
|
|
1125
|
+
.orderBy(sessionQueue.seq);
|
|
1126
|
+
}
|
|
1127
|
+
async countQueuedMessages(sessionId) {
|
|
1128
|
+
this.check();
|
|
1129
|
+
const [row] = await this.db
|
|
1130
|
+
.select({ n: count() })
|
|
1131
|
+
.from(sessionQueue)
|
|
1132
|
+
.where(eq(sessionQueue.sessionId, sessionId));
|
|
1133
|
+
return Number(row?.n ?? 0);
|
|
1134
|
+
}
|
|
1135
|
+
async deleteQueuedMessages(ids) {
|
|
1136
|
+
this.check();
|
|
1137
|
+
if (ids.length > 0)
|
|
1138
|
+
await this.db.delete(sessionQueue).where(inArray(sessionQueue.id, [...ids]));
|
|
1139
|
+
}
|
|
1140
|
+
// --- triggers (track T4) ----------------------------------------------------
|
|
1141
|
+
async agentTriggers(agentId) {
|
|
1142
|
+
this.check();
|
|
1143
|
+
return this.db
|
|
1144
|
+
.select()
|
|
1145
|
+
.from(agentTriggers)
|
|
1146
|
+
.where(eq(agentTriggers.agentId, agentId))
|
|
1147
|
+
.orderBy(agentTriggers.triggerId);
|
|
1148
|
+
}
|
|
1149
|
+
async agentTrigger(agentId, triggerId, options = {}) {
|
|
1150
|
+
this.check();
|
|
1151
|
+
const query = this.db
|
|
1152
|
+
.select()
|
|
1153
|
+
.from(agentTriggers)
|
|
1154
|
+
.where(and(eq(agentTriggers.agentId, agentId), eq(agentTriggers.triggerId, triggerId)));
|
|
1155
|
+
const [row] = options.lock ? await query.for("update") : await query;
|
|
1156
|
+
return row;
|
|
1157
|
+
}
|
|
1158
|
+
async putAgentTrigger(row) {
|
|
1159
|
+
this.check();
|
|
1160
|
+
const { agentId: _a, triggerId: _t, createdAt: _c, ...set } = row;
|
|
1161
|
+
await this.db
|
|
1162
|
+
.insert(agentTriggers)
|
|
1163
|
+
.values(row)
|
|
1164
|
+
.onConflictDoUpdate({ target: [agentTriggers.agentId, agentTriggers.triggerId], set });
|
|
1165
|
+
}
|
|
1166
|
+
async deleteAgentTrigger(agentId, triggerId) {
|
|
1167
|
+
this.check();
|
|
1168
|
+
await this.db
|
|
1169
|
+
.delete(agentTriggers)
|
|
1170
|
+
.where(and(eq(agentTriggers.agentId, agentId), eq(agentTriggers.triggerId, triggerId)));
|
|
1171
|
+
}
|
|
1172
|
+
async deleteAgentTriggers(agentId) {
|
|
1173
|
+
this.check();
|
|
1174
|
+
await this.db.delete(agentTriggers).where(eq(agentTriggers.agentId, agentId));
|
|
1175
|
+
await this.db.delete(triggerRuns).where(eq(triggerRuns.agentId, agentId));
|
|
1176
|
+
}
|
|
1177
|
+
async activeTriggers(options) {
|
|
1178
|
+
this.check();
|
|
1179
|
+
const conditions = [eq(agentTriggers.status, "active"), isNotNull(agentTriggers.nextFireAt)];
|
|
1180
|
+
if (options.dueBefore !== undefined)
|
|
1181
|
+
conditions.push(lte(agentTriggers.nextFireAt, options.dueBefore));
|
|
1182
|
+
if (options.changedSince !== undefined)
|
|
1183
|
+
conditions.push(gte(agentTriggers.updatedAt, options.changedSince));
|
|
1184
|
+
if (options.after)
|
|
1185
|
+
conditions.push(or(gt(agentTriggers.agentId, options.after.agentId), and(eq(agentTriggers.agentId, options.after.agentId), gt(agentTriggers.triggerId, options.after.triggerId))));
|
|
1186
|
+
return this.db
|
|
1187
|
+
.select()
|
|
1188
|
+
.from(agentTriggers)
|
|
1189
|
+
.where(and(...conditions))
|
|
1190
|
+
.orderBy(agentTriggers.agentId, agentTriggers.triggerId)
|
|
1191
|
+
.limit(options.limit);
|
|
1192
|
+
}
|
|
1193
|
+
async agentTriggerByEndpoint(endpointId) {
|
|
1194
|
+
this.check();
|
|
1195
|
+
const [row] = await this.db.select().from(agentTriggers).where(eq(agentTriggers.endpointId, endpointId));
|
|
1196
|
+
return row;
|
|
1197
|
+
}
|
|
1198
|
+
async nextWakeAt(agentId) {
|
|
1199
|
+
this.check();
|
|
1200
|
+
const [row] = await this.db
|
|
1201
|
+
.select({ at: sql `min(${agentTriggers.nextFireAt})` })
|
|
1202
|
+
.from(agentTriggers)
|
|
1203
|
+
.where(and(eq(agentTriggers.agentId, agentId), eq(agentTriggers.status, "active")));
|
|
1204
|
+
return row?.at ?? null;
|
|
1205
|
+
}
|
|
1206
|
+
async insertTriggerRun(row) {
|
|
1207
|
+
this.check();
|
|
1208
|
+
const inserted = await this.db
|
|
1209
|
+
.insert(triggerRuns)
|
|
1210
|
+
.values(row)
|
|
1211
|
+
.onConflictDoNothing()
|
|
1212
|
+
.returning({ id: triggerRuns.id });
|
|
1213
|
+
return inserted.length === 1;
|
|
1214
|
+
}
|
|
1215
|
+
async triggerRunByKey(agentId, runKey) {
|
|
1216
|
+
this.check();
|
|
1217
|
+
const [row] = await this.db
|
|
1218
|
+
.select()
|
|
1219
|
+
.from(triggerRuns)
|
|
1220
|
+
.where(and(eq(triggerRuns.agentId, agentId), eq(triggerRuns.runKey, runKey)));
|
|
1221
|
+
return row;
|
|
1222
|
+
}
|
|
1223
|
+
async updateTriggerRun(id, patch) {
|
|
1224
|
+
this.check();
|
|
1225
|
+
await this.db.update(triggerRuns).set(patch).where(eq(triggerRuns.id, id));
|
|
1226
|
+
}
|
|
1227
|
+
async countTriggerRuns(agentId, since, statuses) {
|
|
1228
|
+
this.check();
|
|
1229
|
+
const [row] = await this.db
|
|
1230
|
+
.select({ n: count() })
|
|
1231
|
+
.from(triggerRuns)
|
|
1232
|
+
.where(and(eq(triggerRuns.agentId, agentId), gte(triggerRuns.firedAt, since), inArray(triggerRuns.status, [...statuses])));
|
|
1233
|
+
return Number(row?.n ?? 0);
|
|
1234
|
+
}
|
|
1235
|
+
async listTriggerRuns(agentId, options) {
|
|
1236
|
+
this.check();
|
|
1237
|
+
const conditions = [eq(triggerRuns.agentId, agentId)];
|
|
1238
|
+
if (options.triggerId !== undefined)
|
|
1239
|
+
conditions.push(eq(triggerRuns.triggerId, options.triggerId));
|
|
1240
|
+
if (options.before !== undefined)
|
|
1241
|
+
conditions.push(lt(triggerRuns.id, options.before));
|
|
1242
|
+
return this.db
|
|
1243
|
+
.select()
|
|
1244
|
+
.from(triggerRuns)
|
|
1245
|
+
.where(and(...conditions))
|
|
1246
|
+
.orderBy(desc(triggerRuns.id))
|
|
1247
|
+
.limit(options.limit);
|
|
1248
|
+
}
|
|
1249
|
+
async pruneTriggerRuns(before) {
|
|
1250
|
+
this.check();
|
|
1251
|
+
const deleted = await this.db
|
|
1252
|
+
.delete(triggerRuns)
|
|
1253
|
+
.where(lt(triggerRuns.firedAt, before))
|
|
1254
|
+
.returning({ id: triggerRuns.id });
|
|
1255
|
+
return deleted.length;
|
|
1256
|
+
}
|
|
1257
|
+
// --- memory (track T5) ------------------------------------------------------
|
|
1258
|
+
async memory(agentId, path, options = {}) {
|
|
1259
|
+
this.check();
|
|
1260
|
+
// The path's own lock, held whether or not a row has it, so two writes creating it queue.
|
|
1261
|
+
if (options.lock)
|
|
1262
|
+
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext(${`nylorun.memories:${agentId}:${path}`}))`);
|
|
1263
|
+
const query = this.db
|
|
1264
|
+
.select()
|
|
1265
|
+
.from(memories)
|
|
1266
|
+
.where(and(eq(memories.agentId, agentId), eq(memories.path, path)));
|
|
1267
|
+
const [row] = options.lock ? await query.for("update") : await query;
|
|
1268
|
+
return row;
|
|
1269
|
+
}
|
|
1270
|
+
async memories(agentId, options) {
|
|
1271
|
+
this.check();
|
|
1272
|
+
const conditions = [eq(memories.agentId, agentId)];
|
|
1273
|
+
// `starts_with`, not LIKE: a path may hold `%` or `_`.
|
|
1274
|
+
if (options.folder !== undefined)
|
|
1275
|
+
conditions.push(sql `starts_with(${memories.path}, ${`${options.folder}/`})`);
|
|
1276
|
+
if (options.after !== undefined)
|
|
1277
|
+
conditions.push(gt(memories.path, options.after));
|
|
1278
|
+
const ordered = this.db
|
|
1279
|
+
.select()
|
|
1280
|
+
.from(memories)
|
|
1281
|
+
.where(and(...conditions))
|
|
1282
|
+
.orderBy(memories.path);
|
|
1283
|
+
const limited = options.limit === undefined ? ordered : ordered.limit(options.limit);
|
|
1284
|
+
return options.lock ? limited.for("update") : limited;
|
|
1285
|
+
}
|
|
1286
|
+
async countMemories(agentId) {
|
|
1287
|
+
this.check();
|
|
1288
|
+
const [row] = await this.db.select({ n: count() }).from(memories).where(eq(memories.agentId, agentId));
|
|
1289
|
+
return Number(row?.n ?? 0);
|
|
1290
|
+
}
|
|
1291
|
+
async recentMemories(agentId, limit) {
|
|
1292
|
+
this.check();
|
|
1293
|
+
return this.db
|
|
1294
|
+
.select({ path: memories.path, description: memories.description, bytes: memories.bytes })
|
|
1295
|
+
.from(memories)
|
|
1296
|
+
.where(eq(memories.agentId, agentId))
|
|
1297
|
+
.orderBy(desc(memories.updatedAt), memories.path)
|
|
1298
|
+
.limit(limit);
|
|
1299
|
+
}
|
|
1300
|
+
async putMemory(row) {
|
|
1301
|
+
this.check();
|
|
1302
|
+
const { agentId: _a, path: _p, ...set } = row;
|
|
1303
|
+
await this.db
|
|
1304
|
+
.insert(memories)
|
|
1305
|
+
.values(row)
|
|
1306
|
+
.onConflictDoUpdate({ target: [memories.agentId, memories.path], set });
|
|
1307
|
+
}
|
|
1308
|
+
async deleteMemory(agentId, path) {
|
|
1309
|
+
this.check();
|
|
1310
|
+
await this.db.delete(memories).where(and(eq(memories.agentId, agentId), eq(memories.path, path)));
|
|
1311
|
+
}
|
|
1312
|
+
async insertMemoryVersion(row) {
|
|
1313
|
+
this.check();
|
|
1314
|
+
await this.db.insert(memoryVersions).values(row);
|
|
1315
|
+
}
|
|
1316
|
+
async memoryVersions(agentId, options) {
|
|
1317
|
+
this.check();
|
|
1318
|
+
const conditions = [eq(memoryVersions.agentId, agentId)];
|
|
1319
|
+
if (options.path !== undefined)
|
|
1320
|
+
conditions.push(eq(memoryVersions.path, options.path));
|
|
1321
|
+
if (options.before !== undefined)
|
|
1322
|
+
conditions.push(lt(memoryVersions.id, options.before));
|
|
1323
|
+
return this.db
|
|
1324
|
+
.select()
|
|
1325
|
+
.from(memoryVersions)
|
|
1326
|
+
.where(and(...conditions))
|
|
1327
|
+
.orderBy(desc(memoryVersions.id))
|
|
1328
|
+
.limit(options.limit);
|
|
1329
|
+
}
|
|
1330
|
+
async memoryVersion(agentId, id) {
|
|
1331
|
+
this.check();
|
|
1332
|
+
const [row] = await this.db
|
|
1333
|
+
.select()
|
|
1334
|
+
.from(memoryVersions)
|
|
1335
|
+
.where(and(eq(memoryVersions.agentId, agentId), eq(memoryVersions.id, id)));
|
|
1336
|
+
return row;
|
|
1337
|
+
}
|
|
1338
|
+
async copyMemories(from, to, now) {
|
|
1339
|
+
this.check();
|
|
1340
|
+
const copied = await this.db.execute(sql `
|
|
1341
|
+
INSERT INTO ${memories} (agent_id, path, content, content_sha256, bytes, description, version, updated_at)
|
|
1342
|
+
SELECT ${to}, path, content, content_sha256, bytes, description, 1, ${now}
|
|
1343
|
+
FROM ${memories} WHERE agent_id = ${from}`);
|
|
1344
|
+
return Number(copied.count ?? 0);
|
|
1345
|
+
}
|
|
1346
|
+
async deleteAgentMemories(agentId) {
|
|
1347
|
+
this.check();
|
|
1348
|
+
await this.db.delete(memories).where(eq(memories.agentId, agentId));
|
|
1349
|
+
await this.db.delete(memoryVersions).where(eq(memoryVersions.agentId, agentId));
|
|
1350
|
+
}
|
|
1099
1351
|
// --- tool crossings --------------------------------------------------------
|
|
1100
1352
|
async toolCrossing(key) {
|
|
1101
1353
|
this.check();
|
|
@@ -1181,6 +1433,11 @@ class PostgresTx {
|
|
|
1181
1433
|
.where(and(eq(artifactVersions.artifactId, artifactId), eq(artifactVersions.version, version)));
|
|
1182
1434
|
return row;
|
|
1183
1435
|
}
|
|
1436
|
+
async artifactVersionByWriteKey(writeKey) {
|
|
1437
|
+
this.check();
|
|
1438
|
+
const [row] = await this.db.select().from(artifactVersions).where(eq(artifactVersions.writeKey, writeKey));
|
|
1439
|
+
return row;
|
|
1440
|
+
}
|
|
1184
1441
|
async artifactVersions(artifactId) {
|
|
1185
1442
|
this.check();
|
|
1186
1443
|
return this.db
|
|
@@ -1220,21 +1477,32 @@ class PostgresTx {
|
|
|
1220
1477
|
this.check();
|
|
1221
1478
|
await this.db.execute(sql `SELECT pg_advisory_xact_lock(hashtext('nylorun.artifacts'))`);
|
|
1222
1479
|
}
|
|
1223
|
-
|
|
1480
|
+
/** The artifacts of Environment `environmentId`: its disk versions, and its sessions'. */
|
|
1481
|
+
artifactsOfEnvironment(environmentId) {
|
|
1482
|
+
return or(eq(artifacts.environmentId, environmentId), inArray(artifacts.sessionId, this.db.select({ id: sessions.id }).from(sessions).where(eq(sessions.environmentId, environmentId))));
|
|
1483
|
+
}
|
|
1484
|
+
async artifactBytes(scope) {
|
|
1224
1485
|
this.check();
|
|
1486
|
+
const within = scope === undefined ? undefined : this.artifactsOfEnvironment(scope.environmentId);
|
|
1225
1487
|
const [files] = await this.db
|
|
1226
1488
|
.select({
|
|
1227
1489
|
bytes: sql `coalesce(sum(${artifactVersions.size}), 0)::bigint`.mapWith(Number),
|
|
1228
1490
|
})
|
|
1229
1491
|
.from(artifactVersions)
|
|
1230
1492
|
.innerJoin(artifacts, eq(artifacts.id, artifactVersions.artifactId))
|
|
1231
|
-
.where(eq(artifacts.kind, "file"));
|
|
1493
|
+
.where(within === undefined ? eq(artifacts.kind, "file") : and(eq(artifacts.kind, "file"), within));
|
|
1232
1494
|
// A folder's files are stored once per distinct hash, however many versions name them.
|
|
1233
|
-
const distinct =
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1495
|
+
const distinct = (within === undefined
|
|
1496
|
+
? this.db
|
|
1497
|
+
.select({ size: sql `max(${artifactContent.size})`.as("size") })
|
|
1498
|
+
.from(artifactContent)
|
|
1499
|
+
.groupBy(artifactContent.sha256)
|
|
1500
|
+
: this.db
|
|
1501
|
+
.select({ size: sql `max(${artifactContent.size})`.as("size") })
|
|
1502
|
+
.from(artifactContent)
|
|
1503
|
+
.innerJoin(artifacts, eq(artifacts.id, artifactContent.artifactId))
|
|
1504
|
+
.where(within)
|
|
1505
|
+
.groupBy(artifactContent.sha256)).as("distinct_content");
|
|
1238
1506
|
const [content] = await this.db
|
|
1239
1507
|
.select({ bytes: sql `coalesce(sum(${distinct.size}), 0)::bigint`.mapWith(Number) })
|
|
1240
1508
|
.from(distinct);
|
|
@@ -1242,22 +1510,26 @@ class PostgresTx {
|
|
|
1242
1510
|
}
|
|
1243
1511
|
async insertArtifactContent(artifactId, version, files) {
|
|
1244
1512
|
this.check();
|
|
1245
|
-
for (let at = 0; at < files.length; at +=
|
|
1513
|
+
for (let at = 0; at < files.length; at += contentBatch())
|
|
1246
1514
|
await this.db
|
|
1247
1515
|
.insert(artifactContent)
|
|
1248
1516
|
.values(files
|
|
1249
|
-
.slice(at, at +
|
|
1517
|
+
.slice(at, at + contentBatch())
|
|
1250
1518
|
.map((file) => ({ artifactId, version, sha256: file.sha256, size: file.size })))
|
|
1251
1519
|
.onConflictDoNothing();
|
|
1252
1520
|
}
|
|
1253
|
-
async referencedArtifactContent(shas) {
|
|
1521
|
+
async referencedArtifactContent(shas, scope) {
|
|
1254
1522
|
this.check();
|
|
1255
1523
|
const found = new Set();
|
|
1256
|
-
for (let at = 0; at < shas.length; at +=
|
|
1257
|
-
const
|
|
1258
|
-
|
|
1259
|
-
.from(artifactContent)
|
|
1260
|
-
|
|
1524
|
+
for (let at = 0; at < shas.length; at += contentBatch()) {
|
|
1525
|
+
const batch = inArray(artifactContent.sha256, shas.slice(at, at + contentBatch()));
|
|
1526
|
+
const rows = scope === undefined
|
|
1527
|
+
? await this.db.selectDistinct({ sha256: artifactContent.sha256 }).from(artifactContent).where(batch)
|
|
1528
|
+
: await this.db
|
|
1529
|
+
.selectDistinct({ sha256: artifactContent.sha256 })
|
|
1530
|
+
.from(artifactContent)
|
|
1531
|
+
.innerJoin(artifacts, eq(artifacts.id, artifactContent.artifactId))
|
|
1532
|
+
.where(and(batch, this.artifactsOfEnvironment(scope.environmentId)));
|
|
1261
1533
|
for (const row of rows)
|
|
1262
1534
|
found.add(row.sha256);
|
|
1263
1535
|
}
|
|
@@ -1302,23 +1574,23 @@ class PostgresTx {
|
|
|
1302
1574
|
}
|
|
1303
1575
|
async heldDefinitionFiles(shas) {
|
|
1304
1576
|
this.check();
|
|
1305
|
-
const found = new
|
|
1306
|
-
for (let at = 0; at < shas.length; at +=
|
|
1577
|
+
const found = new Map();
|
|
1578
|
+
for (let at = 0; at < shas.length; at += contentBatch()) {
|
|
1307
1579
|
const rows = await this.db
|
|
1308
|
-
.select({ sha256: definitionFiles.sha256 })
|
|
1580
|
+
.select({ sha256: definitionFiles.sha256, size: definitionFiles.size })
|
|
1309
1581
|
.from(definitionFiles)
|
|
1310
|
-
.where(inArray(definitionFiles.sha256, shas.slice(at, at +
|
|
1582
|
+
.where(inArray(definitionFiles.sha256, shas.slice(at, at + contentBatch())));
|
|
1311
1583
|
for (const row of rows)
|
|
1312
|
-
found.
|
|
1584
|
+
found.set(row.sha256, row.size);
|
|
1313
1585
|
}
|
|
1314
1586
|
return found;
|
|
1315
1587
|
}
|
|
1316
1588
|
async insertDefinitionFileUses(agentId, manifestHash, shas) {
|
|
1317
1589
|
this.check();
|
|
1318
|
-
for (let at = 0; at < shas.length; at +=
|
|
1590
|
+
for (let at = 0; at < shas.length; at += contentBatch())
|
|
1319
1591
|
await this.db
|
|
1320
1592
|
.insert(definitionFileUses)
|
|
1321
|
-
.values(shas.slice(at, at +
|
|
1593
|
+
.values(shas.slice(at, at + contentBatch()).map((sha256) => ({ agentId, manifestHash, sha256 })))
|
|
1322
1594
|
.onConflictDoNothing();
|
|
1323
1595
|
}
|
|
1324
1596
|
// --- settings ------------------------------------------------------------
|
|
@@ -1344,6 +1616,8 @@ class PostgresTx {
|
|
|
1344
1616
|
if (scope === "sessions" || scope === "all") {
|
|
1345
1617
|
for (const table of SESSION_TABLES)
|
|
1346
1618
|
await db.delete(table);
|
|
1619
|
+
// A session's booked wake (T4) goes with it.
|
|
1620
|
+
await db.delete(agentTriggers).where(eq(agentTriggers.kind, "wake"));
|
|
1347
1621
|
await db.delete(toolCrossings);
|
|
1348
1622
|
// A session's artifacts go with it (their versions by cascade).
|
|
1349
1623
|
await db.delete(artifacts).where(isNotNull(artifacts.sessionId));
|
|
@@ -1356,15 +1630,20 @@ class PostgresTx {
|
|
|
1356
1630
|
basinGeneration: sql `${tenant.basinGeneration} + 1`,
|
|
1357
1631
|
});
|
|
1358
1632
|
}
|
|
1359
|
-
if (scope === "
|
|
1633
|
+
if (scope === "agents" || scope === "all") {
|
|
1360
1634
|
await db.delete(sandboxes);
|
|
1361
1635
|
// Their vaults and credentials go with them (ON DELETE CASCADE).
|
|
1362
|
-
await db.delete(
|
|
1363
|
-
await db.delete(
|
|
1636
|
+
await db.delete(agents);
|
|
1637
|
+
await db.delete(agentEvents);
|
|
1638
|
+
await db.delete(agentTriggers);
|
|
1639
|
+
await db.delete(triggerRuns);
|
|
1640
|
+
// Memories belong to the Agents (D72).
|
|
1641
|
+
await db.delete(memories);
|
|
1642
|
+
await db.delete(memoryVersions);
|
|
1364
1643
|
await db.delete(sandboxSignals);
|
|
1365
1644
|
}
|
|
1366
1645
|
if (scope === "all") {
|
|
1367
|
-
await db.delete(
|
|
1646
|
+
await db.delete(agentManifests);
|
|
1368
1647
|
// The files stay, as their bytes do; only what used them goes.
|
|
1369
1648
|
await db.delete(definitionFileUses);
|
|
1370
1649
|
await db.delete(modelUsage);
|