@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.
Files changed (379) hide show
  1. package/CHANGELOG.md +171 -0
  2. package/README.md +18 -14
  3. package/dist/adapters/execution/restate.d.ts +15 -18
  4. package/dist/adapters/execution/restate.js +31 -27
  5. package/dist/adapters/replication/pgoutput.d.ts +1 -1
  6. package/dist/adapters/replication/pgoutput.js +3 -2
  7. package/dist/adapters/sandbox/local.js +8 -5
  8. package/dist/adapters/sandbox/virtual.js +2 -2
  9. package/dist/adapters/streams/s2.d.ts +1 -1
  10. package/dist/adapters/streams/s2.js +18 -14
  11. package/dist/api/a2a/card.d.ts +4 -3
  12. package/dist/api/a2a/card.js +4 -4
  13. package/dist/api/a2a/endpoint.js +3 -4
  14. package/dist/api/a2a/protocol.js +4 -0
  15. package/dist/api/a2a/routes.d.ts +2 -6
  16. package/dist/api/a2a/routes.js +30 -25
  17. package/dist/api/ag-ui/endpoint.js +2 -3
  18. package/dist/api/ag-ui/routes.js +8 -11
  19. package/dist/api/components.d.ts +6789 -3405
  20. package/dist/api/components.js +43 -30
  21. package/dist/api/gate/keys.js +7 -4
  22. package/dist/api/gate/routes.d.ts +6 -2
  23. package/dist/api/gate/routes.js +15 -11
  24. package/dist/api/http/app.js +9 -4
  25. package/dist/api/http/body.d.ts +17 -3
  26. package/dist/api/http/body.js +35 -7
  27. package/dist/api/http/respond.js +6 -2
  28. package/dist/api/http/routes/access.js +5 -4
  29. package/dist/api/http/routes/agent-manifests.d.ts +10 -0
  30. package/dist/api/http/routes/agent-manifests.js +135 -0
  31. package/dist/api/http/routes/agents.d.ts +11 -0
  32. package/dist/api/http/routes/agents.js +418 -0
  33. package/dist/api/http/routes/artifacts.js +21 -9
  34. package/dist/api/http/routes/coverage.d.ts +4 -4
  35. package/dist/api/http/routes/coverage.js +13 -7
  36. package/dist/api/http/routes/files.d.ts +2 -1
  37. package/dist/api/http/routes/files.js +31 -5
  38. package/dist/api/http/routes/mcp.js +3 -3
  39. package/dist/api/http/routes/me.d.ts +1 -1
  40. package/dist/api/http/routes/me.js +1 -2
  41. package/dist/api/http/routes/memories.d.ts +9 -0
  42. package/dist/api/http/routes/memories.js +152 -0
  43. package/dist/api/http/routes/reads.d.ts +10 -111
  44. package/dist/api/http/routes/reads.js +51 -29
  45. package/dist/api/http/routes/sessions.js +26 -54
  46. package/dist/api/http/routes/tenant.d.ts +2 -2
  47. package/dist/api/http/routes/tenant.js +77 -24
  48. package/dist/api/http/routes/triggers.d.ts +10 -0
  49. package/dist/api/http/routes/triggers.js +180 -0
  50. package/dist/api/inbound-files.d.ts +3 -9
  51. package/dist/api/inbound-files.js +18 -24
  52. package/dist/api/openapi.js +73 -47
  53. package/dist/artifacts/disk.d.ts +10 -14
  54. package/dist/artifacts/disk.js +99 -95
  55. package/dist/artifacts/files.d.ts +13 -4
  56. package/dist/artifacts/files.js +27 -9
  57. package/dist/artifacts/folder-upload.d.ts +75 -0
  58. package/dist/artifacts/folder-upload.js +263 -0
  59. package/dist/artifacts/folders.d.ts +14 -8
  60. package/dist/artifacts/folders.js +19 -11
  61. package/dist/artifacts/links.js +7 -6
  62. package/dist/artifacts/parts.d.ts +9 -14
  63. package/dist/artifacts/parts.js +11 -9
  64. package/dist/artifacts/pipe.d.ts +15 -0
  65. package/dist/artifacts/pipe.js +71 -0
  66. package/dist/artifacts/quota.d.ts +36 -0
  67. package/dist/artifacts/quota.js +44 -0
  68. package/dist/artifacts/service.d.ts +25 -1
  69. package/dist/artifacts/service.js +72 -27
  70. package/dist/blob/fs.js +2 -1
  71. package/dist/blob/s3.d.ts +6 -2
  72. package/dist/blob/s3.js +9 -7
  73. package/dist/blob/types.d.ts +1 -1
  74. package/dist/blob/types.js +1 -1
  75. package/dist/core/flow-host.d.ts +0 -1
  76. package/dist/core/limits.d.ts +11 -35
  77. package/dist/core/limits.js +5 -73
  78. package/dist/core/sandbox-routes.js +0 -1
  79. package/dist/core/turn-manifest.d.ts +1 -2
  80. package/dist/core/turn-manifest.js +4 -28
  81. package/dist/execution/memory.d.ts +8 -5
  82. package/dist/execution/memory.js +8 -6
  83. package/dist/execution/types.d.ts +1 -6
  84. package/dist/execution/types.js +0 -5
  85. package/dist/gates/contract.d.ts +3 -2
  86. package/dist/gates/contract.js +1 -1
  87. package/dist/gates/egress-credentials.js +5 -4
  88. package/dist/gates/egress.d.ts +13 -13
  89. package/dist/gates/egress.js +19 -21
  90. package/dist/gates/fixture-model.js +13 -2
  91. package/dist/gates/handler.d.ts +1 -3
  92. package/dist/gates/handler.js +4 -3
  93. package/dist/gates/http-client.d.ts +4 -3
  94. package/dist/gates/http-client.js +5 -7
  95. package/dist/gates/http-tool.d.ts +24 -4
  96. package/dist/gates/http-tool.js +41 -13
  97. package/dist/gates/in-process.d.ts +2 -1
  98. package/dist/gates/in-process.js +17 -9
  99. package/dist/gates/inflight.d.ts +2 -2
  100. package/dist/gates/inflight.js +3 -2
  101. package/dist/gates/journal.js +5 -7
  102. package/dist/gates/mcp-handler.d.ts +4 -3
  103. package/dist/gates/mcp-handler.js +15 -5
  104. package/dist/gates/meter.js +6 -5
  105. package/dist/gates/model-gate.d.ts +11 -2
  106. package/dist/gates/policy.d.ts +34 -6
  107. package/dist/gates/policy.js +66 -18
  108. package/dist/gates/provider-gate.d.ts +22 -0
  109. package/dist/gates/provider-gate.js +30 -0
  110. package/dist/gates/tool-calls.d.ts +1 -3
  111. package/dist/gates/tool-calls.js +2 -3
  112. package/dist/gates/tool-client.d.ts +1 -1
  113. package/dist/gates/tool-client.js +5 -6
  114. package/dist/gates/tool-contract.d.ts +8 -5
  115. package/dist/gates/tool-contract.js +1 -1
  116. package/dist/gates/tool-gate.d.ts +18 -7
  117. package/dist/gates/tool-gate.js +49 -7
  118. package/dist/harness/calls.d.ts +27 -25
  119. package/dist/harness/calls.js +40 -46
  120. package/dist/harness/executors.d.ts +10 -3
  121. package/dist/harness/executors.js +53 -23
  122. package/dist/harness/main.js +2 -2
  123. package/dist/harness/pod.d.ts +2 -2
  124. package/dist/harness/pod.js +7 -6
  125. package/dist/harness/run-tokens.d.ts +4 -1
  126. package/dist/harness/run-tokens.js +6 -2
  127. package/dist/harness/service.d.ts +17 -14
  128. package/dist/harness/service.js +21 -35
  129. package/dist/harness/setup.d.ts +0 -2
  130. package/dist/harness/setup.js +21 -15
  131. package/dist/harness/ws-client.d.ts +2 -2
  132. package/dist/harness/ws-client.js +7 -5
  133. package/dist/harness/ws-port.d.ts +3 -4
  134. package/dist/harness/ws-port.js +3 -4
  135. package/dist/harness-api/artifacts.d.ts +20 -0
  136. package/dist/harness-api/artifacts.js +478 -0
  137. package/dist/harness-api/in-process.d.ts +2 -2
  138. package/dist/harness-api/in-process.js +18 -16
  139. package/dist/harness-api/record.d.ts +10 -9
  140. package/dist/harness-api/record.js +113 -157
  141. package/dist/harness-api/renew.d.ts +1 -1
  142. package/dist/harness-api/renew.js +2 -2
  143. package/dist/harness-api/server.d.ts +1 -16
  144. package/dist/harness-api/server.js +86 -73
  145. package/dist/harness-api/start.d.ts +27 -5
  146. package/dist/harness-api/start.js +102 -19
  147. package/dist/harness-api/tool-journal.d.ts +15 -10
  148. package/dist/harness-api/tool-journal.js +26 -24
  149. package/dist/harness-api/workspace.d.ts +0 -4
  150. package/dist/harness-api/workspace.js +4 -47
  151. package/dist/harness-api/ws-server.js +10 -10
  152. package/dist/host/create-host.js +2 -3
  153. package/dist/host/execution.js +2 -3
  154. package/dist/host/gates.d.ts +2 -9
  155. package/dist/host/gates.js +15 -12
  156. package/dist/host/http.d.ts +2 -4
  157. package/dist/host/http.js +5 -29
  158. package/dist/host/main.js +10 -3
  159. package/dist/host/operate.js +12 -3
  160. package/dist/host/stack-config.d.ts +11 -0
  161. package/dist/host/stack-config.js +21 -1
  162. package/dist/index.d.ts +0 -1
  163. package/dist/index.js +0 -1
  164. package/dist/infra/index.js +2 -1
  165. package/dist/infra/readiness.d.ts +0 -2
  166. package/dist/infra/readiness.js +4 -3
  167. package/dist/keys/client.d.ts +1 -0
  168. package/dist/keys/client.js +2 -3
  169. package/dist/keys/contract.d.ts +0 -2
  170. package/dist/keys/contract.js +0 -2
  171. package/dist/keys/egress-ca.d.ts +0 -2
  172. package/dist/keys/egress-ca.js +2 -3
  173. package/dist/keys/keys.d.ts +15 -4
  174. package/dist/keys/keys.js +22 -1
  175. package/dist/keys/webhooks.d.ts +25 -0
  176. package/dist/keys/webhooks.js +62 -0
  177. package/dist/keys/x509.d.ts +8 -4
  178. package/dist/keys/x509.js +14 -5
  179. package/dist/management-openapi.json +3043 -1954
  180. package/dist/mcp/connect.d.ts +35 -26
  181. package/dist/mcp/connect.js +112 -141
  182. package/dist/mcp/pool.d.ts +27 -22
  183. package/dist/mcp/pool.js +34 -48
  184. package/dist/mcp/preview.d.ts +12 -5
  185. package/dist/mcp/preview.js +43 -26
  186. package/dist/mcp/snapshot.d.ts +35 -86
  187. package/dist/mcp/snapshot.js +93 -135
  188. package/dist/memory/service.d.ts +97 -0
  189. package/dist/memory/service.js +335 -0
  190. package/dist/memory/tool.d.ts +36 -0
  191. package/dist/memory/tool.js +84 -0
  192. package/dist/model/auth-store.js +5 -3
  193. package/dist/model/capabilities.d.ts +1 -1
  194. package/dist/model/catalog.d.ts +9 -36
  195. package/dist/model/catalog.js +6 -33
  196. package/dist/model/descriptor.d.ts +51 -0
  197. package/dist/model/descriptor.js +83 -0
  198. package/dist/model/models.d.ts +0 -3
  199. package/dist/model/models.js +3 -5
  200. package/dist/model/native-blocks.js +1 -1
  201. package/dist/model/pi-model.d.ts +16 -5
  202. package/dist/model/pi-model.js +86 -105
  203. package/dist/openapi.json +13653 -9986
  204. package/dist/reads/cursor.js +3 -1
  205. package/dist/reads/types.d.ts +3 -3
  206. package/dist/record/agent.d.ts +27 -0
  207. package/dist/record/agent.js +46 -0
  208. package/dist/record/append.d.ts +34 -2
  209. package/dist/record/append.js +50 -1
  210. package/dist/record/index.d.ts +2 -2
  211. package/dist/record/index.js +2 -2
  212. package/dist/redact.d.ts +1 -1
  213. package/dist/redact.js +3 -2
  214. package/dist/sandbox/egress-token.d.ts +3 -3
  215. package/dist/sandbox/egress-token.js +3 -3
  216. package/dist/sandbox/join.js +8 -7
  217. package/dist/sandbox/manager.d.ts +41 -41
  218. package/dist/sandbox/manager.js +112 -44
  219. package/dist/sandbox/placement.d.ts +2 -2
  220. package/dist/sandbox/placement.js +7 -10
  221. package/dist/sandbox/pods/client.d.ts +1 -10
  222. package/dist/sandbox/pods/client.js +8 -4
  223. package/dist/sandbox/pods/lifecycle.d.ts +25 -17
  224. package/dist/sandbox/pods/lifecycle.js +51 -29
  225. package/dist/sandbox/pods/network-gate.d.ts +4 -5
  226. package/dist/sandbox/pods/network-gate.js +7 -7
  227. package/dist/sandbox/pods/reconcile.js +14 -3
  228. package/dist/sandbox/pods/spec.js +8 -5
  229. package/dist/sandbox/policy.d.ts +7 -1
  230. package/dist/sandbox/policy.js +10 -3
  231. package/dist/sandbox/resolve.d.ts +11 -6
  232. package/dist/sandbox/resolve.js +19 -9
  233. package/dist/sandbox/setup.d.ts +6 -2
  234. package/dist/sandbox/setup.js +47 -14
  235. package/dist/sandbox/share.d.ts +5 -14
  236. package/dist/sandbox/share.js +5 -34
  237. package/dist/sandbox/skills.d.ts +7 -13
  238. package/dist/sandbox/skills.js +16 -31
  239. package/dist/sandbox/tenant-config.d.ts +2 -2
  240. package/dist/sandbox/tenant-config.js +4 -3
  241. package/dist/sandbox/tools.d.ts +7 -1
  242. package/dist/sandbox/tools.js +26 -26
  243. package/dist/sandbox/types.d.ts +10 -3
  244. package/dist/sandbox/types.js +9 -0
  245. package/dist/store/postgres/connect.d.ts +6 -5
  246. package/dist/store/postgres/connect.js +14 -11
  247. package/dist/store/postgres/control.js +13 -13
  248. package/dist/store/postgres/drizzle/0028_artifact_write_keys.sql +2 -0
  249. package/dist/store/postgres/drizzle/0029_protocol_15.sql +11 -0
  250. package/dist/store/postgres/drizzle/0030_protocol_15_runtime_block.sql +11 -0
  251. package/dist/store/postgres/drizzle/0031_protocol_15_mcp_snapshot.sql +8 -0
  252. package/dist/store/postgres/drizzle/0032_agents.sql +54 -0
  253. package/dist/store/postgres/drizzle/0033_agent_versions.sql +7 -0
  254. package/dist/store/postgres/drizzle/0034_protocol_17_session_queue.sql +13 -0
  255. package/dist/store/postgres/drizzle/0035_t4_triggers.sql +41 -0
  256. package/dist/store/postgres/drizzle/0036_t5_memories.sql +30 -0
  257. package/dist/store/postgres/drizzle/meta/_journal.json +63 -0
  258. package/dist/store/postgres/reads.js +17 -82
  259. package/dist/store/postgres/record-writer.d.ts +4 -4
  260. package/dist/store/postgres/record-writer.js +9 -9
  261. package/dist/store/postgres/schema.d.ts +1382 -151
  262. package/dist/store/postgres/schema.js +191 -37
  263. package/dist/store/postgres/store.js +384 -105
  264. package/dist/store/postgres/tenant.js +1 -2
  265. package/dist/store/types.d.ts +172 -57
  266. package/dist/store/types.js +0 -1
  267. package/dist/streams/relay/core.d.ts +3 -3
  268. package/dist/streams/relay/core.js +9 -10
  269. package/dist/tenant/advance.js +41 -39
  270. package/dist/tenant/agent-manifests.d.ts +72 -0
  271. package/dist/tenant/agent-manifests.js +359 -0
  272. package/dist/tenant/agent-versions.d.ts +126 -0
  273. package/dist/tenant/agent-versions.js +389 -0
  274. package/dist/tenant/agents.d.ts +230 -0
  275. package/dist/tenant/{environments.js → agents.js} +493 -328
  276. package/dist/tenant/auth.d.ts +1 -1
  277. package/dist/tenant/auth.js +3 -3
  278. package/dist/tenant/commands.d.ts +63 -2
  279. package/dist/tenant/commands.js +240 -90
  280. package/dist/tenant/context.d.ts +57 -33
  281. package/dist/tenant/context.js +6 -2
  282. package/dist/tenant/definition-files.d.ts +25 -4
  283. package/dist/tenant/definition-files.js +85 -47
  284. package/dist/tenant/effects.js +15 -51
  285. package/dist/tenant/ephemeral.js +2 -1
  286. package/dist/tenant/history.d.ts +1 -1
  287. package/dist/tenant/history.js +1 -1
  288. package/dist/tenant/host-token.d.ts +3 -3
  289. package/dist/tenant/host-token.js +11 -10
  290. package/dist/tenant/http.d.ts +5 -8
  291. package/dist/tenant/http.js +9 -0
  292. package/dist/tenant/identity-file.d.ts +29 -6
  293. package/dist/tenant/identity-file.js +45 -15
  294. package/dist/tenant/issuers.d.ts +5 -5
  295. package/dist/tenant/issuers.js +34 -26
  296. package/dist/tenant/jwt.d.ts +8 -2
  297. package/dist/tenant/jwt.js +10 -2
  298. package/dist/tenant/limits.d.ts +87 -0
  299. package/dist/tenant/limits.js +172 -0
  300. package/dist/tenant/memories.d.ts +38 -0
  301. package/dist/tenant/memories.js +119 -0
  302. package/dist/tenant/module.d.ts +4 -1
  303. package/dist/tenant/module.js +9 -8
  304. package/dist/tenant/outbound.d.ts +11 -14
  305. package/dist/tenant/outbound.js +10 -15
  306. package/dist/tenant/reset.js +2 -2
  307. package/dist/tenant/run-grants.d.ts +6 -0
  308. package/dist/tenant/run-grants.js +7 -2
  309. package/dist/tenant/run-token.d.ts +0 -4
  310. package/dist/tenant/run-token.js +6 -11
  311. package/dist/tenant/runtime-limits.d.ts +24 -0
  312. package/dist/tenant/runtime-limits.js +27 -0
  313. package/dist/tenant/runtime.d.ts +1 -1
  314. package/dist/tenant/runtime.js +38 -43
  315. package/dist/tenant/session-streams.js +7 -6
  316. package/dist/tenant/session.d.ts +1 -1
  317. package/dist/tenant/session.js +1 -1
  318. package/dist/tenant/sessions.d.ts +28 -45
  319. package/dist/tenant/sessions.js +89 -209
  320. package/dist/tenant/signing-keys.d.ts +1 -1
  321. package/dist/tenant/signing-keys.js +5 -6
  322. package/dist/tenant/status.js +10 -10
  323. package/dist/tenant/streams.js +18 -20
  324. package/dist/tenant/sweep.d.ts +1 -21
  325. package/dist/tenant/sweep.js +51 -51
  326. package/dist/tenant/transcript.d.ts +70 -23
  327. package/dist/tenant/transcript.js +28 -22
  328. package/dist/tenant/triggers.d.ts +143 -0
  329. package/dist/tenant/triggers.js +715 -0
  330. package/dist/tenant/turn-timing.d.ts +11 -1
  331. package/dist/tenant/turn-timing.js +3 -1
  332. package/dist/tenant/types.d.ts +9 -14
  333. package/dist/tenant/worker.d.ts +4 -10
  334. package/dist/tenant/worker.js +10 -14
  335. package/dist/traces/ids.js +5 -1
  336. package/dist/traces/map.d.ts +10 -7
  337. package/dist/traces/map.js +16 -12
  338. package/dist/traces/otlp.d.ts +3 -3
  339. package/dist/traces/otlp.js +5 -3
  340. package/dist/traces/projector.d.ts +9 -4
  341. package/dist/traces/projector.js +13 -7
  342. package/dist/traces/read.js +6 -1
  343. package/dist/tuning.d.ts +390 -0
  344. package/dist/tuning.js +677 -0
  345. package/dist/vault/headers.js +4 -2
  346. package/dist/vault/service.d.ts +13 -8
  347. package/dist/vault/service.js +61 -17
  348. package/dist/version.d.ts +1 -1
  349. package/dist/version.js +1 -1
  350. package/package.json +13 -12
  351. package/dist/api/http/routes/environment-manifests.d.ts +0 -9
  352. package/dist/api/http/routes/environment-manifests.js +0 -118
  353. package/dist/api/http/routes/environments.d.ts +0 -11
  354. package/dist/api/http/routes/environments.js +0 -332
  355. package/dist/artifacts/export.d.ts +0 -8
  356. package/dist/artifacts/export.js +0 -204
  357. package/dist/artifacts/media-types.d.ts +0 -30
  358. package/dist/artifacts/media-types.js +0 -137
  359. package/dist/artifacts/workspace.d.ts +0 -60
  360. package/dist/artifacts/workspace.js +0 -45
  361. package/dist/media.d.ts +0 -10
  362. package/dist/media.js +0 -58
  363. package/dist/record/environment.d.ts +0 -25
  364. package/dist/record/environment.js +0 -44
  365. package/dist/sandbox/runtime-tools.d.ts +0 -9
  366. package/dist/sandbox/runtime-tools.js +0 -16
  367. package/dist/sandbox/session-sandbox.d.ts +0 -16
  368. package/dist/sandbox/session-sandbox.js +0 -77
  369. package/dist/tenant/artifact-tool.d.ts +0 -13
  370. package/dist/tenant/artifact-tool.js +0 -243
  371. package/dist/tenant/environment-manifests.d.ts +0 -57
  372. package/dist/tenant/environment-manifests.js +0 -200
  373. package/dist/tenant/environments.d.ts +0 -174
  374. package/dist/tenant/skill-tool.d.ts +0 -20
  375. package/dist/tenant/skill-tool.js +0 -67
  376. package/dist/tenant/tool-results.d.ts +0 -57
  377. package/dist/tenant/tool-results.js +0 -298
  378. package/dist/tenant/tool-search.d.ts +0 -39
  379. package/dist/tenant/tool-search.js +0 -103
@@ -11,8 +11,8 @@
11
11
  * exists exactly when what it announces committed.
12
12
  * - **Follow.** `followControlSignals` holds one connection of its own that LISTENs (a pooled
13
13
  * connection cannot). Each notification reads back the signals of the last
14
- * `WINDOW_SECONDS` and delivers those this follower has not delivered yet. So does a poll
15
- * every `pollMs`, and every LISTEN after a reconnect: Postgres does not queue notifications
14
+ * `postgres.controlWindowSeconds` (Host tuning) and delivers those this follower has not delivered yet. So does a poll
15
+ * every `pollMs` (`postgres.controlPollMs`), and every LISTEN after a reconnect: Postgres does not queue notifications
16
16
  * for a session that is not connected, and the rows are what catches up. Ids are never read
17
17
  * as a cursor: they are allocated at insert and commit out of order, so a later id can be
18
18
  * visible first.
@@ -23,14 +23,10 @@
23
23
  */
24
24
  import { gte, lt, sql } from "drizzle-orm";
25
25
  import { createPostgresListenClient } from "./connect.js";
26
+ import { hostTuning } from "../../tuning.js";
26
27
  import { controlSignals } from "./schema.js";
27
28
  /** The channel every signal is notified on. */
28
29
  export const CONTROL_CHANNEL = "nylorun_control";
29
- /** How far back a read-back looks. Longer than the poll, so a missed notification is caught. */
30
- const WINDOW_SECONDS = 120;
31
- const POLL_MS = 5000;
32
- const RETRY_MIN_MS = 100;
33
- const RETRY_MAX_MS = 5000;
34
30
  const SIGNAL = {
35
31
  id: controlSignals.id,
36
32
  kind: controlSignals.kind,
@@ -69,7 +65,11 @@ export async function pruneSignals(db, before) {
69
65
  * start is fixed; the first LISTEN may still be retrying, and the poll covers it meanwhile.
70
66
  */
71
67
  export async function followControlSignals(source, db, onSignal, options = {}) {
72
- const pollMs = options.pollMs ?? POLL_MS;
68
+ const tuning = hostTuning().postgres;
69
+ const pollMs = options.pollMs ?? tuning.controlPollMs;
70
+ // How far back a read-back looks: longer than the poll, so a missed notification is caught.
71
+ const windowSeconds = tuning.controlWindowSeconds;
72
+ const { minMs: retryMinMs, maxMs: retryMaxMs } = tuning.controlRetry;
73
73
  const onError = options.onError ?? (() => { });
74
74
  // Drizzle leaves timestamps to its column types, so a raw read of one is text.
75
75
  const [start] = await db.execute(sql `SELECT clock_timestamp()::text AS now`);
@@ -78,7 +78,7 @@ export async function followControlSignals(source, db, onSignal, options = {}) {
78
78
  const delivered = new Map();
79
79
  let stopped = false;
80
80
  let retry;
81
- let delay = RETRY_MIN_MS;
81
+ let delay = retryMinMs;
82
82
  let draining;
83
83
  let again = false;
84
84
  const client = createPostgresListenClient(source, {
@@ -98,14 +98,14 @@ export async function followControlSignals(source, db, onSignal, options = {}) {
98
98
  void listen();
99
99
  }, delay);
100
100
  retry.unref();
101
- delay = Math.min(delay * 2, RETRY_MAX_MS);
101
+ delay = Math.min(delay * 2, retryMaxMs);
102
102
  }
103
103
  async function listen() {
104
104
  if (stopped)
105
105
  return;
106
106
  try {
107
107
  await client.unsafe(`LISTEN ${CONTROL_CHANNEL}`);
108
- delay = RETRY_MIN_MS;
108
+ delay = retryMinMs;
109
109
  drain();
110
110
  }
111
111
  catch (error) {
@@ -129,7 +129,7 @@ export async function followControlSignals(source, db, onSignal, options = {}) {
129
129
  const rows = await db
130
130
  .select(SIGNAL)
131
131
  .from(controlSignals)
132
- .where(gte(controlSignals.createdAt, sql `greatest(${since}::timestamptz, clock_timestamp() - make_interval(secs => ${WINDOW_SECONDS}))`))
132
+ .where(gte(controlSignals.createdAt, sql `greatest(${since}::timestamptz, clock_timestamp() - make_interval(secs => ${windowSeconds}))`))
133
133
  .orderBy(controlSignals.id);
134
134
  for (const row of rows)
135
135
  deliver(row);
@@ -160,7 +160,7 @@ export async function followControlSignals(source, db, onSignal, options = {}) {
160
160
  }
161
161
  /** A row a read-back can still return is younger than the window: keep twice that. */
162
162
  function forgetOld() {
163
- const before = Date.now() - 2 * WINDOW_SECONDS * 1000;
163
+ const before = Date.now() - 2 * windowSeconds * 1000;
164
164
  for (const [id, at] of delivered)
165
165
  if (at < before)
166
166
  delivered.delete(id);
@@ -0,0 +1,2 @@
1
+ ALTER TABLE "nylorun"."artifact_versions" ADD COLUMN "write_key" text COLLATE "C";--> statement-breakpoint
2
+ CREATE UNIQUE INDEX "artifact_versions_write_key" ON "nylorun"."artifact_versions" USING btree ("write_key") WHERE write_key IS NOT NULL;
@@ -0,0 +1,11 @@
1
+ -- Protocol 15: the harness boundary. `read_artifact` and `save_artifact` are our harness's own
2
+ -- tools, no longer the Runtime's: the manifest schema refuses a pinned `runtime` block that holds
3
+ -- them. A fresh start for the sessions that pinned one (every agent session since protocol 12):
4
+ -- each is closed (`session_closed`) and its history stays readable. Workflow sessions pin no
5
+ -- `runtime` block and carry over.
6
+ UPDATE "nylorun"."sessions" SET "body" = ("body"::jsonb || '{"closedReason":"protocol_15"}'::jsonb)::json
7
+ WHERE nylorun.doc("body") ->> 'closedReason' IS NULL
8
+ AND jsonb_path_exists(
9
+ nylorun.doc("body") -> 'manifest' -> 'runtime' -> 'tools',
10
+ '$[*] ? (@.name == "read_artifact" || @.name == "save_artifact")'
11
+ );
@@ -0,0 +1,11 @@
1
+ -- Protocol 15: the harness writes the model's instructions and defines the sandbox and skill
2
+ -- tools, so the manifest schema refuses a pinned `runtime` block, and a session pins its
3
+ -- definition as registered. A fresh start for the agent sessions that still pinned one (opened
4
+ -- by a build of protocol 15 before this change, on the root agent or an agent it uses as a tool):
5
+ -- each is closed (`session_closed`) and its history stays readable. The others carry over.
6
+ UPDATE "nylorun"."sessions" SET "body" = ("body"::jsonb || '{"closedReason":"protocol_15"}'::jsonb)::json
7
+ WHERE nylorun.doc("body") ->> 'closedReason' IS NULL
8
+ AND (
9
+ jsonb_path_exists(nylorun.doc("body") -> 'manifest', 'lax $.runtime')
10
+ OR jsonb_path_exists(nylorun.doc("body") -> 'manifest', 'lax $.tools[*].agent.runtime')
11
+ );
@@ -0,0 +1,8 @@
1
+ -- Protocol 15: the harness names a session's MCP tools and decides which to defer, so the
2
+ -- session pins what its servers listed, raw (`snapshotSchemaVersion` 2), and every MCP call names
3
+ -- its tool by `{server, tool}`. A session that pinned the former snapshot (model-facing names,
4
+ -- deferral decided by core) cannot run its next turn: each still open is closed
5
+ -- (`session_closed`) and its history stays readable. The others carry over.
6
+ UPDATE "nylorun"."sessions" SET "body" = ("body"::jsonb || '{"closedReason":"protocol_15"}'::jsonb)::json
7
+ WHERE nylorun.doc("body") ->> 'closedReason' IS NULL
8
+ AND nylorun.doc("body") -> 'mcpSnapshot' ->> 'snapshotSchemaVersion' = '1';
@@ -0,0 +1,54 @@
1
+ -- Protocol 16: Agents from one manifest (track T2), a fresh start. Agent definitions and
2
+ -- environment manifests cannot become agent manifests (v8) on their own: a definition has no
3
+ -- runtime section, and an Environment held sessions of many agents. So both go, and so do the
4
+ -- Environments with their pods, disks and vaults, as protocol 11 dropped sandboxes and vaults.
5
+ -- Every open session is closed (`protocol_16`): its history stays readable. `environments` is
6
+ -- renamed `agents` (made from a saved agent manifest only) and its lifecycle stream
7
+ -- `agent_events`; model budget scope `agent` is `manifest`, keyed by the manifest's name, so a
8
+ -- budget keeps its meaning, and the usage ledger names the manifest.
9
+ UPDATE "nylorun"."sessions" SET "body" = ("body"::jsonb || '{"closedReason":"protocol_16"}'::jsonb)::json
10
+ WHERE nylorun.doc("body") ->> 'closedReason' IS NULL;--> statement-breakpoint
11
+ DELETE FROM "nylorun"."vaults" WHERE "id" <> 'host';--> statement-breakpoint
12
+ DELETE FROM "nylorun"."vault_idempotency" WHERE "id" NOT LIKE 'host-model%';--> statement-breakpoint
13
+ DELETE FROM "nylorun"."sandboxes";--> statement-breakpoint
14
+ DELETE FROM "nylorun"."sandbox_signals";--> statement-breakpoint
15
+ DELETE FROM "nylorun"."artifacts" WHERE "environment_id" IS NOT NULL;--> statement-breakpoint
16
+ DELETE FROM "nylorun"."environments";--> statement-breakpoint
17
+ DELETE FROM "nylorun"."definition_file_uses";--> statement-breakpoint
18
+ DROP TABLE "nylorun"."definitions";--> statement-breakpoint
19
+ DROP TABLE "nylorun"."environment_manifests";--> statement-breakpoint
20
+ DROP TABLE "nylorun_streams"."environment_events";--> statement-breakpoint
21
+ CREATE TABLE "nylorun_streams"."agent_events" (
22
+ "agent_id" text COLLATE "C" NOT NULL,
23
+ "seq" bigint NOT NULL,
24
+ "type" text NOT NULL,
25
+ "body" json NOT NULL,
26
+ "committed_at" timestamp with time zone DEFAULT now() NOT NULL,
27
+ CONSTRAINT "agent_events_pkey" PRIMARY KEY("agent_id","seq")
28
+ );
29
+ --> statement-breakpoint
30
+ CREATE TABLE "nylorun"."agent_manifests" (
31
+ "name" text COLLATE "C" NOT NULL,
32
+ "version" integer NOT NULL,
33
+ "body" json NOT NULL,
34
+ "hash" text COLLATE "C" NOT NULL,
35
+ "saved_by" json NOT NULL,
36
+ "created_at" text COLLATE "C" NOT NULL,
37
+ CONSTRAINT "agent_manifests_pkey" PRIMARY KEY("name","version")
38
+ );
39
+ --> statement-breakpoint
40
+ ALTER TABLE "nylorun"."environments" RENAME TO "agents";--> statement-breakpoint
41
+ ALTER TABLE "nylorun"."agents" RENAME CONSTRAINT "environments_pkey" TO "agents_pkey";--> statement-breakpoint
42
+ ALTER TABLE "nylorun"."agents" DROP CONSTRAINT "environments_kind_check";--> statement-breakpoint
43
+ ALTER TABLE "nylorun"."agents" ADD CONSTRAINT "agents_kind_check" CHECK ("nylorun"."agents"."kind" IN ('virtual', 'pod', 'none'));--> statement-breakpoint
44
+ ALTER INDEX "nylorun"."environments_manifest" RENAME TO "agents_manifest";--> statement-breakpoint
45
+ ALTER TABLE "nylorun"."agents" ALTER COLUMN "manifest_name" SET NOT NULL;--> statement-breakpoint
46
+ ALTER TABLE "nylorun"."agents" ALTER COLUMN "manifest_version" SET NOT NULL;--> statement-breakpoint
47
+ ALTER TABLE "nylorun"."agents" ALTER COLUMN "manifest_hash" SET NOT NULL;--> statement-breakpoint
48
+ ALTER TABLE "nylorun"."agents" ADD COLUMN "manifest_ref" text NOT NULL;--> statement-breakpoint
49
+ ALTER TABLE "nylorun"."agents" ADD COLUMN "desired_state" text DEFAULT 'on' NOT NULL;--> statement-breakpoint
50
+ ALTER TABLE "nylorun"."model_usage" RENAME COLUMN "agent_id" TO "manifest_name";--> statement-breakpoint
51
+ ALTER INDEX "nylorun"."model_usage_agent" RENAME TO "model_usage_manifest";--> statement-breakpoint
52
+ UPDATE "nylorun"."model_budgets" SET "scope" = 'manifest' WHERE "scope" = 'agent';--> statement-breakpoint
53
+ ALTER TABLE "nylorun"."sessions" ADD COLUMN "manifest_name" text GENERATED ALWAYS AS (nylorun.doc(body)->'definition'->>'name') STORED;--> statement-breakpoint
54
+ CREATE INDEX "sessions_manifest" ON "nylorun"."sessions" USING btree ("manifest_name");
@@ -0,0 +1,7 @@
1
+ -- Track T3, Agents that evolve (D73): an Agent moves between versions of its manifest. While it
2
+ -- is outdated it names the version it moves to (`target_version`); a version that failed to start
3
+ -- is kept so a tracking Agent does not move to it again (`failed_version`); and while a pod starts
4
+ -- on a new version, what it ran before (`start_check`), which a failed start reverts to.
5
+ ALTER TABLE "nylorun"."agents" ADD COLUMN "target_version" integer;--> statement-breakpoint
6
+ ALTER TABLE "nylorun"."agents" ADD COLUMN "failed_version" integer;--> statement-breakpoint
7
+ ALTER TABLE "nylorun"."agents" ADD COLUMN "start_check" json;
@@ -0,0 +1,13 @@
1
+ CREATE TABLE "nylorun"."session_queue" (
2
+ "id" text COLLATE "C" PRIMARY KEY NOT NULL,
3
+ "session_id" text COLLATE "C" NOT NULL,
4
+ "seq" bigint NOT NULL,
5
+ "command" json NOT NULL,
6
+ "input" json NOT NULL,
7
+ "file_artifacts" json NOT NULL,
8
+ "writer" json NOT NULL,
9
+ "trace" json,
10
+ "created_at" text COLLATE "C" NOT NULL
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE UNIQUE INDEX "session_queue_order" ON "nylorun"."session_queue" USING btree ("session_id","seq");
@@ -0,0 +1,41 @@
1
+ CREATE TABLE "nylorun"."agent_triggers" (
2
+ "agent_id" text COLLATE "C" NOT NULL,
3
+ "trigger_id" text COLLATE "C" NOT NULL,
4
+ "kind" text NOT NULL,
5
+ "status" text NOT NULL,
6
+ "paused_reason" text,
7
+ "generation" integer DEFAULT 0 NOT NULL,
8
+ "next_fire_at" text COLLATE "C",
9
+ "last_fire_at" text COLLATE "C",
10
+ "endpoint_id" text COLLATE "C",
11
+ "sealed_secret" json,
12
+ "session_id" text COLLATE "C",
13
+ "note" text,
14
+ "effect_id" text,
15
+ "created_at" text COLLATE "C" NOT NULL,
16
+ "updated_at" text COLLATE "C" NOT NULL,
17
+ CONSTRAINT "agent_triggers_pkey" PRIMARY KEY("agent_id","trigger_id")
18
+ );
19
+ --> statement-breakpoint
20
+ CREATE TABLE "nylorun"."trigger_runs" (
21
+ "id" text COLLATE "C" PRIMARY KEY NOT NULL,
22
+ "agent_id" text COLLATE "C" NOT NULL,
23
+ "trigger_id" text COLLATE "C" NOT NULL,
24
+ "kind" text NOT NULL,
25
+ "run_key" text COLLATE "C" NOT NULL,
26
+ "due_at" text COLLATE "C" NOT NULL,
27
+ "fired_at" text COLLATE "C" NOT NULL,
28
+ "late" boolean DEFAULT false NOT NULL,
29
+ "status" text NOT NULL,
30
+ "reason" text,
31
+ "session_id" text COLLATE "C",
32
+ "turn_id" text COLLATE "C",
33
+ "queued_message_id" text COLLATE "C"
34
+ );
35
+ --> statement-breakpoint
36
+ ALTER TABLE "nylorun"."session_queue" ADD COLUMN "cause" json;--> statement-breakpoint
37
+ CREATE INDEX "agent_triggers_due" ON "nylorun"."agent_triggers" USING btree ("status","next_fire_at");--> statement-breakpoint
38
+ CREATE UNIQUE INDEX "agent_triggers_endpoint" ON "nylorun"."agent_triggers" USING btree ("endpoint_id") WHERE endpoint_id IS NOT NULL;--> statement-breakpoint
39
+ CREATE UNIQUE INDEX "trigger_runs_key" ON "nylorun"."trigger_runs" USING btree ("agent_id","run_key");--> statement-breakpoint
40
+ CREATE INDEX "trigger_runs_agent" ON "nylorun"."trigger_runs" USING btree ("agent_id","id");--> statement-breakpoint
41
+ CREATE INDEX "trigger_runs_fired" ON "nylorun"."trigger_runs" USING btree ("fired_at");
@@ -0,0 +1,30 @@
1
+ CREATE TABLE "nylorun"."memories" (
2
+ "agent_id" text COLLATE "C" NOT NULL,
3
+ "path" text COLLATE "C" NOT NULL,
4
+ "content" text NOT NULL,
5
+ "content_sha256" text NOT NULL,
6
+ "bytes" integer NOT NULL,
7
+ "description" text,
8
+ "version" integer NOT NULL,
9
+ "updated_at" text COLLATE "C" NOT NULL,
10
+ CONSTRAINT "memories_pkey" PRIMARY KEY("agent_id","path")
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE TABLE "nylorun"."memory_versions" (
14
+ "id" text COLLATE "C" PRIMARY KEY NOT NULL,
15
+ "agent_id" text COLLATE "C" NOT NULL,
16
+ "path" text COLLATE "C" NOT NULL,
17
+ "from_path" text COLLATE "C",
18
+ "operation" text NOT NULL,
19
+ "content" text,
20
+ "content_sha256" text,
21
+ "bytes" integer,
22
+ "actor" text NOT NULL,
23
+ "session_id" text COLLATE "C",
24
+ "turn_id" text COLLATE "C",
25
+ "trigger_run_id" text COLLATE "C",
26
+ "created_at" text COLLATE "C" NOT NULL
27
+ );
28
+ --> statement-breakpoint
29
+ CREATE INDEX "memory_versions_agent" ON "nylorun"."memory_versions" USING btree ("agent_id","id");--> statement-breakpoint
30
+ CREATE INDEX "memory_versions_path" ON "nylorun"."memory_versions" USING btree ("agent_id","path","id");
@@ -197,6 +197,69 @@
197
197
  "when": 1791997067694,
198
198
  "tag": "0027_environment_image_digest",
199
199
  "breakpoints": true
200
+ },
201
+ {
202
+ "idx": 28,
203
+ "version": "7",
204
+ "when": 1792084466204,
205
+ "tag": "0028_artifact_write_keys",
206
+ "breakpoints": true
207
+ },
208
+ {
209
+ "idx": 29,
210
+ "version": "7",
211
+ "when": 1792086180701,
212
+ "tag": "0029_protocol_15",
213
+ "breakpoints": true
214
+ },
215
+ {
216
+ "idx": 30,
217
+ "version": "7",
218
+ "when": 1792091020175,
219
+ "tag": "0030_protocol_15_runtime_block",
220
+ "breakpoints": true
221
+ },
222
+ {
223
+ "idx": 31,
224
+ "version": "7",
225
+ "when": 1792094620175,
226
+ "tag": "0031_protocol_15_mcp_snapshot",
227
+ "breakpoints": true
228
+ },
229
+ {
230
+ "idx": 32,
231
+ "version": "7",
232
+ "when": 1792098220175,
233
+ "tag": "0032_agents",
234
+ "breakpoints": true
235
+ },
236
+ {
237
+ "idx": 33,
238
+ "version": "7",
239
+ "when": 1792161078177,
240
+ "tag": "0033_agent_versions",
241
+ "breakpoints": true
242
+ },
243
+ {
244
+ "idx": 34,
245
+ "version": "7",
246
+ "when": 1792163689759,
247
+ "tag": "0034_protocol_17_session_queue",
248
+ "breakpoints": true
249
+ },
250
+ {
251
+ "idx": 35,
252
+ "version": "7",
253
+ "when": 1792164194039,
254
+ "tag": "0035_t4_triggers",
255
+ "breakpoints": true
256
+ },
257
+ {
258
+ "idx": 36,
259
+ "version": "7",
260
+ "when": 1792172016681,
261
+ "tag": "0036_t5_memories",
262
+ "breakpoints": true
200
263
  }
201
264
  ]
202
265
  }
@@ -4,12 +4,14 @@ import { and, asc, desc, eq, exists, gt, inArray, isNull, lt, ne, or, sql, } fro
4
4
  import { isArtifactId } from "@nylorun/core/compatibility";
5
5
  import { readCursor } from "../../reads/cursor.js";
6
6
  import { fail } from "../../tenant/http.js";
7
+ import { limitsInForce, readTenantLimits } from "../../tenant/limits.js";
7
8
  import { artifactView } from "../../artifacts/service.js";
8
9
  import { sandboxWorkspaceKey } from "../../sandbox/records.js";
9
10
  import { database, driverError } from "./db.js";
10
11
  import { createPostgresReadClient } from "./connect.js";
12
+ import { hostTuning } from "../../tuning.js";
11
13
  import { toolCallDuration, toolCallStatus } from "../../harness-api/tool-status.js";
12
- import { effects, artifacts, modelUsage, environments, sandboxes, sessions, sessionEvents, } from "./schema.js";
14
+ import { effects, artifacts, modelUsage, sandboxes, sessions, sessionEvents, tenantSettings, } from "./schema.js";
13
15
  const sessionFields = {
14
16
  id: sessions.id,
15
17
  agentId: sessions.agentId,
@@ -17,11 +19,18 @@ const sessionFields = {
17
19
  status: sessions.status,
18
20
  activeTurnId: sql `${sessions.body}->>'activeTurnId'`,
19
21
  lastTurnId: sql `${sessions.body}->>'lastTurnId'`,
20
- environmentId: sessions.environmentId,
21
22
  createdAt: sessions.createdAt,
22
23
  };
24
+ /** Rows whose Agent id an Agent grant (`*`, an id, or a `p/*` prefix) reaches; none reach nothing. */
25
+ function grantsWhere(column, grants) {
26
+ if (grants.includes("*"))
27
+ return sql `true`;
28
+ if (grants.length === 0)
29
+ return sql `false`;
30
+ return or(...grants.map((grant) => grant.endsWith("/*") ? sql `starts_with(${column}, ${grant.slice(0, -1)})` : eq(column, grant)));
31
+ }
23
32
  function accessWhere(access) {
24
- return and(access.owner === undefined ? undefined : eq(sessions.ownerUserId, access.owner), access.agents === undefined ? undefined : inArray(sessions.agentId, [...access.agents]));
33
+ return and(access.owner === undefined ? undefined : eq(sessions.ownerUserId, access.owner), access.agents === undefined ? undefined : grantsWhere(sessions.agentId, access.agents));
25
34
  }
26
35
  function publicCall(row) {
27
36
  return {
@@ -29,7 +38,7 @@ function publicCall(row) {
29
38
  effectId: row.effectKey,
30
39
  sessionId: row.sessionId,
31
40
  turnId: row.turnId,
32
- agentId: row.agentId,
41
+ manifestName: row.manifestName,
33
42
  provider: row.provider,
34
43
  model: row.model,
35
44
  at: row.createdAt,
@@ -64,6 +73,7 @@ function publicToolCall(body) {
64
73
  toolName: request.toolName ?? null,
65
74
  kind: body.toolKind ?? null,
66
75
  server: body.server ?? null,
76
+ tool: body.tool ?? null,
67
77
  skill: body.skill ?? null,
68
78
  plugin: body.plugin ?? null,
69
79
  status,
@@ -118,7 +128,7 @@ export function createPostgresReadStore(source, tenantId) {
118
128
  return row.id;
119
129
  }
120
130
  return {
121
- close: () => pool.end({ timeout: 2 }),
131
+ close: () => pool.end({ timeout: hostTuning().postgres.readCloseTimeoutSeconds }),
122
132
  artifacts: (filters, page, access) => read(async (tx) => {
123
133
  if (filters.sessionId !== undefined)
124
134
  await requireSession(tx, filters.sessionId, access);
@@ -163,9 +173,7 @@ export function createPostgresReadStore(source, tenantId) {
163
173
  const rows = await tx
164
174
  .select(fields)
165
175
  .from(sessions)
166
- .where(and(accessWhere(access), position, filters.agentId === undefined ? undefined : eq(sessions.agentId, filters.agentId), filters.status === undefined ? undefined : eq(sessions.status, filters.status), filters.environmentId === undefined
167
- ? undefined
168
- : eq(sessions.environmentId, filters.environmentId), filters.ownerUserId === undefined
176
+ .where(and(accessWhere(access), position, filters.agentId === undefined ? undefined : eq(sessions.agentId, filters.agentId), filters.status === undefined ? undefined : eq(sessions.status, filters.status), filters.manifest === undefined ? undefined : eq(sessions.manifestName, filters.manifest), filters.ownerUserId === undefined
169
177
  ? undefined
170
178
  : eq(sessions.ownerUserId, filters.ownerUserId)))
171
179
  .orderBy(sql `${sessions.createdAt} desc nulls last`, desc(sessions.id))
@@ -186,8 +194,8 @@ export function createPostgresReadStore(source, tenantId) {
186
194
  .select({
187
195
  sessionId: sessions.id,
188
196
  agentId: sessions.agentId,
197
+ definition: sql `${sessions.body}->'definition'`,
189
198
  manifestHash: sql `${sessions.body}->>'manifestHash'`,
190
- implementationVersion: sql `${sessions.body}->>'implementationVersion'`,
191
199
  manifest: sql `${sessions.body}->'manifest'`,
192
200
  })
193
201
  .from(sessions)
@@ -301,78 +309,5 @@ export function createPostgresReadStore(source, tenantId) {
301
309
  asOf: new Date().toISOString(),
302
310
  };
303
311
  }),
304
- environments: (labels, page, access, grants) => read(async (tx) => {
305
- const cursor = readCursor(tenantId, "environments", labels);
306
- const key = keyOf(cursor.decode(page.cursor), 1);
307
- const allowed = grants === undefined
308
- ? undefined
309
- : or(...grants.map((grant) => grant.endsWith("/*")
310
- ? sql `starts_with(${environments.id}, ${grant.slice(0, -1)})`
311
- : eq(environments.id, grant)));
312
- const rows = await tx
313
- .select()
314
- .from(environments)
315
- .where(and(grants?.length === 0 ? sql `false` : allowed, key ? gt(environments.id, key[0]) : undefined, or(isNull(environments.desired), ne(environments.desired, "deleted")), ...Object.entries(labels).map(([k, v]) => sql `${environments.labels}::jsonb->>${k} = ${v}`)))
316
- .orderBy(asc(environments.id))
317
- .limit(page.limit + 1);
318
- const items = [];
319
- for (const row of rows.slice(0, page.limit)) {
320
- const [related] = await tx
321
- .select({
322
- items: sql `coalesce(json_agg(json_build_object('id', ${sessions.id}, 'activeTurnId', ${sessions.body}->>'activeTurnId') order by ${sessions.id}), '[]'::json)`,
323
- })
324
- .from(sessions)
325
- .where(and(eq(sessions.environmentId, row.id), accessWhere(access)));
326
- const [compute] = await tx
327
- .select({ body: sandboxes.body })
328
- .from(sandboxes)
329
- .where(eq(sandboxes.id, sandboxWorkspaceKey(tenantId, row.id)))
330
- .limit(1);
331
- const isPod = row.kind === "pod";
332
- items.push({
333
- id: row.id,
334
- kind: row.kind,
335
- labels: row.labels,
336
- manifest: row.recipe,
337
- ...(row.manifestName === null ? {} : { manifestName: row.manifestName }),
338
- ...(row.manifestVersion === null ? {} : { manifestVersion: row.manifestVersion }),
339
- ...(row.manifestHash === null ? {} : { manifestHash: row.manifestHash }),
340
- ...(row.forkedFrom ? { forkedFrom: row.forkedFrom } : {}),
341
- version: row.version,
342
- appliedVersion: row.appliedVersion,
343
- ownerUserId: row.ownerUserId,
344
- state: isPod
345
- ? row.observed === "running"
346
- ? "running"
347
- : row.observed === "creating"
348
- ? "creating"
349
- : "stopped"
350
- : row.kind === "none"
351
- ? "ready"
352
- : (compute?.body?.state ?? "ready"),
353
- ...(isPod
354
- ? {
355
- pod: {
356
- desired: row.desired,
357
- observed: row.observed,
358
- volumeGeneration: row.volumeGen,
359
- hostEpoch: row.hostEpoch,
360
- ...(row.reason ? { reason: row.reason } : {}),
361
- ...(row.imageDigest ? { imageDigest: row.imageDigest } : {}),
362
- },
363
- }
364
- : {}),
365
- lastUsedAt: new Date(row.lastUsedAt).toISOString(),
366
- sessions: related.items,
367
- createdAt: row.createdAt,
368
- updatedAt: row.updatedAt,
369
- });
370
- }
371
- const last = items.at(-1);
372
- return {
373
- environments: items,
374
- nextCursor: rows.length > page.limit && last ? cursor.encode([last.id]) : null,
375
- };
376
- }),
377
312
  };
378
313
  }
@@ -1,9 +1,9 @@
1
- import type { RecordWriter, EnvironmentRecordWriter } from "../../record/index.js";
1
+ import type { RecordWriter, AgentRecordWriter } from "../../record/index.js";
2
2
  import type { Transaction } from "./db.js";
3
3
  /**
4
- * The Environment stream writer of transaction `db` (`record/environment.ts`): the only inserts
5
- * into `environment_events`. The caller holds the Environment row's lock, which orders its events.
4
+ * The Agent stream writer of transaction `db` (`record/agent.ts`): the only inserts into
5
+ * `agent_events`. The caller holds the Agent row's lock, which orders its events.
6
6
  */
7
- export declare function postgresEnvironmentRecordWriter(db: Transaction): EnvironmentRecordWriter;
7
+ export declare function postgresAgentRecordWriter(db: Transaction): AgentRecordWriter;
8
8
  /** The record writer of transaction `db`. */
9
9
  export declare function postgresRecordWriter(db: Transaction): RecordWriter;
@@ -5,22 +5,22 @@
5
5
  * run in the store's transaction under the caller's session row lock.
6
6
  */
7
7
  import { eq, sql } from "drizzle-orm";
8
- import { environmentEvents, sessionEvents, sessionLogHeads, tenant } from "./schema.js";
8
+ import { agentEvents, sessionEvents, sessionLogHeads, tenant } from "./schema.js";
9
9
  /**
10
- * The Environment stream writer of transaction `db` (`record/environment.ts`): the only inserts
11
- * into `environment_events`. The caller holds the Environment row's lock, which orders its events.
10
+ * The Agent stream writer of transaction `db` (`record/agent.ts`): the only inserts into
11
+ * `agent_events`. The caller holds the Agent row's lock, which orders its events.
12
12
  */
13
- export function postgresEnvironmentRecordWriter(db) {
13
+ export function postgresAgentRecordWriter(db) {
14
14
  return {
15
- async nextSeq(environmentId) {
15
+ async nextSeq(agentId) {
16
16
  const [row] = await db
17
- .select({ next: sql `coalesce(max(${environmentEvents.seq}) + 1, 0)`.mapWith(Number) })
18
- .from(environmentEvents)
19
- .where(eq(environmentEvents.environmentId, environmentId));
17
+ .select({ next: sql `coalesce(max(${agentEvents.seq}) + 1, 0)`.mapWith(Number) })
18
+ .from(agentEvents)
19
+ .where(eq(agentEvents.agentId, agentId));
20
20
  return row?.next ?? 0;
21
21
  },
22
22
  async insert(row) {
23
- await db.insert(environmentEvents).values(row);
23
+ await db.insert(agentEvents).values(row);
24
24
  },
25
25
  };
26
26
  }