@nylorun/runtime 0.27.0-beta → 0.29.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.
Files changed (160) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +1 -1
  3. package/dist/api/a2a/card.d.ts +4 -3
  4. package/dist/api/a2a/card.js +3 -3
  5. package/dist/api/a2a/routes.js +18 -7
  6. package/dist/api/ag-ui/routes.js +4 -7
  7. package/dist/api/components.d.ts +5854 -2718
  8. package/dist/api/components.js +39 -30
  9. package/dist/api/http/app.js +9 -4
  10. package/dist/api/http/body.d.ts +2 -0
  11. package/dist/api/http/body.js +20 -0
  12. package/dist/api/http/define.d.ts +4 -0
  13. package/dist/api/http/define.js +20 -9
  14. package/dist/api/http/routes/agent-manifests.d.ts +10 -0
  15. package/dist/api/http/routes/agent-manifests.js +135 -0
  16. package/dist/api/http/routes/agents.d.ts +11 -0
  17. package/dist/api/http/routes/agents.js +418 -0
  18. package/dist/api/http/routes/artifacts.js +2 -2
  19. package/dist/api/http/routes/coverage.d.ts +4 -4
  20. package/dist/api/http/routes/coverage.js +12 -6
  21. package/dist/api/http/routes/files.js +1 -1
  22. package/dist/api/http/routes/mcp.js +2 -2
  23. package/dist/api/http/routes/me.d.ts +1 -1
  24. package/dist/api/http/routes/me.js +1 -2
  25. package/dist/api/http/routes/memories.d.ts +9 -0
  26. package/dist/api/http/routes/memories.js +152 -0
  27. package/dist/api/http/routes/reads.d.ts +1 -137
  28. package/dist/api/http/routes/reads.js +31 -12
  29. package/dist/api/http/routes/sessions.js +21 -50
  30. package/dist/api/http/routes/tenant.js +13 -10
  31. package/dist/api/http/routes/triggers.d.ts +10 -0
  32. package/dist/api/http/routes/triggers.js +183 -0
  33. package/dist/api/openapi.js +69 -47
  34. package/dist/artifacts/disk.d.ts +10 -10
  35. package/dist/artifacts/disk.js +27 -27
  36. package/dist/artifacts/quota.d.ts +1 -1
  37. package/dist/artifacts/quota.js +2 -2
  38. package/dist/artifacts/service.js +2 -2
  39. package/dist/core/flow-host.d.ts +0 -1
  40. package/dist/gates/egress-credentials.js +1 -1
  41. package/dist/gates/egress.d.ts +5 -5
  42. package/dist/gates/egress.js +6 -6
  43. package/dist/gates/http-tool.js +2 -2
  44. package/dist/gates/meter.js +22 -5
  45. package/dist/gates/policy.d.ts +8 -3
  46. package/dist/gates/policy.js +7 -2
  47. package/dist/gates/tenant-vaults.d.ts +1 -1
  48. package/dist/harness/pod.d.ts +2 -0
  49. package/dist/harness/setup.js +17 -6
  50. package/dist/harness-api/record.js +11 -0
  51. package/dist/harness-api/server.js +4 -0
  52. package/dist/harness-api/start.d.ts +11 -7
  53. package/dist/harness-api/start.js +49 -5
  54. package/dist/harness-api/workspace.js +2 -2
  55. package/dist/host/config-for.d.ts +2 -0
  56. package/dist/host/config-for.js +1 -0
  57. package/dist/host/http.d.ts +2 -2
  58. package/dist/host/http.js +5 -2
  59. package/dist/host/main.js +1 -0
  60. package/dist/keys/keys.d.ts +15 -4
  61. package/dist/keys/keys.js +16 -0
  62. package/dist/keys/webhooks.d.ts +25 -0
  63. package/dist/keys/webhooks.js +62 -0
  64. package/dist/management-openapi.json +313 -133
  65. package/dist/mcp/connect.d.ts +2 -2
  66. package/dist/mcp/connect.js +3 -3
  67. package/dist/mcp/preview.js +7 -7
  68. package/dist/memory/service.d.ts +97 -0
  69. package/dist/memory/service.js +335 -0
  70. package/dist/memory/tool.d.ts +36 -0
  71. package/dist/memory/tool.js +84 -0
  72. package/dist/model/pi-model.js +7 -0
  73. package/dist/openapi.json +13120 -9034
  74. package/dist/reads/types.d.ts +3 -3
  75. package/dist/record/agent.d.ts +27 -0
  76. package/dist/record/agent.js +46 -0
  77. package/dist/record/index.d.ts +1 -1
  78. package/dist/record/index.js +1 -1
  79. package/dist/sandbox/join.js +5 -5
  80. package/dist/sandbox/placement.d.ts +1 -1
  81. package/dist/sandbox/placement.js +3 -3
  82. package/dist/sandbox/pods/lifecycle.d.ts +6 -6
  83. package/dist/sandbox/pods/lifecycle.js +6 -6
  84. package/dist/sandbox/pods/reconcile.js +10 -2
  85. package/dist/sandbox/resolve.d.ts +3 -3
  86. package/dist/sandbox/resolve.js +7 -7
  87. package/dist/sandbox/setup.d.ts +3 -1
  88. package/dist/sandbox/setup.js +14 -4
  89. package/dist/store/postgres/drizzle/0032_agents.sql +54 -0
  90. package/dist/store/postgres/drizzle/0033_agent_versions.sql +7 -0
  91. package/dist/store/postgres/drizzle/0034_protocol_17_session_queue.sql +13 -0
  92. package/dist/store/postgres/drizzle/0035_t4_triggers.sql +41 -0
  93. package/dist/store/postgres/drizzle/0036_t5_memories.sql +30 -0
  94. package/dist/store/postgres/drizzle/0037_model_usage_cost_split.sql +4 -0
  95. package/dist/store/postgres/drizzle/meta/_journal.json +42 -0
  96. package/dist/store/postgres/reads.js +44 -87
  97. package/dist/store/postgres/record-writer.d.ts +4 -4
  98. package/dist/store/postgres/record-writer.js +9 -9
  99. package/dist/store/postgres/schema.d.ts +1408 -123
  100. package/dist/store/postgres/schema.js +194 -38
  101. package/dist/store/postgres/store.js +329 -79
  102. package/dist/store/postgres/tenant.js +1 -2
  103. package/dist/store/types.d.ts +155 -50
  104. package/dist/store/types.js +0 -1
  105. package/dist/tenant/advance.js +20 -8
  106. package/dist/tenant/agent-manifests.d.ts +72 -0
  107. package/dist/tenant/agent-manifests.js +359 -0
  108. package/dist/tenant/agent-versions.d.ts +126 -0
  109. package/dist/tenant/agent-versions.js +389 -0
  110. package/dist/tenant/agents.d.ts +230 -0
  111. package/dist/tenant/{environments.js → agents.js} +464 -320
  112. package/dist/tenant/auth.d.ts +1 -1
  113. package/dist/tenant/auth.js +3 -3
  114. package/dist/tenant/commands.d.ts +63 -2
  115. package/dist/tenant/commands.js +240 -83
  116. package/dist/tenant/context.d.ts +46 -19
  117. package/dist/tenant/context.js +6 -2
  118. package/dist/tenant/effects.js +7 -16
  119. package/dist/tenant/identity-file.d.ts +6 -6
  120. package/dist/tenant/identity-file.js +12 -10
  121. package/dist/tenant/issuers.js +3 -3
  122. package/dist/tenant/limits.d.ts +0 -3
  123. package/dist/tenant/limits.js +0 -3
  124. package/dist/tenant/memories.d.ts +38 -0
  125. package/dist/tenant/memories.js +119 -0
  126. package/dist/tenant/reset.js +2 -2
  127. package/dist/tenant/run-grants.d.ts +6 -0
  128. package/dist/tenant/run-grants.js +4 -0
  129. package/dist/tenant/runtime.d.ts +1 -1
  130. package/dist/tenant/runtime.js +8 -0
  131. package/dist/tenant/sessions.d.ts +28 -45
  132. package/dist/tenant/sessions.js +85 -208
  133. package/dist/tenant/status.js +6 -7
  134. package/dist/tenant/sweep.js +12 -3
  135. package/dist/tenant/transcript.d.ts +16 -16
  136. package/dist/tenant/triggers.d.ts +143 -0
  137. package/dist/tenant/triggers.js +715 -0
  138. package/dist/tenant/turn-timing.d.ts +11 -1
  139. package/dist/tenant/turn-timing.js +3 -1
  140. package/dist/tenant/types.d.ts +5 -0
  141. package/dist/tenant/worker.d.ts +2 -0
  142. package/dist/tenant/worker.js +5 -0
  143. package/dist/traces/map.d.ts +1 -1
  144. package/dist/traces/map.js +7 -1
  145. package/dist/tuning.d.ts +7 -0
  146. package/dist/tuning.js +19 -0
  147. package/dist/vault/service.d.ts +13 -8
  148. package/dist/vault/service.js +61 -17
  149. package/dist/version.d.ts +1 -1
  150. package/dist/version.js +1 -1
  151. package/package.json +13 -12
  152. package/dist/api/http/routes/environment-manifests.d.ts +0 -9
  153. package/dist/api/http/routes/environment-manifests.js +0 -118
  154. package/dist/api/http/routes/environments.d.ts +0 -11
  155. package/dist/api/http/routes/environments.js +0 -332
  156. package/dist/record/environment.d.ts +0 -27
  157. package/dist/record/environment.js +0 -46
  158. package/dist/tenant/environment-manifests.d.ts +0 -57
  159. package/dist/tenant/environment-manifests.js +0 -208
  160. package/dist/tenant/environments.d.ts +0 -172
@@ -54,7 +54,6 @@ export const tenant = nylorun.table("tenant", {
54
54
  /** Earlier generations whose basins are still to be deleted. */
55
55
  retiredGenerations: integer().array().notNull().default(sql `'{}'`),
56
56
  }, () => [check("tenant_singleton_check", sql `singleton`)]);
57
- export const definitions = documents("definitions");
58
57
  const xid8 = customType({ dataType: () => "xid8" });
59
58
  export const sessions = nylorun.table("sessions", {
60
59
  id: textC().primaryKey(),
@@ -69,14 +68,17 @@ export const sessions = nylorun.table("sessions", {
69
68
  ownerExpiresAt: timestamp({ withTimezone: true, mode: "date" }),
70
69
  /** The session owner (`ownerUserId`), not the lease column `owner`. */
71
70
  ownerUserId: field("->>'ownerUserId'"),
72
- /** The Environment the session names (`environment`, protocol 11). */
71
+ /** The Agent's environment the session runs on: its Agent's id (protocol 16). */
73
72
  environmentId: field("->>'environmentId'"),
73
+ /** The agent manifest the session pinned a version of (protocol 16). */
74
+ manifestName: field("->'definition'->>'name'"),
74
75
  }, (t) => [
75
76
  index("sessions_created").on(t.createdAt.desc().nullsLast(), t.id.desc().nullsFirst()),
76
77
  index("sessions_status").on(t.status, t.ownerExpiresAt),
77
78
  index("sessions_agent").on(t.agentId),
78
79
  index("sessions_owner_user").on(t.ownerUserId),
79
80
  index("sessions_environment").on(t.environmentId),
81
+ index("sessions_manifest").on(t.manifestName),
80
82
  ]);
81
83
  export const commands = documents("commands");
82
84
  export const effects = nylorun.table("effects", {
@@ -108,13 +110,15 @@ export const principals = nylorun.table("principals", {
108
110
  createdAt: text().notNull(),
109
111
  });
110
112
  /**
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
+ * An Agent (protocol 16; an Environment from protocol 11): the live instance of one version of an
114
+ * agent manifest, with its id, kind, labels, the recipe its environment runs (its manifest
115
+ * version's runtime section resolved, `recipe`, and what the current compute runs, `applied`),
113
116
  * 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.
117
+ * Sessions name it by id (the session body's `agentId`, and `environmentId` for its environment).
118
+ * Not the `sandboxes` document table, which holds the virtual backend's compute records, keyed by
119
+ * workspace key.
116
120
  */
117
- export const environments = nylorun.table("environments", {
121
+ export const agents = nylorun.table("agents", {
118
122
  id: textC().primaryKey(),
119
123
  kind: text({ enum: ["virtual", "pod", "none"] }).notNull(),
120
124
  /** `{ key: value }`, filtered through `nylorun.doc(labels)`. */
@@ -179,34 +183,150 @@ export const environments = nylorun.table("environments", {
179
183
  */
180
184
  diskSeed: jsonText(),
181
185
  /**
182
- * The environment manifest it was made from and its version (D63): null for an Environment
183
- * made from an inline manifest. Never changed after creation.
186
+ * The agent manifest it was made from and the version of it that it runs (track T3 moves it:
187
+ * `PUT /v1/agents/{id}`, and a save of the manifest for a tracking one).
184
188
  */
185
- manifestName: textC(),
186
- manifestVersion: integer(),
187
- /** The hash of what it runs (`recipe`), from creation on. */
188
- manifestHash: textC(),
189
- /** The Environment it was forked from: `{ environment, disk }` (Q15). Never changed. */
189
+ manifestName: textC().notNull(),
190
+ manifestVersion: integer().notNull(),
191
+ /** How it names the manifest: `tracking` (`name`) or `pinned` (`name@n`). */
192
+ manifestRef: text({ enum: ["tracking", "pinned"] }).notNull(),
193
+ /** The hash of the manifest version it runs. */
194
+ manifestHash: textC().notNull(),
195
+ /** `on`, or `off` once paused (track T6); nothing sets `off` yet. */
196
+ desiredState: text({ enum: ["on", "off"] }).notNull().default("on"),
197
+ /** The Agent it was forked from: `{ agent, disk }` (Q15). Never changed. */
190
198
  forkedFrom: jsonText(),
199
+ /**
200
+ * The manifest version it is moving to while it is outdated (track T3, D73): it waits for its
201
+ * required secrets, or for its pod's next start. `manifestVersion` stays the one it runs.
202
+ */
203
+ targetVersion: integer(),
204
+ /** A version that failed to start (T3): a tracking Agent does not move to it again on its own. */
205
+ failedVersion: integer(),
206
+ /**
207
+ * While a pod starts on a new version (T3): `{ from, startedAt }`, what it ran before, which a
208
+ * failed start reverts to. Cleared when the new pod's harness joins.
209
+ */
210
+ startCheck: jsonText(),
211
+ }, (t) => [
212
+ check("agents_kind_check", sql `${t.kind} IN ('virtual', 'pod', 'none')`),
213
+ index("agents_manifest").on(t.manifestName, t.manifestVersion),
214
+ ]);
215
+ /**
216
+ * An Agent's triggers (track T4, D74): what its manifest's `runtime.triggers` declares is the
217
+ * manifest's; whether each one is on and when it fires next is the Agent's, here. A booked wake
218
+ * (D77) is a row of kind `wake` with id `wake:<sessionId>`. Postgres holds the truth: one
219
+ * durable timer per active trigger is armed from `nextFireAt`, and the sweep re-arms an overdue
220
+ * one, so the execution's timers can be rebuilt from these rows.
221
+ */
222
+ export const agentTriggers = nylorun.table("agent_triggers", {
223
+ agentId: textC().notNull(),
224
+ triggerId: textC().notNull(),
225
+ kind: text({ enum: ["schedule", "at", "webhook", "wake"] }).notNull(),
226
+ status: text({ enum: ["active", "paused", "completed"] }).notNull(),
227
+ /** `manual`, or `new` for a trigger an upgrade added. */
228
+ pausedReason: text(),
229
+ /** Bumped when its timing changes, so a timer armed for an older time does nothing. */
230
+ generation: integer().notNull().default(0),
231
+ /** When it fires next (ISO), while active; a schedule's includes its jitter. */
232
+ nextFireAt: textC(),
233
+ lastFireAt: textC(),
234
+ /** A webhook trigger's endpoint id (`wh_…`), kept across upgrades. */
235
+ endpointId: textC(),
236
+ /**
237
+ * A webhook trigger's signing secret, sealed with the Tenant's vault key: only the keys service
238
+ * opens it, to verify a delivery (D75).
239
+ */
240
+ sealedSecret: jsonText(),
241
+ /** A booked wake's session, its note and the effect that booked it. */
242
+ sessionId: textC(),
243
+ note: text(),
244
+ effectId: text(),
245
+ createdAt: textC().notNull(),
246
+ updatedAt: textC().notNull(),
191
247
  }, (t) => [
192
- check("environments_kind_check", sql `${t.kind} IN ('virtual', 'pod', 'none')`),
193
- index("environments_manifest").on(t.manifestName, t.manifestVersion),
248
+ primaryKey({ name: "agent_triggers_pkey", columns: [t.agentId, t.triggerId] }),
249
+ index("agent_triggers_due").on(t.status, t.nextFireAt),
250
+ uniqueIndex("agent_triggers_endpoint").on(t.endpointId).where(sql `endpoint_id IS NOT NULL`),
194
251
  ]);
195
252
  /**
196
- * An environment manifest's versions (D63): a named, versioned definition of a kind of
197
- * Environment, saved like an agent. A version is written once and never changed; a save whose
198
- * body hashes the same as the latest writes nothing.
253
+ * An Agent's memories (track T5, D72): one row per Markdown file under `/memories`, its content
254
+ * inline (the Runtime limit `memoryBytes`, 100 KiB by default, bounds it). `version` counts the
255
+ * changes to this path; `description` is its frontmatter's, for the pinned index. A write locks the
256
+ * one row it changes, so writes to different memories never wait on each other.
257
+ */
258
+ export const memories = nylorun.table("memories", {
259
+ agentId: textC().notNull(),
260
+ path: textC().notNull(),
261
+ content: text().notNull(),
262
+ contentSha256: text().notNull(),
263
+ bytes: integer().notNull(),
264
+ description: text(),
265
+ version: integer().notNull(),
266
+ updatedAt: textC().notNull(),
267
+ }, (t) => [primaryKey({ name: "memories_pkey", columns: [t.agentId, t.path] })]);
268
+ /**
269
+ * One row per change to an Agent's memories (D72): what changed it, the content it left (`null`
270
+ * for a delete), and who made it, with the session, turn and trigger run of a turn's write.
271
+ * Versions belong to the Agent, so they outlive a deleted memory; they go with the Agent. Ids
272
+ * increase with time (`newMemoryVersionId`), so they page newest first.
199
273
  */
200
- export const environmentManifests = nylorun.table("environment_manifests", {
274
+ export const memoryVersions = nylorun.table("memory_versions", {
275
+ id: textC().primaryKey(),
276
+ agentId: textC().notNull(),
277
+ path: textC().notNull(),
278
+ /** A rename's old path. */
279
+ fromPath: textC(),
280
+ operation: text({ enum: ["create", "str_replace", "insert", "delete", "rename"] }).notNull(),
281
+ content: text(),
282
+ contentSha256: text(),
283
+ bytes: integer(),
284
+ actor: text().notNull(),
285
+ sessionId: textC(),
286
+ turnId: textC(),
287
+ triggerRunId: textC(),
288
+ createdAt: textC().notNull(),
289
+ }, (t) => [index("memory_versions_agent").on(t.agentId, t.id), index("memory_versions_path").on(t.agentId, t.path, t.id)]);
290
+ /**
291
+ * Each run of an Agent's triggers (D74): one per fire, delivery or run by hand, keyed by what
292
+ * caused it (`runKey`: `fire:<trigger>:<due ms>`, `webhook:<trigger>:<delivery id>`,
293
+ * `manual:<trigger>:<idempotency key>`), so a repeated cause makes no second run. Kept for the
294
+ * Runtime limit `triggerRunRetentionMs`.
295
+ */
296
+ export const triggerRuns = nylorun.table("trigger_runs", {
297
+ id: textC().primaryKey(),
298
+ agentId: textC().notNull(),
299
+ triggerId: textC().notNull(),
300
+ kind: text({ enum: ["schedule", "at", "webhook", "wake"] }).notNull(),
301
+ runKey: textC().notNull(),
302
+ dueAt: textC().notNull(),
303
+ firedAt: textC().notNull(),
304
+ late: boolean().notNull().default(false),
305
+ status: text({ enum: ["started", "queued", "skipped", "failed"] }).notNull(),
306
+ reason: text(),
307
+ sessionId: textC(),
308
+ turnId: textC(),
309
+ queuedMessageId: textC(),
310
+ }, (t) => [
311
+ uniqueIndex("trigger_runs_key").on(t.agentId, t.runKey),
312
+ index("trigger_runs_agent").on(t.agentId, t.id),
313
+ index("trigger_runs_fired").on(t.firedAt),
314
+ ]);
315
+ /**
316
+ * An agent manifest's versions (protocol 16): a named, versioned document with a harness and a
317
+ * runtime section. A version is written once and never changed; a save whose body hashes the
318
+ * same as the latest writes nothing.
319
+ */
320
+ export const agentManifests = nylorun.table("agent_manifests", {
201
321
  name: textC().notNull(),
202
322
  version: integer().notNull(),
203
- /** The manifest (`EnvironmentManifest`) as saved. */
323
+ /** The manifest (`AgentManifestV8`) as saved. */
204
324
  body: jsonText().notNull(),
205
325
  hash: textC().notNull(),
206
326
  /** `{ actor }`: the subject the save acted for, else `application`. */
207
327
  savedBy: jsonText().notNull(),
208
328
  createdAt: textC().notNull(),
209
- }, (t) => [primaryKey({ name: "environment_manifests_pkey", columns: [t.name, t.version] })]);
329
+ }, (t) => [primaryKey({ name: "agent_manifests_pkey", columns: [t.name, t.version] })]);
210
330
  /**
211
331
  * A vault (D56): the host model's (`id = 'host'`), or one Environment's, created and deleted with
212
332
  * it (`environment_id`, unique, deleted with the Environment's row). No other vault exists.
@@ -217,14 +337,14 @@ export const vaults = nylorun.table("vaults", {
217
337
  /** JSON text, or null. */
218
338
  metadataJson: text(),
219
339
  createdAt: textC().notNull(),
220
- /** The Environment the vault belongs to; null only for the host vault. */
340
+ /** The Agent the vault belongs to; null only for the host vault. */
221
341
  environmentId: textC(),
222
342
  }, (t) => [
223
343
  uniqueIndex("vaults_environment").on(t.environmentId),
224
344
  foreignKey({
225
345
  name: "vaults_environment_id_fkey",
226
346
  columns: [t.environmentId],
227
- foreignColumns: [environments.id],
347
+ foreignColumns: [agents.id],
228
348
  }).onDelete("cascade"),
229
349
  check("vaults_owner_check", sql `(${t.id} = 'host') = (${t.environmentId} IS NULL)`),
230
350
  ]);
@@ -305,7 +425,8 @@ export const signingKeys = nylorun.table("signing_keys", {
305
425
  * flagged `duplicate`; both were billed. Budgets read their spend from it. Token counts are 0
306
426
  * when the provider sent none. `startedAt`, `endedAt` and `firstTokenMs` are the gate's own
307
427
  * timing of the call (R7.1, migration 0022); null on rows written before, and `firstTokenMs`
308
- * when the provider streamed nothing.
428
+ * when the provider streamed nothing. The `cost*Usd` columns split `costUsd` by token kind, at the
429
+ * prices the adapter applied (migration 0037); null on rows written before.
309
430
  */
310
431
  export const modelUsage = nylorun.table("model_usage", {
311
432
  id: textC().primaryKey(),
@@ -316,7 +437,11 @@ export const modelUsage = nylorun.table("model_usage", {
316
437
  txid: xid8().notNull().default(sql `pg_current_xact_id()`),
317
438
  sessionId: textC().notNull(),
318
439
  turnId: textC().notNull(),
319
- agentId: textC().notNull(),
440
+ /**
441
+ * The agent manifest the call's agent came from: the loop manifest's id, a version's name
442
+ * (protocol 16; the definition id before, under `agent_id`).
443
+ */
444
+ manifestName: textC().notNull(),
320
445
  provider: text(),
321
446
  model: text(),
322
447
  inputTokens: integer().notNull(),
@@ -335,27 +460,58 @@ export const modelUsage = nylorun.table("model_usage", {
335
460
  endedAt: text(),
336
461
  /** From `startedAt` to the provider's first stream event. */
337
462
  firstTokenMs: integer(),
463
+ /** What the uncached input cost. */
464
+ costInputUsd: doublePrecision(),
465
+ /** What the input read from the provider's cache cost. */
466
+ costCacheReadUsd: doublePrecision(),
467
+ /** What the input written to the provider's cache cost. */
468
+ costCacheWriteUsd: doublePrecision(),
469
+ /** What the output cost. */
470
+ costOutputUsd: doublePrecision(),
338
471
  }, (t) => [
339
472
  index("model_usage_session").on(t.sessionId, t.createdAt, t.id),
340
473
  index("model_usage_export").on(t.txid, t.id),
341
474
  index("model_usage_effect").on(t.effectKey),
342
- index("model_usage_agent").on(t.agentId, t.createdAt),
475
+ index("model_usage_manifest").on(t.manifestName, t.createdAt),
343
476
  index("model_usage_turn").on(t.turnId),
344
477
  index("model_usage_created").on(t.createdAt),
345
478
  ]);
346
479
  /**
347
480
  * Model budgets (P1.3): hard caps the model gate checks before each call, at least one limit
348
- * set. One row per scope: `turn` and `tenant` use `*`, `agent` the agent id. `period` is the
481
+ * set. One row per scope: `turn` and `tenant` use `*`, `manifest` the agent manifest's name. `period` is the
349
482
  * UTC `day` or `month` the spend is counted over, or null for `turn`.
350
483
  */
351
484
  export const modelBudgets = nylorun.table("model_budgets", {
352
- scope: text({ enum: ["tenant", "agent", "turn"] }).notNull(),
485
+ scope: text({ enum: ["tenant", "manifest", "turn"] }).notNull(),
353
486
  scopeId: textC().notNull(),
354
487
  period: text({ enum: ["day", "month"] }),
355
488
  limitUsd: doublePrecision(),
356
489
  limitTokens: bigint({ mode: "number" }),
357
490
  updatedAt: text().notNull(),
358
491
  }, (t) => [primaryKey({ name: "model_budgets_pkey", columns: [t.scope, t.scopeId] })]);
492
+ /**
493
+ * Each session's queue (protocol 17, D76): messages that arrived while its turn ran or waited, in
494
+ * order (`seq`), until a turn takes them. A row holds the command as sent, the turn input its
495
+ * message gives the engine (file parts pinned when it was queued), and who sent it.
496
+ */
497
+ export const sessionQueue = nylorun.table("session_queue", {
498
+ id: textC().primaryKey(),
499
+ sessionId: textC().notNull(),
500
+ seq: bigint({ mode: "number" }).notNull(),
501
+ /** The `message` command as sent (`command.message`'s payload when a turn takes it). */
502
+ command: jsonText().notNull(),
503
+ /** The engine's input for it: an agent's message input, or a workflow's input value. */
504
+ input: jsonText().notNull(),
505
+ /** The artifacts its file parts named, which the session may read again. */
506
+ fileArtifacts: jsonText().notNull(),
507
+ /** Who sent it (`EventWriter`). */
508
+ writer: jsonText().notNull(),
509
+ /** The W3C trace context it was sent with. */
510
+ trace: jsonText(),
511
+ /** What sent it when not a client (track T4): a trigger's run, or the session's own wake. */
512
+ cause: jsonText(),
513
+ createdAt: textC().notNull(),
514
+ }, (t) => [uniqueIndex("session_queue_order").on(t.sessionId, t.seq)]);
359
515
  /**
360
516
  * The Tool Gate's keyed MCP calls (F4.1 G3): one row per call, written by the gates service
361
517
  * before it calls the server and given the answer after. A re-send whose row has an answer
@@ -390,7 +546,7 @@ export const artifacts = nylorun.table("artifacts", {
390
546
  labelsJson: text(),
391
547
  createdAt: textC().notNull(),
392
548
  updatedAt: text().notNull(),
393
- /** The Environment whose disk versions this folder holds (R2d step 3); one per Environment. */
549
+ /** The Agent whose disk versions this folder holds (R2d step 3); one per Agent. */
394
550
  environmentId: textC(),
395
551
  }, (t) => [
396
552
  index("artifacts_session").on(t.sessionId, t.createdAt, t.id),
@@ -459,9 +615,9 @@ export const definitionFiles = nylorun.table("definition_files", {
459
615
  createdAt: textC().notNull(),
460
616
  });
461
617
  /**
462
- * Which definition version names which definition file: one row per agent id, manifest hash
463
- * and file, written when the definition is stored. A later sweep deletes the files no
464
- * definition uses.
618
+ * Which agent manifest version names which definition file: one row per owner
619
+ * (`agent-manifest:<name>`), manifest hash and file, written when the version is saved. A later
620
+ * sweep deletes the files no version uses.
465
621
  */
466
622
  export const definitionFileUses = nylorun.table("definition_file_uses", {
467
623
  agentId: textC().notNull(),
@@ -541,16 +697,16 @@ export const sandboxSignals = nylorun.table("sandbox_signals", {
541
697
  // ---------------------------------------------------------------------------
542
698
  // nylorun_streams: the record
543
699
  /**
544
- * Each Environment's lifecycle stream (`nylorun.environment-event/1`), numbered from 0 per
545
- * Environment id. Written only by the record module; not published to the stream relay.
700
+ * Each Agent's lifecycle stream (`nylorun.agent-event/1`), numbered from 0 per Agent id. Written
701
+ * only by the record module; not published to the stream relay.
546
702
  */
547
- export const environmentEvents = nylorunStreams.table("environment_events", {
548
- environmentId: textC().notNull(),
703
+ export const agentEvents = nylorunStreams.table("agent_events", {
704
+ agentId: textC().notNull(),
549
705
  seq: bigint({ mode: "number" }).notNull(),
550
706
  type: text().notNull(),
551
707
  body: jsonText().notNull(),
552
708
  committedAt: timestamp({ withTimezone: true, mode: "string" }).notNull().defaultNow(),
553
- }, (t) => [primaryKey({ name: "environment_events_pkey", columns: [t.environmentId, t.seq] })]);
709
+ }, (t) => [primaryKey({ name: "agent_events_pkey", columns: [t.agentId, t.seq] })]);
554
710
  /** Each session's log head: the next seq and the basin generation its events go to. */
555
711
  export const sessionLogHeads = nylorunStreams.table("session_log_heads", {
556
712
  sessionId: textC().primaryKey(),