@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
@@ -1,108 +1,38 @@
1
1
  /**
2
- * Session and definition resources: `PUT/GET /v1/agents`, `PUT /v1/sessions/:id` (create, or
3
- * find an identical one), the session list and the session view. Reads use the store's typed
4
- * queries; `PUT /v1/sessions/:id` runs in one transaction with the Environment's checks.
2
+ * Session resources: `PUT /v1/sessions/:id` (create, or find an identical one), the session list
3
+ * and the session view. A session runs on one Agent (protocol 16) and pins the manifest version
4
+ * the Agent runs when it opens; each turn takes the version the Agent runs then
5
+ * (`agent-versions.ts`). Reads use the store's typed queries; `PUT /v1/sessions/:id` runs in
6
+ * one transaction with the Agent's checks.
5
7
  */
6
- import { DefinitionDocumentSchema, definitionFilesOf, } from "@nylorun/core/contracts";
7
- import { hashManifest } from "@nylorun/core/compatibility";
8
- import { approvalRefusal, codeToolRefusal } from "@nylorun/core/define";
8
+ import {} from "@nylorun/core/contracts";
9
9
  import { aggregateWaits, isWorkflowManifest } from "../core/flow-host.js";
10
10
  import { canonical } from "../store/canonical.js";
11
- import { sandboxSpecOf } from "../sandbox/resolve.js";
12
- import { withRuntimeTools, withSandbox } from "../sandbox/session-sandbox.js";
13
- import { authoredRuntimeBlocks, declaredSandboxes } from "../sandbox/share.js";
14
- import { effectiveSandboxConfig, readSandboxConfig } from "../sandbox/tenant-config.js";
15
- import { HARNESS_ID, checkPlacement, requirePods } from "../sandbox/placement.js";
16
- import { openEnvironment, recordAttachment } from "./environments.js";
17
- import { harnessOf, } from "./context.js";
11
+ import { readSandboxConfig } from "../sandbox/tenant-config.js";
12
+ import { checkPlacement, requirePods } from "../sandbox/placement.js";
13
+ import { pinOf } from "./agent-versions.js";
14
+ import { openAgent, recordAttachment } from "./agents.js";
15
+ import { harnessOf, reachesAgent, } from "./context.js";
18
16
  import { fail } from "./http.js";
19
- import { missingDefinitionFiles } from "./definition-files.js";
17
+ import { definitionFileIssues } from "./definition-files.js";
18
+ import { limitsInForce, readTenantLimits } from "./limits.js";
20
19
  /** A session's creation identity: everything but the request id. */
21
20
  const sessionIdentity = (value) => {
22
21
  const { requestId: _requestId, ...body } = value ?? {};
23
22
  return canonical(body);
24
23
  };
25
- export async function listDefinitions(ctx) {
26
- const definitions = await ctx.store.tx((t) => t.listDefinitions());
27
- return {
28
- agents: definitions.map((d) => ({
29
- agentId: d.manifest.id,
30
- manifest: d.manifest,
31
- manifestHash: d.manifestHash,
32
- implementationVersion: d.implementationVersion,
33
- })),
34
- };
35
- }
36
- /**
37
- * The agents a token caller may see: id, name and description only, never
38
- * instructions, tools or MCP servers, and only the agents allowed.
39
- */
40
- export async function listAgentsPublic(ctx, agents) {
41
- const definitions = await ctx.store.tx((t) => t.listDefinitions());
42
- return {
43
- agents: definitions
44
- .filter((d) => agents === "*" || agents.has(d.manifest.id))
45
- .map((d) => ({
46
- agentId: d.manifest.id,
47
- ...(typeof d.manifest.name === "string" ? { name: d.manifest.name } : {}),
48
- ...(typeof d.manifest.description === "string"
49
- ? { description: d.manifest.description }
50
- : {}),
51
- })),
52
- };
53
- }
54
- export async function putDefinition(ctx, agentId, body, options = {}) {
55
- if (body.manifest.id !== agentId)
56
- fail(400, "Agent id mismatch");
57
- DefinitionDocumentSchema.parse(body.manifest);
58
- // The Runtime runs agents from their manifests alone (track R2): no tool may need it.
59
- const code = codeToolRefusal(body.manifest);
60
- if (code)
61
- fail(400, code);
62
- // Tool approvals are the Tenant's tool policy, decided at the Tool Gate (R5 step 2).
63
- const approval = approvalRefusal(body.manifest);
64
- if (approval)
65
- fail(400, approval);
66
- const declared = declaredSandboxes(body.manifest);
67
- if (declared.length > 0)
68
- fail(400, `${declared.join(", ")} declares a sandbox. Agents no longer declare one: remove .sandbox(), create an Environment with the sandbox (PUT /v1/environments/{id}) and open the session on it, createSession({ environment }). See MIGRATION.md.`);
69
- const runtime = authoredRuntimeBlocks(body.manifest);
70
- if (runtime.length > 0)
71
- fail(400, `${runtime.join(", ")} sets runtime, which only the Runtime writes when it pins a session's agent. Remove it and register the manifest your builder makes.`);
72
- const definition = {
73
- ...body,
74
- manifestHash: hashManifest(body.manifest),
75
- };
76
- const files = [...definitionFilesOf(body.manifest)];
77
- await ctx.store.tx(async (t) => {
78
- const missing = await missingDefinitionFiles(t, body.manifest);
79
- if (missing.length > 0)
80
- fail(400, `The definition names ${missing.length} file(s) the Runtime does not hold; upload each with PUT /v1/files/<sha256> first: ${missing.join(", ")}`, { code: "definition_files_missing", details: { missing } });
81
- if (options.dryRun)
82
- return;
83
- await t.put("definitions", agentId, definition);
84
- await t.insertDefinitionFileUses(agentId, definition.manifestHash, files);
85
- });
86
- return {
87
- agentId,
88
- manifestHash: definition.manifestHash,
89
- implementationVersion: body.implementationVersion,
90
- ...(options.dryRun ? { dryRun: true } : {}),
91
- };
92
- }
93
24
  /**
94
- * `access`, when the request acts for a person, limits the list to that person's sessions of
95
- * the agents they may use.
25
+ * `access`, when the request acts for a person, limits the list to that person's sessions on
26
+ * the Agents they may use.
96
27
  */
97
28
  export async function listSessions(ctx, agentId, access) {
98
29
  const sessions = await ctx.store.tx((t) => t.listSessions({
99
30
  ...(agentId === null ? {} : { agentId }),
100
31
  ...(access === undefined ? {} : { ownerUserId: access.owner }),
101
32
  }));
102
- const allowed = access?.agents;
103
33
  return {
104
34
  sessions: sessions
105
- .filter((s) => allowed === undefined || allowed.has(s.agentId))
35
+ .filter((s) => reachesAgent(access, s.agentId))
106
36
  .map((s) => ({
107
37
  id: s.id,
108
38
  agentId: s.agentId,
@@ -113,137 +43,90 @@ export async function listSessions(ctx, agentId, access) {
113
43
  };
114
44
  }
115
45
  /**
116
- * Create a session from its definition, or find an identical one. `access`, when the request
117
- * acts for a subject, must be the session's owner: another owner's session id is the 404 of a
118
- * missing one (not the 409 of a mismatch), and so is an Environment whose owner guard names
119
- * another owner.
46
+ * Create a session on an Agent, or find an identical one. `access`, when the request acts for a
47
+ * subject, must be the session's owner: another owner's session id is the 404 of a missing one
48
+ * (not the 409 of a mismatch), and so is an Agent whose owner guard names another owner.
120
49
  *
121
- * The session's Environment is fixed for its life: its sandbox (kinds `virtual` and `pod`) is
122
- * the session's, with the spec of the Environment's applied recipe pinned now, and its vault
123
- * holds the session's credentials. Without one the session has no sandbox and no credentials.
50
+ * The session runs on its Agent for its life: the Agent's sandbox (kinds `virtual` and `pod`) is
51
+ * the session's, with the spec of what the Agent runs pinned now, and the Agent's vault holds the
52
+ * session's credentials. It pins the manifest version the Agent runs (`definition`), as the loop
53
+ * manifest that version's harness section makes, and the harness that section names (`pinOf`);
54
+ * a turn's first segment pins the version the Agent runs then (`repinTurn`).
124
55
  */
125
56
  export async function putSession(ctx, id, body, access, options = {}) {
126
57
  const opaque = access !== undefined;
127
58
  if (opaque && body.ownerUserId !== access.owner)
128
59
  fail(403, "ownerUserId must be the subject");
129
- // An agent the subject may not use is the 404 of a missing definition.
130
- if (access?.agents !== undefined && !access.agents.has(body.agentId))
131
- fail(404, "Definition not found");
132
- return ctx.store.tx(async (t) => {
133
- const prior = await t.lockSession(id);
134
- if (opaque &&
135
- prior &&
136
- (prior.ownerUserId !== access.owner ||
137
- (access.agents !== undefined && !access.agents.has(prior.agentId))))
138
- fail(404, "Session not found");
139
- if (prior && options.createOnly) {
140
- if (prior.ownerUserId !== body.ownerUserId ||
141
- prior.agentId !== body.agentId)
142
- fail(404, "Session not found");
143
- return prior;
144
- }
145
- if (prior) {
146
- if (sessionIdentity(prior.creation) !== sessionIdentity(body))
147
- fail(409, "Session already exists with different creation parameters");
148
- return prior;
149
- }
150
- const definition = (await t.get("definitions", body.agentId)) ??
151
- fail(404, "Definition not found");
152
- const environment = body.environment === undefined
153
- ? undefined
154
- : await openEnvironment(t, body.environment, {
155
- ...(options.environmentGrants === undefined ? {} : { grants: options.environmentGrants }),
156
- ownerUserId: body.ownerUserId,
157
- opaque,
158
- });
159
- if (!isWorkflowManifest(definition.manifest))
160
- await checkRequirements(t, definition.manifest, environment);
161
- const config = await readSandboxConfig(t);
162
- // The harness the session runs for its life (R4.1): its Environment's, else ours. A flow
163
- // runs in core and our engine, whatever its Environment names.
164
- const harness = isWorkflowManifest(definition.manifest) || environment === undefined
165
- ? HARNESS_ID
166
- : environment.applied.harness;
167
- // Placement (D38, D52): where this session's harness may run, decided now and kept.
168
- checkPlacement(config, environment?.kind, harness);
169
- if (environment?.kind === "pod")
170
- await requirePods(ctx.pods, `Environment ${environment.id}`);
171
- const spec = environment === undefined || environment.kind === "none"
172
- ? undefined
173
- : sandboxSpecOf(environment.applied, effectiveSandboxConfig(config).limits.idle);
174
- const pinned = spec === undefined ? runtimeTools(definition) : pin(definition, spec);
175
- const created = {
176
- id,
177
- agentId: body.agentId,
178
- ownerUserId: body.ownerUserId,
179
- manifest: pinned.manifest ?? definition.manifest,
180
- manifestHash: pinned.manifestHash ?? definition.manifestHash,
181
- definitionHash: definition.manifestHash,
182
- implementationVersion: definition.implementationVersion,
183
- info: body.info,
184
- status: "idle",
185
- activeTurnId: null,
186
- creation: body,
187
- harness,
188
- ...(environment === undefined
189
- ? {}
190
- : { environmentId: environment.id, environmentVersion: environment.version }),
191
- ...(spec === undefined ? {} : { sandbox: spec }),
192
- };
193
- await t.put("sessions", id, created);
194
- if (environment !== undefined)
195
- await recordAttachment(t, id, environment.id);
196
- return created;
197
- });
60
+ // An Agent the subject may not use is the 404 of a missing one.
61
+ if (!reachesAgent(access, body.agent))
62
+ fail(404, "Agent not found");
63
+ return ctx.store.tx((t) => openSessionIn(ctx, t, id, body, access, options));
198
64
  }
199
65
  /**
200
- * Refuses a session whose agent requires what its Environment lacks (protocol 14, D65): a
201
- * sandbox (`any`: kind `virtual` or `pod`), a pod, or a secret its vault does not hold. Every
202
- * gap is named in one `409 environment_unsuitable`.
66
+ * `putSession`'s work in transaction `t`: also how a trigger's first run opens the session it
67
+ * names (track T4), in the run's transaction.
203
68
  */
204
- async function checkRequirements(t, manifest, environment) {
205
- const requires = manifest.requires;
206
- if (requires === undefined)
207
- return;
208
- const missing = [];
209
- const kind = environment?.kind;
210
- if (requires.sandbox === "any" && kind !== "virtual" && kind !== "pod")
211
- missing.push("sandbox");
212
- if (requires.sandbox === "pod" && kind !== "pod")
213
- missing.push("pod");
214
- if (requires.secrets?.length) {
215
- const vault = environment === undefined ? undefined : await t.vaultOfEnvironment(environment.id);
216
- const held = new Set(vault ? (await t.credentialsForVault(vault.id)).map((row) => row.name) : []);
217
- for (const name of requires.secrets)
218
- if (!held.has(name))
219
- missing.push(`secret:${name}`);
69
+ export async function openSessionIn(ctx, t, id, body, access, options = {}) {
70
+ const opaque = access !== undefined;
71
+ const prior = await t.lockSession(id);
72
+ if (opaque && prior && (prior.ownerUserId !== access.owner || !reachesAgent(access, prior.agentId)))
73
+ fail(404, "Session not found");
74
+ if (prior && options.createOnly) {
75
+ if (prior.ownerUserId !== body.ownerUserId || prior.agentId !== body.agent)
76
+ fail(404, "Session not found");
77
+ return prior;
220
78
  }
221
- if (missing.length === 0)
222
- return;
223
- const where = environment === undefined ? "the session names no Environment" : `Environment ${environment.id} lacks it`;
224
- fail(409, `Agent ${manifest.id} requires ${missing.map((gap) => (gap.startsWith("secret:") ? `the secret ${gap.slice(7)}` : gap === "pod" ? "a pod Environment" : "a sandbox")).join(", ")}, and ${where}.`, { code: "environment_unsuitable", details: { missing } });
79
+ if (prior) {
80
+ if (sessionIdentity(prior.creation) !== sessionIdentity(body))
81
+ fail(409, "Session already exists with different creation parameters");
82
+ return prior;
83
+ }
84
+ const agent = await openAgent(t, body.agent, {
85
+ ...(options.agentGrants === undefined ? {} : { grants: options.agentGrants }),
86
+ ownerUserId: body.ownerUserId,
87
+ opaque,
88
+ });
89
+ // The version the Agent runs, both sections (T3): its loop manifest, harness and sandbox spec.
90
+ const { pin } = await pinOf(t, agent);
91
+ await checkSkillLimit(t, pin.manifest, agent);
92
+ const config = await readSandboxConfig(t);
93
+ // Placement (D38, D52): where this session's harness may run, decided now and kept.
94
+ checkPlacement(config, agent.kind, pin.harness);
95
+ if (agent.kind === "pod")
96
+ await requirePods(ctx.pods, `Agent ${agent.id}`);
97
+ const created = {
98
+ id,
99
+ agentId: agent.id,
100
+ ownerUserId: body.ownerUserId,
101
+ manifest: pin.manifest,
102
+ manifestHash: pin.manifestHash,
103
+ definition: { ...pin.definition },
104
+ ...(pin.loop === undefined ? {} : { loop: pin.loop }),
105
+ info: body.info,
106
+ status: "idle",
107
+ activeTurnId: null,
108
+ creation: body,
109
+ harness: pin.harness,
110
+ environmentId: agent.id,
111
+ environmentVersion: agent.version,
112
+ ...(pin.sandbox === undefined ? {} : { sandbox: pin.sandbox }),
113
+ };
114
+ await t.put("sessions", id, created);
115
+ await recordAttachment(t, id, agent.id);
116
+ return created;
225
117
  }
226
118
  /**
227
- * The manifest a session without a sandbox pins: each agent's `runtime` block, with
228
- * `read_artifact` (R2b C11) and its skill tools; nothing for a workflow.
119
+ * Refuses a session whose Agent's manifest carries a skill larger than the Agent allows now: its
120
+ * manifest's `limits.skills.totalBytes`, else the Tenant's, never above the Tenant's, which may
121
+ * have been lowered since the manifest was saved. `413 limit_exceeded`, with each skill and its
122
+ * size in `details.skills`.
229
123
  */
230
- function runtimeTools(definition) {
231
- if (isWorkflowManifest(definition.manifest))
232
- return {};
233
- const pinned = withRuntimeTools(definition.manifest);
234
- if (!pinned.ok)
235
- return fail(400, pinned.message);
236
- return { manifest: pinned.manifest, manifestHash: pinned.manifestHash };
237
- }
238
- /** The manifest a session with a sandbox pins: the definition with the sandbox in its `runtime` block. */
239
- function pin(definition, spec) {
240
- // A workflow's manifest stays as registered: its agents inherit the sandbox when they start.
241
- if (isWorkflowManifest(definition.manifest))
242
- return {};
243
- const sandboxed = withSandbox(definition.manifest, spec);
244
- if (!sandboxed.ok)
245
- return fail(400, sandboxed.message);
246
- return { manifest: sandboxed.manifest, manifestHash: sandboxed.manifestHash };
124
+ async function checkSkillLimit(t, manifest, agent) {
125
+ const limitBytes = limitsInForce(await readTenantLimits(t), agent.applied.limits).skills.totalBytes;
126
+ const { oversized } = await definitionFileIssues(t, manifest, limitBytes);
127
+ if (oversized.length === 0)
128
+ return;
129
+ fail(413, `Agent ${agent.id} allows a skill's files at most ${limitBytes} bytes together, and its manifest carries ${oversized.map((skill) => `'${skill.name}' (${skill.bytes})`).join(", ")}.`, { code: "limit_exceeded", details: { limitBytes, skills: oversized } });
247
130
  }
248
131
  /** The session resource returned by `GET`/`PUT /v1/sessions/:id`. */
249
132
  export async function sessionView(t, s) {
@@ -267,14 +150,11 @@ export async function sessionView(t, s) {
267
150
  id: s.id,
268
151
  agentId: s.agentId,
269
152
  ownerUserId: s.ownerUserId,
153
+ manifest: s.definition ?? null,
270
154
  manifestHash: s.manifestHash,
271
- ...(s.definitionHash === undefined ? {} : { definitionHash: s.definitionHash }),
272
- implementationVersion: s.implementationVersion,
273
155
  status: s.status,
274
156
  activeTurnId: s.activeTurnId,
275
- environment: s.environmentId === undefined
276
- ? null
277
- : { id: s.environmentId, version: s.environmentVersion ?? 1 },
157
+ queuedMessages: await t.countQueuedMessages(s.id),
278
158
  harness: harnessOf(s),
279
159
  ...(s.closedReason === undefined ? {} : { closedReason: s.closedReason }),
280
160
  mcpSnapshot: s.mcpSnapshot ?? null,
@@ -48,7 +48,7 @@ export declare class SigningKeys {
48
48
  /**
49
49
  * Rotates: previous → revoked, current → previous, standby → current, new standby. Refused
50
50
  * with 409 while the previous key may still verify live tokens (retired less than the
51
- * longest token lifetime, `maxTtlSeconds` or `TOKEN_TTL_MAX_SECONDS`, plus a minute ago), unless
51
+ * longest token lifetime, `maxTtlSeconds` or `keys.tokenTtlMaxSeconds`, plus a minute ago), unless
52
52
  * `force`.
53
53
  */
54
54
  rotate(t: Tx, kek: Buffer, maxTtlSeconds: number, force: boolean): Promise<SigningKeyRow[]>;
@@ -15,12 +15,10 @@
15
15
  */
16
16
  import { exportJWK, exportPKCS8, generateKeyPair, importJWK, importPKCS8, } from "jose";
17
17
  import { newSigningKeyId, SIGNING_KEY_ID_PATTERN, } from "@nylorun/core/compatibility";
18
- import { TOKEN_TTL_MAX_SECONDS } from "@nylorun/core/contracts";
19
18
  import { decryptSecret, encryptSecret } from "../vault/crypto.js";
20
19
  import { fail } from "./http.js";
20
+ import { hostTuning } from "../tuning.js";
21
21
  const ALG = "ES256";
22
- /** Grace added to the longest token lifetime before a previous key may be revoked. */
23
- const ROTATION_GRACE_MS = 60_000;
24
22
  export class SigningKeys {
25
23
  options;
26
24
  publicKeys = new Map();
@@ -107,7 +105,7 @@ export class SigningKeys {
107
105
  /**
108
106
  * Rotates: previous → revoked, current → previous, standby → current, new standby. Refused
109
107
  * with 409 while the previous key may still verify live tokens (retired less than the
110
- * longest token lifetime, `maxTtlSeconds` or `TOKEN_TTL_MAX_SECONDS`, plus a minute ago), unless
108
+ * longest token lifetime, `maxTtlSeconds` or `keys.tokenTtlMaxSeconds`, plus a minute ago), unless
111
109
  * `force`.
112
110
  */
113
111
  async rotate(t, kek, maxTtlSeconds, force) {
@@ -118,8 +116,9 @@ export class SigningKeys {
118
116
  const [previous] = await t.signingKeys(["previous"]);
119
117
  if (previous && !force) {
120
118
  const retired = Date.parse(previous.retiredAt ?? previous.createdAt);
121
- const longest = Math.max(maxTtlSeconds, TOKEN_TTL_MAX_SECONDS);
122
- const until = retired + longest * 1000 + ROTATION_GRACE_MS;
119
+ const longest = Math.max(maxTtlSeconds, hostTuning().keys.tokenTtlMaxSeconds);
120
+ // The grace added to the longest token lifetime before a previous key may be revoked.
121
+ const until = retired + longest * 1000 + hostTuning().tenant.signingKeyRotationGraceMs;
123
122
  if (until > now.getTime())
124
123
  fail(409, "The previous key may still verify live tokens", {
125
124
  code: "request_rejected",
@@ -1,11 +1,10 @@
1
1
  import { FIXTURE_MODEL_SETTING, seedFixtureModel } from "./model-setting.js";
2
2
  import { ENVIRONMENTS_CONFIG_SETTING, writeSandboxConfig } from "../sandbox/tenant-config.js";
3
+ import { hostTuning } from "../tuning.js";
3
4
  /** The Tenant's harnesses, for its status and the Host's. */
4
5
  export function harnessStatusOf(ctx) {
5
6
  return { mode: ctx.mcp ? "in-process" : "remote", ...ctx.harness.status() };
6
7
  }
7
- /** How long status waits for the execution to list stuck invocations. */
8
- const STUCK_TIMEOUT_MS = 5000;
9
8
  /** `TenantStatus.execution`: paused and backing-off invocations, or why they are unknown. */
10
9
  async function executionStatus(stuckInvocations) {
11
10
  let timer;
@@ -13,7 +12,9 @@ async function executionStatus(stuckInvocations) {
13
12
  const stuck = await Promise.race([
14
13
  stuckInvocations(),
15
14
  new Promise((_, reject) => {
16
- timer = setTimeout(() => reject(new Error("Timed out listing stuck invocations")), STUCK_TIMEOUT_MS);
15
+ timer = setTimeout(() => reject(new Error("Timed out listing stuck invocations")),
16
+ // How long status waits for the execution to list stuck invocations.
17
+ hostTuning().tenant.statusTimeoutMs);
17
18
  }),
18
19
  ]);
19
20
  return {
@@ -46,9 +47,9 @@ async function executionStatus(stuckInvocations) {
46
47
  /** Build `TenantStatusSchema` with secrets redacted (A14). */
47
48
  export async function buildTenantStatus(ctx) {
48
49
  const health = await ctx.store.health();
49
- const { counts, definitions } = await ctx.store.tx(async (t) => ({
50
+ const { counts, rows } = await ctx.store.tx(async (t) => ({
50
51
  counts: await t.counts(),
51
- definitions: await t.listDefinitions(),
52
+ rows: await t.listEnvironments(),
52
53
  }));
53
54
  const [modelView, sandboxReport, execution, streams] = await Promise.all([
54
55
  ctx.vault.getHostModel(),
@@ -56,11 +57,10 @@ export async function buildTenantStatus(ctx) {
56
57
  ctx.stuckInvocations ? executionStatus(ctx.stuckInvocations) : undefined,
57
58
  ctx.streamsStatus?.(),
58
59
  ]);
59
- const agents = [
60
- ...new Set(definitions
61
- .map((d) => d.manifest?.id)
62
- .filter((id) => typeof id === "string")),
63
- ]
60
+ // The Tenant's Agents; a pod Agent being deleted is none.
61
+ const agents = rows
62
+ .filter((row) => row.pod?.desired !== "deleted")
63
+ .map((row) => row.id)
64
64
  .sort()
65
65
  .map((agentId) => ({ agentId }));
66
66
  return {
@@ -1,17 +1,16 @@
1
1
  import { basinOf } from "../streams/basin.js";
2
2
  import { createStreamRelay, } from "../streams/relay/core.js";
3
3
  import { retry } from "../retry.js";
4
+ import { hostTuning } from "../tuning.js";
4
5
  import { checkSessionStreams, currentBasin } from "./session-streams.js";
5
- const RETRY_MIN_MS = 100;
6
- const RETRY_MAX_MS = 2000;
7
- /** The longest wait between two `ensureTenant` attempts while the basin is being repaired. */
8
- const BASIN_RETRY_MAX_MS = 5000;
9
- /** A repair started within this long after the last one succeeded waits for the next failure. */
10
- const BASIN_REPAIR_COOLDOWN_MS = 1000;
11
- /** How often every session stream is checked against its session (backstop for lost signals). */
12
- const FEED_CHECK_MS = 30_000;
13
- /** How long a retired basin stays for readers that have not moved yet. */
14
- const RETIRE_GRACE_MS = 60_000;
6
+ /*
7
+ * Timings are the Host tuning's `streams` group (`tuning.ts`): `retry` for deletions and
8
+ * repairs, `basinRetryMaxMs` (the longest wait between two `ensureTenant` attempts while the
9
+ * basin is being repaired), `basinRepairCooldownMs` (a repair started within this long after the
10
+ * last one succeeded waits for the next failure), `feedCheckMs` (how often every session stream is
11
+ * checked against its session, the backstop for lost signals), `retireGraceMs` (how long a retired
12
+ * basin stays for readers that have not moved yet).
13
+ */
15
14
  const messageOf = (error) => error instanceof Error ? error.message : String(error);
16
15
  /**
17
16
  * Wires the Tenant to Durable Streams: reads its basin generation, checks the basin, starts
@@ -25,7 +24,7 @@ export async function wireStreams(ctx, options) {
25
24
  const { store, streams, tenantId } = options;
26
25
  const logger = ctx.config.logger;
27
26
  const stop = new AbortController();
28
- const graceMs = options.retireGraceMs ?? RETIRE_GRACE_MS;
27
+ const graceMs = options.retireGraceMs ?? hostTuning().streams.retireGraceMs;
29
28
  // Nothing is reported once the wiring stops: the Tenant (and its log directory) may be gone,
30
29
  // and a throwing report in a detached loop would be an unhandled rejection.
31
30
  const report = (what) => (error) => {
@@ -53,7 +52,7 @@ export async function wireStreams(ctx, options) {
53
52
  });
54
53
  relay?.start();
55
54
  // Streams whose session was reset end on the `sessions.reset` signal; this catches lost ones.
56
- const feedCheck = setInterval(() => void checkSessionStreams(ctx).catch(report("session stream check failed")), FEED_CHECK_MS);
55
+ const feedCheck = setInterval(() => void checkSessionStreams(ctx).catch(report("session stream check failed")), hostTuning().streams.feedCheckMs);
57
56
  feedCheck.unref();
58
57
  const retiring = new Set();
59
58
  const timers = new Set();
@@ -94,9 +93,8 @@ export async function wireStreams(ctx, options) {
94
93
  async function deleteRetired(generation) {
95
94
  try {
96
95
  await retry(() => streams.deleteTenant(basinOf(tenantId, generation)), {
97
- minMs: RETRY_MIN_MS,
98
- maxMs: RETRY_MAX_MS,
99
- attempts: 5,
96
+ ...hostTuning().streams.retry,
97
+ attempts: hostTuning().streams.retireAttempts,
100
98
  });
101
99
  await store.tx((t) => t.forgetRetiredGeneration(generation));
102
100
  logger.info("retired stream basin deleted", { generation });
@@ -160,7 +158,7 @@ export async function streamsStatus(ctx, options = {}) {
160
158
  const wiring = ctx.sessionStreams.wiring;
161
159
  return {
162
160
  reachable: wiring
163
- ? await probe(wiring.streams, options.probeTimeoutMs ?? 2000)
161
+ ? await probe(wiring.streams, options.probeTimeoutMs ?? hostTuning().streams.probeTimeoutMs)
164
162
  : false,
165
163
  basin: wiring?.basin() ?? { ready: false, failures: 0, lastError: null },
166
164
  generation: ctx.sessionStreams.generation,
@@ -215,17 +213,17 @@ function basinKeeper(streams, basinKey, signal, onError) {
215
213
  repair() {
216
214
  if (repairing || signal.aborted)
217
215
  return;
218
- if (ready && readyFor === basinKey() && Date.now() - repairedAt < BASIN_REPAIR_COOLDOWN_MS)
216
+ if (ready && readyFor === basinKey() && Date.now() - repairedAt < hostTuning().streams.basinRepairCooldownMs)
219
217
  return;
220
218
  repairing = true;
221
219
  ready = false;
222
220
  void (async () => {
223
221
  await retry(ensure, {
224
- minMs: RETRY_MIN_MS,
225
- maxMs: BASIN_RETRY_MAX_MS,
222
+ minMs: hostTuning().streams.retry.minMs,
223
+ maxMs: hostTuning().streams.basinRetryMaxMs,
226
224
  signal,
227
225
  onError: (error) => {
228
- if (failures === 1 || failures % 10 === 0)
226
+ if (failures === 1 || failures % hostTuning().streams.basinLogEveryFailures === 0)
229
227
  onError(error);
230
228
  },
231
229
  }).then(() => (repairedAt = Date.now()), () => undefined);
@@ -1,32 +1,12 @@
1
1
  import type { PendingRequest } from "../store/types.js";
2
2
  import type { TenantContext } from "./context.js";
3
- /**
4
- * How old an outbox row is before the sweep delivers it, unless its delivery after commit
5
- * already failed (then it is due at once): longer than that delivery can take with its
6
- * retries, so the sweep does not send again, and double the load on, an execution that is
7
- * only slow. Sending one twice is harmless either way (the idempotency key).
8
- */
9
- export declare const OUTBOX_GRACE_MS = 30000;
10
- /**
11
- * How often the orphan scan, and the stale pod sandbox check, run after the first pass of a
12
- * Tenant opened on this process.
13
- */
14
- export declare const ORPHAN_SCAN_MS = 60000;
15
- /**
16
- * How long one pass may spend draining the outbox, and paging through orphaned sessions.
17
- * A backlog is worked off over several passes rather than holding one (and with it the
18
- * Tenant's sweep object in the execution) for long.
19
- */
20
- export declare const DRAIN_BUDGET_MS = 2000;
21
3
  export declare function sweep(ctx: TenantContext): Promise<void>;
22
- /** Failed deliveries after which the sweep parks an outbox row (`Tx.failOutbox`). */
23
- export declare const MAX_OUTBOX_ATTEMPTS = 10;
24
4
  /**
25
5
  * Deliver the outbox rows that are due (`Tx.pendingOutbox`: older than `graceMs`, or whose
26
6
  * delivery failed), oldest first, batch after batch until none is left or `budgetMs` is
27
7
  * spent, and delete the delivered ones. Each row is delivered on its own: one that fails
28
8
  * (Restate refuses it, or a Runtime that does not know a wake's reason) is tried again later,
29
- * with backoff, so it never holds back the rows behind it, and after `MAX_OUTBOX_ATTEMPTS`
9
+ * with backoff, so it never holds back the rows behind it, and after `sweep.outboxAttempts`
30
10
  * failures it is parked: logged once, at error, and kept in the outbox for an operator. A
31
11
  * parked wake's session is still re-woken by the orphan scan while it is runnable, and a
32
12
  * parked sandbox signal's pod by the stale pod check. A row the Tenant declines (it is