@nylorun/runtime 0.22.0-beta → 0.24.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 +161 -0
- package/README.md +95 -30
- package/dist/adapters/execution/restate.d.ts +15 -3
- package/dist/adapters/execution/restate.js +78 -84
- 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/adapters/streams/s2.js +1 -13
- package/dist/api/a2a/endpoint.js +5 -1
- package/dist/api/a2a/routes.d.ts +2 -0
- package/dist/api/a2a/routes.js +2 -2
- package/dist/api/a2a/tasks.js +2 -1
- package/dist/api/ag-ui/endpoint.js +4 -2
- package/dist/api/ag-ui/history.js +4 -1
- package/dist/api/ag-ui/routes.d.ts +4 -1
- package/dist/api/ag-ui/routes.js +11 -10
- package/dist/api/ag-ui/translate.js +3 -2
- package/dist/api/components.d.ts +4953 -1204
- package/dist/api/components.js +25 -16
- package/dist/api/gate/keys.js +7 -1
- package/dist/api/gate/routes.d.ts +6 -0
- package/dist/api/gate/routes.js +39 -3
- package/dist/api/http/app.js +4 -4
- 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/environments.d.ts +11 -0
- package/dist/api/http/routes/environments.js +283 -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 +45 -9
- package/dist/api/http/routes/reads.js +54 -5
- package/dist/api/http/routes/sessions.js +11 -6
- package/dist/api/http/routes/tenant.js +32 -10
- package/dist/api/openapi.js +31 -26
- package/dist/artifacts/disk.d.ts +59 -0
- package/dist/artifacts/disk.js +563 -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/service.d.ts +2 -1
- package/dist/artifacts/service.js +6 -1
- package/dist/artifacts/workspace.d.ts +1 -1
- package/dist/artifacts/workspace.js +1 -1
- package/dist/core/flow-host.d.ts +3 -22
- package/dist/core/flow-host.js +11 -37
- 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 +10 -43
- package/dist/execution/types.d.ts +11 -9
- package/dist/execution/types.js +5 -7
- 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 +28 -1
- package/dist/gates/egress.js +115 -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 +6 -2
- package/dist/gates/http-tool.js +3 -5
- 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 +52 -0
- package/dist/gates/mcp-handler.d.ts +4 -0
- package/dist/gates/mcp-handler.js +5 -1
- 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 +134 -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 +10 -68
- package/dist/gates/tool-contract.js +1 -85
- package/dist/gates/tool-gate.d.ts +1 -1
- package/dist/harness/calls.d.ts +12 -5
- package/dist/harness/calls.js +21 -12
- package/dist/harness/executors.js +12 -9
- package/dist/harness/main.js +18 -5
- package/dist/harness/pod.d.ts +34 -0
- package/dist/harness/pod.js +41 -0
- package/dist/harness/service.d.ts +0 -1
- package/dist/harness/service.js +13 -5
- package/dist/harness/setup.d.ts +27 -0
- package/dist/harness/setup.js +150 -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 +174 -44
- package/dist/harness-api/redact.d.ts +3 -0
- package/dist/harness-api/redact.js +45 -0
- package/dist/harness-api/server.d.ts +8 -0
- package/dist/harness-api/server.js +93 -13
- 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 +96 -0
- package/dist/harness-api/tool-journal.js +102 -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 +6 -3
- package/dist/harness-api/workspace.js +27 -11
- package/dist/harness-api/ws-server.d.ts +11 -3
- package/dist/harness-api/ws-server.js +94 -15
- package/dist/host/execution.d.ts +8 -6
- package/dist/host/gates.d.ts +2 -1
- package/dist/host/gates.js +10 -2
- package/dist/host/main.js +64 -21
- package/dist/host/operate.js +67 -5
- package/dist/host/stack-config.d.ts +70 -0
- package/dist/host/stack-config.js +67 -1
- package/dist/infra/execution.d.ts +18 -1
- package/dist/infra/execution.js +28 -4
- package/dist/infra/index.d.ts +1 -1
- package/dist/keys/client.js +4 -1
- package/dist/keys/keys.d.ts +5 -5
- package/dist/keys/keys.js +5 -7
- package/dist/management-openapi.json +999 -2211
- package/dist/mcp/connect.d.ts +25 -20
- package/dist/mcp/connect.js +29 -30
- package/dist/mcp/pool.d.ts +2 -2
- package/dist/mcp/pool.js +1 -1
- package/dist/mcp/preview.d.ts +3 -3
- package/dist/mcp/preview.js +10 -20
- package/dist/mcp/snapshot.d.ts +5 -11
- package/dist/mcp/snapshot.js +6 -7
- package/dist/model/pi-model.js +8 -0
- package/dist/openapi.json +6955 -2526
- 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/retry.d.ts +21 -0
- package/dist/retry.js +34 -0
- 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 -20
- package/dist/sandbox/manager.d.ts +16 -8
- package/dist/sandbox/manager.js +33 -17
- package/dist/sandbox/placement.d.ts +13 -12
- package/dist/sandbox/placement.js +29 -12
- package/dist/sandbox/pods/client.d.ts +6 -1
- package/dist/sandbox/pods/lifecycle.d.ts +28 -27
- package/dist/sandbox/pods/lifecycle.js +14 -26
- package/dist/sandbox/pods/reconcile.js +21 -15
- package/dist/sandbox/pods/spec.d.ts +15 -13
- package/dist/sandbox/pods/spec.js +16 -20
- package/dist/sandbox/records.d.ts +2 -2
- package/dist/sandbox/records.js +3 -3
- package/dist/sandbox/resolve.d.ts +35 -27
- package/dist/sandbox/resolve.js +66 -41
- package/dist/sandbox/session-sandbox.js +1 -1
- package/dist/sandbox/setup.d.ts +61 -0
- package/dist/sandbox/setup.js +123 -0
- package/dist/sandbox/share.d.ts +11 -21
- package/dist/sandbox/share.js +12 -41
- 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/control.js +8 -1
- package/dist/store/postgres/drizzle/0018_wake_outbox_retries.sql +3 -0
- package/dist/store/postgres/drizzle/0019_sandbox_signal_outbox.sql +18 -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/meta/_journal.json +42 -0
- package/dist/store/postgres/reads.js +117 -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 +1213 -779
- package/dist/store/postgres/schema.js +136 -76
- package/dist/store/postgres/store.js +283 -117
- package/dist/store/types.d.ts +206 -88
- package/dist/streams/relay/core.js +1 -13
- package/dist/tenant/advance.d.ts +7 -6
- package/dist/tenant/advance.js +121 -49
- package/dist/tenant/artifact-tool.js +3 -4
- package/dist/tenant/commands.d.ts +15 -2
- package/dist/tenant/commands.js +94 -14
- package/dist/tenant/context.d.ts +67 -33
- package/dist/tenant/context.js +4 -15
- package/dist/tenant/control.d.ts +8 -1
- package/dist/tenant/control.js +2 -0
- package/dist/tenant/effects.d.ts +1 -1
- package/dist/tenant/effects.js +37 -20
- package/dist/tenant/environments.d.ts +167 -0
- package/dist/tenant/environments.js +823 -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/principals.js +1 -1
- package/dist/tenant/reset.js +3 -3
- package/dist/tenant/runtime.d.ts +6 -1
- package/dist/tenant/runtime.js +30 -4
- package/dist/tenant/scheduler.d.ts +7 -0
- package/dist/tenant/scheduler.js +38 -7
- package/dist/tenant/session-streams.d.ts +0 -1
- package/dist/tenant/session-streams.js +1 -13
- package/dist/tenant/session.d.ts +3 -3
- package/dist/tenant/session.js +0 -14
- package/dist/tenant/sessions.d.ts +13 -13
- package/dist/tenant/sessions.js +61 -138
- package/dist/tenant/signing-keys.d.ts +5 -1
- package/dist/tenant/status.js +3 -3
- package/dist/tenant/streams.js +14 -29
- package/dist/tenant/sweep.d.ts +39 -12
- package/dist/tenant/sweep.js +168 -63
- package/dist/tenant/transcript.d.ts +210 -20
- package/dist/tenant/transcript.js +62 -11
- 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 +42 -0
- package/dist/traces/ids.js +85 -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 +317 -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 +64 -0
- package/dist/vault/error.d.ts +11 -1
- package/dist/vault/error.js +5 -1
- package/dist/vault/service.d.ts +47 -48
- package/dist/vault/service.js +321 -382
- 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 +14 -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/tenant/sandboxes.d.ts +0 -122
- package/dist/tenant/sandboxes.js +0 -562
|
@@ -69,14 +69,14 @@ export const sessions = nylorun.table("sessions", {
|
|
|
69
69
|
ownerExpiresAt: timestamp({ withTimezone: true, mode: "date" }),
|
|
70
70
|
/** The session owner (`ownerUserId`), not the lease column `owner`. */
|
|
71
71
|
ownerUserId: field("->>'ownerUserId'"),
|
|
72
|
-
/** The
|
|
73
|
-
|
|
72
|
+
/** The Environment the session names (`environment`, protocol 11). */
|
|
73
|
+
environmentId: field("->>'environmentId'"),
|
|
74
74
|
}, (t) => [
|
|
75
75
|
index("sessions_created").on(t.createdAt.desc().nullsLast(), t.id.desc().nullsFirst()),
|
|
76
76
|
index("sessions_status").on(t.status, t.ownerExpiresAt),
|
|
77
77
|
index("sessions_agent").on(t.agentId),
|
|
78
78
|
index("sessions_owner_user").on(t.ownerUserId),
|
|
79
|
-
index("
|
|
79
|
+
index("sessions_environment").on(t.environmentId),
|
|
80
80
|
]);
|
|
81
81
|
export const commands = documents("commands");
|
|
82
82
|
export const effects = nylorun.table("effects", {
|
|
@@ -107,22 +107,92 @@ export const principals = nylorun.table("principals", {
|
|
|
107
107
|
idempotencyKey: text(),
|
|
108
108
|
createdAt: text().notNull(),
|
|
109
109
|
});
|
|
110
|
+
/**
|
|
111
|
+
* An Environment (D55, protocol 11): its id, kind, labels, the recipe the app asked for and the
|
|
112
|
+
* recipe its compute runs (`applied`, copied from `recipe` when a stopped pod is asked to run),
|
|
113
|
+
* the owner guard, and when it was last used. Kind `pod` adds the pod's lifecycle columns.
|
|
114
|
+
* Sessions name it by id (the session body's `environmentId`). Not the `sandboxes` document
|
|
115
|
+
* table, which holds the virtual backend's compute records, keyed by workspace key.
|
|
116
|
+
*/
|
|
117
|
+
export const environments = nylorun.table("environments", {
|
|
118
|
+
id: textC().primaryKey(),
|
|
119
|
+
kind: text({ enum: ["virtual", "pod", "none"] }).notNull(),
|
|
120
|
+
/** `{ key: value }`, filtered through `nylorun.doc(labels)`. */
|
|
121
|
+
labels: jsonText().notNull(),
|
|
122
|
+
/** What the app asked for (`EnvironmentRecipe`), resolved against the Tenant's limits. */
|
|
123
|
+
recipe: jsonText().notNull(),
|
|
124
|
+
/** The recipe the current pod or workspace runs. */
|
|
125
|
+
applied: jsonText().notNull(),
|
|
126
|
+
version: integer().notNull().default(1),
|
|
127
|
+
appliedVersion: integer().notNull().default(1),
|
|
128
|
+
/** The owner guard: only this owner's sessions may name the Environment. */
|
|
129
|
+
ownerUserId: text(),
|
|
130
|
+
/** A turn's end, a recipe change, a secret write, a stop or a reset (`lifecycle.deleteAfter`). */
|
|
131
|
+
lastUsedAt: timestamp({ withTimezone: true, mode: "string" }).notNull().defaultNow(),
|
|
132
|
+
createdAt: textC().notNull(),
|
|
133
|
+
updatedAt: textC().notNull(),
|
|
134
|
+
// Kind `pod` (F7.2, D34): null otherwise. `tenant/environments.ts` and the `Sandbox`
|
|
135
|
+
// object's reconcile (`sandbox/pods/reconcile.ts`) are the only writers.
|
|
136
|
+
/** The agent-sandbox Sandbox's name, `sbx-<16 base32>-g<volume_gen>` (`podName`). */
|
|
137
|
+
k8sName: textC(),
|
|
138
|
+
/** Bumped by every reset: a new Sandbox on a new volume. */
|
|
139
|
+
volumeGen: integer().notNull().default(0),
|
|
140
|
+
/** `running`, `suspended` or `deleted`. */
|
|
141
|
+
desired: text({ enum: ["running", "suspended", "deleted"] }),
|
|
142
|
+
/** `creating`, `running`, `suspended`, `lost`, `failed` or `deleting`. */
|
|
143
|
+
observed: text({ enum: ["creating", "running", "suspended", "lost", "failed", "deleting"] }),
|
|
144
|
+
/** The UID of the pod that last joined. */
|
|
145
|
+
podUid: text(),
|
|
146
|
+
/**
|
|
147
|
+
* Bumped by every join (`host.join`), relaunch, loss and reset: host and egress tokens carry
|
|
148
|
+
* it (`epc`), and one of an older epoch is refused (egress-gate reads it too).
|
|
149
|
+
*/
|
|
150
|
+
hostEpoch: integer().notNull().default(0),
|
|
151
|
+
/** sha256 (hex) of the incarnation's join token; the token itself is never stored. */
|
|
152
|
+
joinTokenHash: text(),
|
|
153
|
+
/** Bumped by every change the Runtime asks of the pod: the sandboxes service's `opId`. */
|
|
154
|
+
rev: integer().notNull().default(0),
|
|
155
|
+
/** When a turn last ended on it, for the idle timer. */
|
|
156
|
+
lastActiveAt: timestamp({ withTimezone: true }),
|
|
157
|
+
/** When the current incarnation was asked to run, for the ready deadline. */
|
|
158
|
+
startedAt: timestamp({ withTimezone: true }),
|
|
159
|
+
/** Why it failed or was lost. */
|
|
160
|
+
reason: text(),
|
|
161
|
+
/** An earlier incarnation's Sandbox still to delete (after a reset or a loss). */
|
|
162
|
+
retiring: textC(),
|
|
163
|
+
/**
|
|
164
|
+
* The id the engine keeps on the volume (`/harness/volume-id`), recorded at the first join:
|
|
165
|
+
* a join with another one means the volume was replaced (its files are gone), so `lost`.
|
|
166
|
+
*/
|
|
167
|
+
volumeId: text(),
|
|
168
|
+
/**
|
|
169
|
+
* The disk lease (R2d step 3): `{ kind, version?, startedAt, until }` while a snapshot, a
|
|
170
|
+
* restore or a seed copies the disk; turns are refused until it ends or `until` passes.
|
|
171
|
+
*/
|
|
172
|
+
diskOp: jsonText(),
|
|
173
|
+
/** The disk version the next volume starts from: `{ artifactId, version }` (R2d step 3). */
|
|
174
|
+
diskSeed: jsonText(),
|
|
175
|
+
}, (t) => [check("environments_kind_check", sql `${t.kind} IN ('virtual', 'pod', 'none')`)]);
|
|
176
|
+
/**
|
|
177
|
+
* A vault (D56): the host model's (`id = 'host'`), or one Environment's, created and deleted with
|
|
178
|
+
* it (`environment_id`, unique, deleted with the Environment's row). No other vault exists.
|
|
179
|
+
*/
|
|
110
180
|
export const vaults = nylorun.table("vaults", {
|
|
111
181
|
id: textC().primaryKey(),
|
|
112
182
|
name: text().notNull(),
|
|
113
|
-
ownerUserId: text().notNull(),
|
|
114
183
|
/** JSON text, or null. */
|
|
115
184
|
metadataJson: text(),
|
|
116
185
|
createdAt: textC().notNull(),
|
|
117
|
-
/**
|
|
118
|
-
|
|
119
|
-
* attachable to any session (owner `installation`); `host`: the model vault, never attached.
|
|
120
|
-
*/
|
|
121
|
-
scope: text({ enum: ["user", "installation", "host"] }).notNull().default("user"),
|
|
186
|
+
/** The Environment the vault belongs to; null only for the host vault. */
|
|
187
|
+
environmentId: textC(),
|
|
122
188
|
}, (t) => [
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
189
|
+
uniqueIndex("vaults_environment").on(t.environmentId),
|
|
190
|
+
foreignKey({
|
|
191
|
+
name: "vaults_environment_id_fkey",
|
|
192
|
+
columns: [t.environmentId],
|
|
193
|
+
foreignColumns: [environments.id],
|
|
194
|
+
}).onDelete("cascade"),
|
|
195
|
+
check("vaults_owner_check", sql `(${t.id} = 'host') = (${t.environmentId} IS NULL)`),
|
|
126
196
|
]);
|
|
127
197
|
/** A credential of a vault: its binding in the clear, its secret sealed. */
|
|
128
198
|
export const vaultCredentials = nylorun.table("vault_credentials", {
|
|
@@ -146,6 +216,7 @@ export const vaultCredentials = nylorun.table("vault_credentials", {
|
|
|
146
216
|
foreignColumns: [vaults.id],
|
|
147
217
|
}).onDelete("cascade"),
|
|
148
218
|
index("vault_credentials_vault").on(t.vaultId, t.createdAt, t.id),
|
|
219
|
+
uniqueIndex("vault_credentials_name").on(t.vaultId, t.name),
|
|
149
220
|
]);
|
|
150
221
|
export const vaultAudit = nylorun.table("vault_audit", {
|
|
151
222
|
ord: bigint({ mode: "number" }).primaryKey().generatedAlwaysAsIdentity(),
|
|
@@ -198,7 +269,9 @@ export const signingKeys = nylorun.table("signing_keys", {
|
|
|
198
269
|
* The model usage ledger (P1.3): one row per model call a gate served, written after the call.
|
|
199
270
|
* A second row for the same effect (a call the gate ran again after a gateway restart) is
|
|
200
271
|
* flagged `duplicate`; both were billed. Budgets read their spend from it. Token counts are 0
|
|
201
|
-
* when the provider sent none.
|
|
272
|
+
* when the provider sent none. `startedAt`, `endedAt` and `firstTokenMs` are the gate's own
|
|
273
|
+
* timing of the call (R7.1, migration 0022); null on rows written before, and `firstTokenMs`
|
|
274
|
+
* when the provider streamed nothing.
|
|
202
275
|
*/
|
|
203
276
|
export const modelUsage = nylorun.table("model_usage", {
|
|
204
277
|
id: textC().primaryKey(),
|
|
@@ -222,6 +295,12 @@ export const modelUsage = nylorun.table("model_usage", {
|
|
|
222
295
|
/** True when an earlier row has the same `effectKey`: the provider billed the call twice. */
|
|
223
296
|
duplicate: boolean().notNull(),
|
|
224
297
|
createdAt: text().notNull(),
|
|
298
|
+
/** When the gate sent the call to the provider. */
|
|
299
|
+
startedAt: text(),
|
|
300
|
+
/** When the provider's answer was complete. */
|
|
301
|
+
endedAt: text(),
|
|
302
|
+
/** From `startedAt` to the provider's first stream event. */
|
|
303
|
+
firstTokenMs: integer(),
|
|
225
304
|
}, (t) => [
|
|
226
305
|
index("model_usage_session").on(t.sessionId, t.createdAt, t.id),
|
|
227
306
|
index("model_usage_export").on(t.txid, t.id),
|
|
@@ -260,60 +339,6 @@ export const toolCrossings = nylorun.table("tool_crossings", {
|
|
|
260
339
|
/** The gate's answer (`McpAnswer`), once the call ended; null while it runs or once lost. */
|
|
261
340
|
answer: jsonText(),
|
|
262
341
|
}, (t) => [index("tool_crossings_settled").on(t.settledAt)]);
|
|
263
|
-
/**
|
|
264
|
-
* A sandbox resource (blueprint D39, F7.1): its id, kind, the spec resolved against the
|
|
265
|
-
* Tenant's limits when it was created, and the developer's labels. Sessions attach to it by id
|
|
266
|
-
* (the session body's `sandboxId`). Not the `sandboxes` document table, which holds the virtual
|
|
267
|
-
* backend's compute records, keyed by workspace key.
|
|
268
|
-
*/
|
|
269
|
-
export const sandboxResources = nylorun.table("sandbox_resources", {
|
|
270
|
-
id: textC().primaryKey(),
|
|
271
|
-
kind: text({ enum: ["virtual", "pod"] }).notNull(),
|
|
272
|
-
/** The resolved `SandboxManifest`. */
|
|
273
|
-
spec: jsonText().notNull(),
|
|
274
|
-
/** `{ key: value }`, filtered through `nylorun.doc(labels)`. */
|
|
275
|
-
labels: jsonText().notNull(),
|
|
276
|
-
createdAt: textC().notNull(),
|
|
277
|
-
updatedAt: textC().notNull(),
|
|
278
|
-
// Kind `pod` (F7.2, D34): null for a virtual sandbox. `tenant/sandboxes.ts` and the
|
|
279
|
-
// `Sandbox` object's reconcile (`sandbox/pods/reconcile.ts`) are the only writers.
|
|
280
|
-
/** The agent-sandbox Sandbox's name, `sbx-<16 base32>-g<volume_gen>` (`podName`). */
|
|
281
|
-
k8sName: textC(),
|
|
282
|
-
/** Bumped by every reset: a new Sandbox on a new volume. */
|
|
283
|
-
volumeGen: integer().notNull().default(0),
|
|
284
|
-
/** `running`, `suspended` or `deleted`. */
|
|
285
|
-
desired: text({ enum: ["running", "suspended", "deleted"] }),
|
|
286
|
-
/** `creating`, `running`, `suspended`, `expired`, `lost`, `failed` or `deleting`. */
|
|
287
|
-
observed: text({
|
|
288
|
-
enum: ["creating", "running", "suspended", "expired", "lost", "failed", "deleting"],
|
|
289
|
-
}),
|
|
290
|
-
/** The UID of the pod that last joined. */
|
|
291
|
-
podUid: text(),
|
|
292
|
-
/**
|
|
293
|
-
* Bumped by every join (`host.join`), relaunch, loss and reset: host and egress tokens carry
|
|
294
|
-
* it (`epc`), and one of an older epoch is refused (egress-gate reads it too).
|
|
295
|
-
*/
|
|
296
|
-
hostEpoch: integer().notNull().default(0),
|
|
297
|
-
/** sha256 (hex) of the incarnation's join token; the token itself is never stored. */
|
|
298
|
-
joinTokenHash: text(),
|
|
299
|
-
/** Bumped by every change the Runtime asks of the pod: the sandboxes service's `opId`. */
|
|
300
|
-
rev: integer().notNull().default(0),
|
|
301
|
-
/** When a turn last ended on it, for the idle timer. */
|
|
302
|
-
lastActiveAt: timestamp({ withTimezone: true }),
|
|
303
|
-
/** When its TTL passes (`createdAt + lifecycle.ttl`). */
|
|
304
|
-
expiresAt: timestamp({ withTimezone: true }),
|
|
305
|
-
/** When the current incarnation was asked to run, for the ready deadline. */
|
|
306
|
-
startedAt: timestamp({ withTimezone: true }),
|
|
307
|
-
/** Why it failed or was lost. */
|
|
308
|
-
reason: text(),
|
|
309
|
-
/** An earlier incarnation's Sandbox still to delete (after a reset or a loss). */
|
|
310
|
-
retiring: textC(),
|
|
311
|
-
/**
|
|
312
|
-
* The id the engine keeps on the volume (`/harness/volume-id`), recorded at the first join:
|
|
313
|
-
* a join with another one means the volume was replaced (its files are gone), so `lost`.
|
|
314
|
-
*/
|
|
315
|
-
volumeId: text(),
|
|
316
|
-
});
|
|
317
342
|
/**
|
|
318
343
|
* Artifacts (blueprint D35, F8.1 and F8.2): an id, a name and numbered versions. The bytes are in
|
|
319
344
|
* the Object store under each version's `blobKey` (a folder's: its manifest); a blob counts only
|
|
@@ -331,8 +356,12 @@ export const artifacts = nylorun.table("artifacts", {
|
|
|
331
356
|
labelsJson: text(),
|
|
332
357
|
createdAt: textC().notNull(),
|
|
333
358
|
updatedAt: text().notNull(),
|
|
359
|
+
/** The Environment whose disk versions this folder holds (R2d step 3); one per Environment. */
|
|
360
|
+
environmentId: textC(),
|
|
334
361
|
}, (t) => [
|
|
335
362
|
index("artifacts_session").on(t.sessionId, t.createdAt, t.id),
|
|
363
|
+
uniqueIndex("artifacts_environment_disk").on(t.environmentId).where(sql `environment_id IS NOT NULL`),
|
|
364
|
+
index("artifacts_creation_order").on(t.createdAt, t.id),
|
|
336
365
|
check("artifacts_kind_check", sql `kind IN ('file', 'folder')`),
|
|
337
366
|
]);
|
|
338
367
|
/** The versions of an artifact, immutable once written. */
|
|
@@ -344,7 +373,7 @@ export const artifactVersions = nylorun.table("artifact_versions", {
|
|
|
344
373
|
size: bigint({ mode: "number" }).notNull(),
|
|
345
374
|
sha256: text().notNull(),
|
|
346
375
|
contentType: text().notNull(),
|
|
347
|
-
source: text({ enum: ["upload", "engine", "export"] }).notNull(),
|
|
376
|
+
source: text({ enum: ["upload", "engine", "export", "snapshot"] }).notNull(),
|
|
348
377
|
createdAt: textC().notNull(),
|
|
349
378
|
}, (t) => [
|
|
350
379
|
primaryKey({ name: "artifact_versions_pkey", columns: [t.artifactId, t.version] }),
|
|
@@ -406,7 +435,8 @@ export const definitionFileUses = nylorun.table("definition_file_uses", {
|
|
|
406
435
|
* written in the transaction that commits what they announce and notified on
|
|
407
436
|
* `nylorun_control` at commit (`control.ts`). A row outlives its notification so a process
|
|
408
437
|
* whose listener was down catches up; the Tenant sweep deletes old ones. `created_at` is the
|
|
409
|
-
* insert's own clock (`clock_timestamp()`), not its transaction's start.
|
|
438
|
+
* insert's own clock (`clock_timestamp()`), not its transaction's start. `sandbox_id` and
|
|
439
|
+
* `epoch` are a `host.revoked` signal's.
|
|
410
440
|
*/
|
|
411
441
|
export const controlSignals = nylorun.table("control_signals", {
|
|
412
442
|
id: bigint({ mode: "number" }).primaryKey().generatedAlwaysAsIdentity(),
|
|
@@ -417,16 +447,20 @@ export const controlSignals = nylorun.table("control_signals", {
|
|
|
417
447
|
createdAt: timestamp({ withTimezone: true, mode: "string" })
|
|
418
448
|
.notNull()
|
|
419
449
|
.default(sql `clock_timestamp()`),
|
|
450
|
+
sandboxId: textC(),
|
|
451
|
+
epoch: integer(),
|
|
420
452
|
}, (t) => [
|
|
421
453
|
index("control_signals_created_at").on(t.createdAt),
|
|
422
|
-
check("control_signals_kind_check", sql `${t.kind} IN ('session.cancel', 'sessions.reset')`),
|
|
454
|
+
check("control_signals_kind_check", sql `${t.kind} IN ('session.cancel', 'sessions.reset', 'host.revoked')`),
|
|
423
455
|
]);
|
|
424
456
|
/**
|
|
425
457
|
* The wake outbox (architecture §12.3): one row per wake a committed transaction asked for
|
|
426
458
|
* (`Tx.wake`), written in that transaction, so a commit never loses its wake. The row is
|
|
427
459
|
* deleted once Durable Session Execution has accepted the wake; until then the Tenant sweep
|
|
428
460
|
* delivers it again, with the same idempotency key (`dedupe_key`, or `wake:<id>` without
|
|
429
|
-
* one). `created_at` is the insert's own clock (`clock_timestamp()`).
|
|
461
|
+
* one). `created_at` is the insert's own clock (`clock_timestamp()`). `attempts` counts the
|
|
462
|
+
* sweep's failed deliveries, `retry_at` is when it tries the row again, and a row
|
|
463
|
+
* `parked_at` is never tried again: it stays for an operator (`Tx.failOutbox`).
|
|
430
464
|
*/
|
|
431
465
|
export const wakes = nylorun.table("wakes", {
|
|
432
466
|
id: textC().primaryKey(),
|
|
@@ -436,20 +470,46 @@ export const wakes = nylorun.table("wakes", {
|
|
|
436
470
|
createdAt: timestamp({ withTimezone: true, mode: "date" })
|
|
437
471
|
.notNull()
|
|
438
472
|
.default(sql `clock_timestamp()`),
|
|
473
|
+
attempts: integer().notNull().default(0),
|
|
474
|
+
retryAt: timestamp({ withTimezone: true, mode: "date" }),
|
|
475
|
+
parkedAt: timestamp({ withTimezone: true, mode: "date" }),
|
|
439
476
|
}, (t) => [index("wakes_created_at").on(t.createdAt)]);
|
|
477
|
+
/**
|
|
478
|
+
* The sandbox signal outbox (F7.2): one row per pod sandbox reconcile or timer a committed
|
|
479
|
+
* transaction asked for (`Tx.signalSandbox`), kept and delivered as the wake outbox's rows are
|
|
480
|
+
* (`attempts`, `retry_at`, `parked_at`). A reconcile is sent with the idempotency key
|
|
481
|
+
* `signal:<id>`; a timer (`kind` `arm`) is its `timer` at `at` (ms since the epoch). Not in
|
|
482
|
+
* `wakes`, so a Runtime that delivers only wakes never reads one.
|
|
483
|
+
*/
|
|
484
|
+
export const sandboxSignals = nylorun.table("sandbox_signals", {
|
|
485
|
+
id: textC().primaryKey(),
|
|
486
|
+
sandboxId: textC().notNull(),
|
|
487
|
+
kind: text().notNull(),
|
|
488
|
+
timer: text(),
|
|
489
|
+
at: bigint({ mode: "number" }),
|
|
490
|
+
createdAt: timestamp({ withTimezone: true, mode: "date" })
|
|
491
|
+
.notNull()
|
|
492
|
+
.default(sql `clock_timestamp()`),
|
|
493
|
+
attempts: integer().notNull().default(0),
|
|
494
|
+
retryAt: timestamp({ withTimezone: true, mode: "date" }),
|
|
495
|
+
parkedAt: timestamp({ withTimezone: true, mode: "date" }),
|
|
496
|
+
}, (t) => [
|
|
497
|
+
index("sandbox_signals_created_at").on(t.createdAt),
|
|
498
|
+
check("sandbox_signals_kind_check", sql `${t.kind} IN ('reconcile', 'arm')`),
|
|
499
|
+
]);
|
|
440
500
|
// ---------------------------------------------------------------------------
|
|
441
501
|
// nylorun_streams: the record
|
|
442
502
|
/**
|
|
443
|
-
* Each
|
|
444
|
-
* Written only by the record module; not published to the stream relay.
|
|
503
|
+
* Each Environment's lifecycle stream (`nylorun.environment-event/1`), numbered from 0 per
|
|
504
|
+
* Environment id. Written only by the record module; not published to the stream relay.
|
|
445
505
|
*/
|
|
446
|
-
export const
|
|
447
|
-
|
|
506
|
+
export const environmentEvents = nylorunStreams.table("environment_events", {
|
|
507
|
+
environmentId: textC().notNull(),
|
|
448
508
|
seq: bigint({ mode: "number" }).notNull(),
|
|
449
509
|
type: text().notNull(),
|
|
450
510
|
body: jsonText().notNull(),
|
|
451
511
|
committedAt: timestamp({ withTimezone: true, mode: "string" }).notNull().defaultNow(),
|
|
452
|
-
}, (t) => [primaryKey({ name: "
|
|
512
|
+
}, (t) => [primaryKey({ name: "environment_events_pkey", columns: [t.environmentId, t.seq] })]);
|
|
453
513
|
/** Each session's log head: the next seq and the basin generation its events go to. */
|
|
454
514
|
export const sessionLogHeads = nylorunStreams.table("session_log_heads", {
|
|
455
515
|
sessionId: textC().primaryKey(),
|