@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
@@ -7,7 +7,7 @@
7
7
  import { mkdirSync, readdirSync, rmSync } from "node:fs";
8
8
  import { join, posix } from "node:path";
9
9
  import { SANDBOX_WORKSPACE } from "@nylorun/core/define";
10
- import { SandboxFileTooLargeError } from "../../sandbox/types.js";
10
+ import { SandboxFileTooLargeError, wholeBytes } from "../../sandbox/types.js";
11
11
  const ENV = Object.freeze({
12
12
  PATH: "/usr/local/bin:/usr/bin:/bin",
13
13
  HOME: SANDBOX_WORKSPACE,
@@ -143,7 +143,7 @@ export function virtualBackend(options) {
143
143
  return { entries, truncated: !complete };
144
144
  },
145
145
  async writeFile(path, content) {
146
- await (typeof content === "string" ? fs.writeFile(path, content, "utf8") : fs.writeFile(path, content));
146
+ await (typeof content === "string" ? fs.writeFile(path, content, "utf8") : fs.writeFile(path, await wholeBytes(content)));
147
147
  },
148
148
  async stop() { },
149
149
  };
@@ -11,7 +11,7 @@ export interface S2StreamsOptions {
11
11
  basinPrefix?: string;
12
12
  /**
13
13
  * How long `ensureTenant` waits for a previous deletion of the same basin to
14
- * finish. Defaults to two minutes.
14
+ * finish. Default `streams.s2BasinDeletionWaitMs` (Host tuning, two minutes).
15
15
  */
16
16
  basinDeletionWaitMs?: number;
17
17
  }
@@ -59,13 +59,14 @@
59
59
  import { AppendInput, AppendRecord, RangeNotSatisfiableError, S2, S2Error, SeqNumMismatchError, } from "@s2-dev/streamstore";
60
60
  import { parseBasin, tenantBasinName, validateBasinPrefix } from "../../streams/basin.js";
61
61
  import { sleep } from "../../retry.js";
62
+ import { hostTuning, S2_BATCH_MAX_RECORDS } from "../../tuning.js";
62
63
  import {} from "../../streams/types.js";
63
- /** Records per unary read while reading history. */
64
- const HISTORY_PAGE = 1000;
65
- const RETRY_MIN_MS = 100;
66
- const RETRY_MAX_MS = 2000;
67
- /** Attempts for an append that loses a `transaction_conflict` race. */
68
- const CONFLICT_ATTEMPTS = 6;
64
+ /**
65
+ * Records per unary read while reading history: the most one S2 read returns. Retries are the Host
66
+ * tuning's `streams.s2Retry`, `s2ConflictAttempts` (an append that loses a `transaction_conflict`
67
+ * race), `s2ConflictRetryMs` and `s2BasinRetryMs`.
68
+ */
69
+ const HISTORY_PAGE = S2_BATCH_MAX_RECORDS;
69
70
  export function createS2Streams(options = {}) {
70
71
  return new S2Streams(options);
71
72
  }
@@ -77,7 +78,7 @@ class S2Streams {
77
78
  closing = new AbortController();
78
79
  constructor(options) {
79
80
  this.prefix = validateBasinPrefix(options.basinPrefix ?? "");
80
- this.deletionWaitMs = options.basinDeletionWaitMs ?? 120_000;
81
+ this.deletionWaitMs = options.basinDeletionWaitMs ?? hostTuning().streams.s2BasinDeletionWaitMs;
81
82
  this.s2 = new S2({
82
83
  accessToken: options.token ?? "s2-lite",
83
84
  ...(options.endpoint
@@ -99,7 +100,8 @@ class S2Streams {
99
100
  ...(options.matchSeq !== undefined ? { matchSeqNum: options.matchSeq } : {}),
100
101
  });
101
102
  const handle = this.handle(tenantId, stream);
102
- let delay = RETRY_MIN_MS / 4;
103
+ const { s2ConflictRetryMs, s2ConflictAttempts } = hostTuning().streams;
104
+ let delay = s2ConflictRetryMs;
103
105
  for (let attempt = 1;; attempt += 1) {
104
106
  try {
105
107
  const ack = await handle.append(input, { signal: this.closing.signal });
@@ -110,7 +112,7 @@ class S2Streams {
110
112
  return { status: "seq_mismatch", tail: error.expectedSeqNum };
111
113
  // Concurrent appends to one stream can abort each other; the aborted
112
114
  // one wrote nothing, so it is retried.
113
- if (!isTransactionConflict(error) || attempt >= CONFLICT_ATTEMPTS)
115
+ if (!isTransactionConflict(error) || attempt >= s2ConflictAttempts)
114
116
  throw error;
115
117
  await sleep(delay * (1 + Math.random()), this.closing.signal);
116
118
  this.checkOpen();
@@ -143,7 +145,8 @@ class S2Streams {
143
145
  this.checkOpen();
144
146
  const basin = this.basinName(tenantId);
145
147
  const deadline = Date.now() + this.deletionWaitMs;
146
- let delay = RETRY_MIN_MS * 5;
148
+ const tuning = hostTuning().streams;
149
+ let delay = tuning.s2BasinRetryMs;
147
150
  for (;;) {
148
151
  try {
149
152
  await this.s2.basins.ensure({
@@ -165,7 +168,7 @@ class S2Streams {
165
168
  throw error;
166
169
  await sleep(delay, this.closing.signal);
167
170
  this.checkOpen();
168
- delay = Math.min(delay * 2, RETRY_MAX_MS);
171
+ delay = Math.min(delay * 2, tuning.s2Retry.maxMs);
169
172
  }
170
173
  }
171
174
  }
@@ -271,7 +274,8 @@ class S2Streams {
271
274
  const aborted = anySignal(signal, this.closing.signal);
272
275
  const handle = this.handle(tenantId, stream);
273
276
  let next = fromSeq;
274
- let delay = RETRY_MIN_MS;
277
+ const { minMs: retryMinMs, maxMs: retryMaxMs } = hostTuning().streams.s2Retry;
278
+ let delay = retryMinMs;
275
279
  try {
276
280
  while (!aborted.aborted) {
277
281
  try {
@@ -283,7 +287,7 @@ class S2Streams {
283
287
  if (record.seqNum < next)
284
288
  continue;
285
289
  next = record.seqNum + 1;
286
- delay = RETRY_MIN_MS;
290
+ delay = retryMinMs;
287
291
  yield toRecord(record);
288
292
  if (aborted.aborted)
289
293
  return;
@@ -300,7 +304,7 @@ class S2Streams {
300
304
  // S2 unreachable, or a stream being deleted: retry below.
301
305
  }
302
306
  await sleep(delay, aborted);
303
- delay = Math.min(delay * 2, RETRY_MAX_MS);
307
+ delay = Math.min(delay * 2, retryMaxMs);
304
308
  }
305
309
  }
306
310
  finally {
@@ -1,6 +1,6 @@
1
1
  /**
2
- * The Agent Card of one agent, from its manifest: name, description and one skill, never its
3
- * instructions, tools or MCP servers. The Runtime does not know where callers reach it, so
2
+ * The Agent Card of one Agent, from its manifest version: its id as the name, the manifest's
3
+ * description and one skill, never its instructions, tools or MCP servers. The Runtime does not know where callers reach it, so
4
4
  * `supportedInterfaces` is empty: whoever publishes the card (the gateway in v1) adds its own
5
5
  * URL, provider and security schemes.
6
6
  */
@@ -10,7 +10,8 @@ export interface CardDefinition {
10
10
  name?: unknown;
11
11
  description?: unknown;
12
12
  };
13
- readonly implementationVersion: string;
13
+ /** The manifest version the Agent runs, as `name@version`. */
14
+ readonly version: string;
14
15
  }
15
16
  import type { ModelInput } from "@nylorun/core/contracts";
16
17
  /**
@@ -1,10 +1,10 @@
1
1
  /**
2
- * The Agent Card of one agent, from its manifest: name, description and one skill, never its
3
- * instructions, tools or MCP servers. The Runtime does not know where callers reach it, so
2
+ * The Agent Card of one Agent, from its manifest version: its id as the name, the manifest's
3
+ * description and one skill, never its instructions, tools or MCP servers. The Runtime does not know where callers reach it, so
4
4
  * `supportedInterfaces` is empty: whoever publishes the card (the gateway in v1) adds its own
5
5
  * URL, provider and security schemes.
6
6
  */
7
- import { MODEL_IMAGE_TYPES } from "../../artifacts/media-types.js";
7
+ import { MODEL_IMAGE_TYPES } from "@nylorun/core/contracts";
8
8
  const MODES = ["text/plain", "application/json"];
9
9
  /** The media types a card advertises for each file input a model reads. */
10
10
  const INPUT_MODES = {
@@ -39,7 +39,7 @@ export function agentCard(agentId, definition, inputModes = MODES) {
39
39
  name,
40
40
  description,
41
41
  supportedInterfaces: [],
42
- version: definition.implementationVersion,
42
+ version: definition.version,
43
43
  capabilities: { streaming: false, pushNotifications: false, extendedAgentCard: false },
44
44
  defaultInputModes: [...inputModes],
45
45
  defaultOutputModes: MODES,
@@ -1,6 +1,5 @@
1
1
  import { z } from "zod";
2
- import { readText } from "../http/body.js";
3
- import { INLINE_BODY_MAX_BYTES } from "../inbound-files.js";
2
+ import { bodyLimit, readText } from "../http/body.js";
4
3
  import { TraceHeaders, tenantRoute } from "../http/define.js";
5
4
  import { traceContextOf } from "../../traces/ids.js";
6
5
  import { jsonResponse } from "../http/respond.js";
@@ -57,7 +56,7 @@ export function a2aRoutes(api) {
57
56
  path: "/v1/a2a/agents/{agentId}",
58
57
  tags: TAGS,
59
58
  summary: "Call an agent over A2A",
60
- description: "A2A 1.0 JSON-RPC, for a subject: `SendMessage` (blocking up to 5 minutes, or `returnImmediately`), `GetTask` and `CancelTask`. A message is text, one data part, or text and `raw` files (at most 20 MiB each, stored as artifacts of the context's session); a file `url` is `ContentTypeNotSupportedError`. A context is one session per subject, agent and `contextId`; a task is one turn. JSON-RPC errors are answered with 200; limits, scopes and unavailable streams stay HTTP errors.",
59
+ description: "A2A 1.0 JSON-RPC, for a subject: `SendMessage` (blocking up to the Runtime limit `a2aWaitMs`, 5 minutes by default, or `returnImmediately`), `GetTask` and `CancelTask`. A message is text, one data part, or text and `raw` files (at most the Runtime limit `inlineFileBytes` each, 20 MiB by default, stored as artifacts of the context's session); a file `url` is `ContentTypeNotSupportedError`. A context is one session per subject, agent and `contextId`; a task is one turn. JSON-RPC errors are answered with 200; limits, scopes and unavailable streams stay HTTP errors.",
61
60
  externalDocs: A2A_SPECIFICATION,
62
61
  request: {
63
62
  params: agentId,
@@ -79,7 +78,7 @@ export function a2aRoutes(api) {
79
78
  const trace = traceContextOf(c.req.raw.headers);
80
79
  return jsonResponse(200, await a2aCall(c.env.tenant, scope, c.req.param("agentId"), {
81
80
  // A message may carry files inline.
82
- body: () => readText(c.req.raw, INLINE_BODY_MAX_BYTES),
81
+ body: async () => readText(c.req.raw, await bodyLimit(c.env.tenant, "inline")),
83
82
  version: typeof version === "string" ? version : (c.req.query("A2A-Version") ?? null),
84
83
  ...(trace ? { trace } : {}),
85
84
  }, c.env.outgoing));
@@ -109,6 +109,10 @@ export function checkVersion(value) {
109
109
  if (`${major}.${minor}` !== A2A_VERSION)
110
110
  a2aFail("versionNotSupported", `A2A version ${trimmed === "" ? "0.3" : trimmed} is not supported; send A2A-Version: ${A2A_VERSION}`, { supportedVersions: A2A_VERSION });
111
111
  }
112
+ /**
113
+ * At most 200 characters: an identifier's grammar is the protocol's (B15), the same in every
114
+ * installation, so its length is a constant, not a setting.
115
+ */
112
116
  const MAX_ID = 200;
113
117
  const VISIBLE = /^[\x21-\x7e]+$/;
114
118
  function checkId(value, field, required) {
@@ -1,14 +1,10 @@
1
1
  import type { ServerResponse } from "node:http";
2
2
  import { type AuthScope, type TenantContext } from "../../tenant/context.js";
3
3
  import type { TraceContext } from "../../traces/ids.js";
4
- /**
5
- * How long a blocking `SendMessage` waits for the task to end or ask for input. After it, the
6
- * task is returned `WORKING` and keeps running; the caller polls `GetTask`.
7
- */
8
- export declare const A2A_BLOCKING_WAIT_MS: number;
9
4
  /**
10
5
  * `GET /v1/a2a/agents/:agent/card`: the agent's card, for a caller who may use the agent. Its
11
- * input modes name the files the Tenant's model reads.
6
+ * input modes name the files the Tenant's model reads natively: a hint, since any file is
7
+ * accepted and the agent's harness decides how its model sees it (protocol 15).
12
8
  */
13
9
  export declare function a2aCard(ctx: TenantContext, scope: AuthScope, agentId: string): Promise<unknown>;
14
10
  /**
@@ -17,31 +17,29 @@
17
17
  import { randomUUID } from "node:crypto";
18
18
  import { SessionCommandSchema, } from "@nylorun/core/contracts";
19
19
  import { commandKey } from "../../core/flow-host.js";
20
- import { contentTypeFor } from "../../artifacts/media-types.js";
20
+ import { contentTypeFor } from "@nylorun/core/contracts";
21
21
  import { discardFiles, inlineFileName, messageParts, } from "../inbound-files.js";
22
22
  import { agentCard, inputModesFor } from "./card.js";
23
23
  import { A2aError, a2aFail, checkVersion, jsonRpcError, jsonRpcResult, parseEnvelope, parseSendParams, parseTaskParams, } from "./protocol.js";
24
24
  import { SETTLED_EVENTS, buildTask, contextSessionId, newContextId, parseTaskId, pendingInteraction, taskIdOf, } from "./tasks.js";
25
- import { currentModelInputs } from "../../model/catalog.js";
25
+ import { currentModelDescriptor } from "../../model/descriptor.js";
26
26
  import { accessOf } from "../../tenant/auth.js";
27
27
  import { command } from "../../tenant/commands.js";
28
- import { loadSession, } from "../../tenant/context.js";
28
+ import { loadSession, reachesAgent, } from "../../tenant/context.js";
29
+ import { agentGrantsOf, liveEnvironment } from "../../tenant/agents.js";
29
30
  import { HttpError, fail } from "../../tenant/http.js";
30
31
  import { observeSession, readHistory } from "../../tenant/session-streams.js";
31
32
  import { putSession } from "../../tenant/sessions.js";
32
- /**
33
- * How long a blocking `SendMessage` waits for the task to end or ask for input. After it, the
34
- * task is returned `WORKING` and keeps running; the caller polls `GetTask`.
35
- */
36
- export const A2A_BLOCKING_WAIT_MS = 5 * 60_000;
33
+ import { readRuntimeLimits } from "../../tenant/runtime-limits.js";
37
34
  /**
38
35
  * `GET /v1/a2a/agents/:agent/card`: the agent's card, for a caller who may use the agent. Its
39
- * input modes name the files the Tenant's model reads.
36
+ * input modes name the files the Tenant's model reads natively: a hint, since any file is
37
+ * accepted and the agent's harness decides how its model sees it (protocol 15).
40
38
  */
41
39
  export async function a2aCard(ctx, scope, agentId) {
42
40
  const definition = await definitionFor(ctx, agentId, accessOf(scope));
43
- // The files a caller may send: those the Tenant's model reads now.
44
- return agentCard(agentId, definition, inputModesFor(await currentModelInputs(ctx)));
41
+ // The files the Tenant's model reads now.
42
+ return agentCard(agentId, definition, inputModesFor((await currentModelDescriptor(ctx))?.inputs));
45
43
  }
46
44
  /**
47
45
  * `POST /v1/a2a/agents/:agent`: one A2A JSON-RPC call, for a subject. JSON-RPC answers (errors
@@ -108,12 +106,22 @@ async function operation(caller, request, signal) {
108
106
  return a2aFail("methodNotFound", `Method ${request.method} not found`);
109
107
  }
110
108
  }
111
- /** The agent's definition, or a `404` when it is missing or the caller may not use it. */
109
+ /**
110
+ * What the card of Agent `agentId` says (the manifest version it runs), or a `404` when it is
111
+ * missing or the caller may not use it. Every caller's session runs on that Agent, with its disk
112
+ * and vault (D66, D70): an app that serves several audiences makes an Agent for each.
113
+ */
112
114
  async function definitionFor(ctx, agentId, access) {
113
- if (access?.agents !== undefined && !access.agents.has(agentId))
115
+ if (!reachesAgent(access, agentId))
114
116
  return fail(404, "Agent not found");
115
- const definition = await ctx.store.tx((t) => t.get("definitions", agentId));
116
- return definition ?? fail(404, "Agent not found");
117
+ return ctx.store.tx(async (t) => {
118
+ const agent = (await liveEnvironment(t, agentId)) ?? fail(404, "Agent not found");
119
+ const version = await t.agentManifest(agent.manifestName, agent.manifestVersion);
120
+ return {
121
+ manifest: { id: agentId, ...(version?.body.description === undefined ? {} : { description: version.body.description }) },
122
+ version: `${agent.manifestName}@${agent.manifestVersion}`,
123
+ };
124
+ });
117
125
  }
118
126
  const taskNotFound = (taskId) => a2aFail("taskNotFound", "Task not found", { taskId });
119
127
  /** The caller's session for a context, or undefined when it does not exist yet. */
@@ -155,11 +163,6 @@ conflict) {
155
163
  catch (error) {
156
164
  if (!(error instanceof HttpError))
157
165
  throw error;
158
- // A file the agent's model does not read (`attachment_unsupported`).
159
- if (error.status === 422)
160
- return a2aFail("contentTypeNotSupported", error.message, {
161
- reason: error.rejection.code ?? "request_rejected",
162
- });
163
166
  if (error.status !== 409)
164
167
  throw error;
165
168
  if (error.message.startsWith("Idempotency key"))
@@ -174,9 +177,9 @@ async function openContext(caller, sessionId) {
174
177
  return existing;
175
178
  return putSession(caller.ctx, sessionId, {
176
179
  requestId: randomUUID(),
177
- agentId: caller.agentId,
180
+ agent: caller.agentId,
178
181
  ownerUserId: caller.access.owner,
179
- }, caller.access);
182
+ }, caller.access, agentGrantsOf(caller.scope) === undefined ? {} : { agentGrants: agentGrantsOf(caller.scope) });
180
183
  }
181
184
  async function sendMessage(caller, params, signal) {
182
185
  const send = parseSendParams(params);
@@ -320,14 +323,16 @@ async function cancelTask(caller, taskId) {
320
323
  return (await ownedTask(caller, taskId)).task;
321
324
  }
322
325
  /**
323
- * Waits until the turn ends, pauses or has an uncertain effect, the caller hangs up, or
324
- * `A2A_BLOCKING_WAIT_MS` passes. Follows the session's shared stream from the command's
326
+ * Waits until the turn ends, pauses or has an uncertain effect, the caller hangs up, or the
327
+ * Tenant's Runtime limit `a2aWaitMs` passes: after it, the task is returned `WORKING` and keeps
328
+ * running, and the caller polls `GetTask`. Follows the session's shared stream from the command's
325
329
  * cursor, so the events the task is built from are there when it returns. A feed that ends
326
330
  * (reset, deleted, closing) ends the wait: the task says what the session says then.
327
331
  */
328
332
  async function settled(ctx, sessionId, turnId, cursor, signal) {
329
333
  const stop = new AbortController();
330
- const timer = setTimeout(() => stop.abort(), A2A_BLOCKING_WAIT_MS);
334
+ const { a2aWaitMs } = await ctx.store.tx((t) => readRuntimeLimits(t));
335
+ const timer = setTimeout(() => stop.abort(), a2aWaitMs);
331
336
  timer.unref();
332
337
  const hangup = () => stop.abort();
333
338
  signal.addEventListener("abort", hangup, { once: true });
@@ -2,7 +2,6 @@ import { RESPONSE_ALREADY_SENT } from "@hono/node-server/utils/response";
2
2
  import { z } from "zod";
3
3
  import { EventSchemas, MessageSchema, RunAgentInputSchema } from "@ag-ui/core/schemas";
4
4
  import { readJson } from "../http/body.js";
5
- import { INLINE_BODY_MAX_BYTES } from "../inbound-files.js";
6
5
  import { TraceHeaders, tenantRoute } from "../http/define.js";
7
6
  import { traceContextOf } from "../../traces/ids.js";
8
7
  import { jsonResponse } from "../http/respond.js";
@@ -51,7 +50,7 @@ export function agUiRoutes(api) {
51
50
  path: "/v1/ag-ui/agents/{agentId}",
52
51
  tags: TAGS,
53
52
  summary: "Run an agent",
54
- description: "For a person, named by a trusted issuer's token or by `Nylorun-Subject`. The thread is one session per person, agent and thread, created on its first run with `forwardedProps.nylorun.session`. The trailing user message starts a turn (its id is the idempotency key); its media parts are files: bytes sent inline (`data`, at most 20 MiB each) are stored as artifacts of the session, a `file` source with provider `nylorun` names an artifact, and a URL is refused. `resume` answers interrupts. A busy session, or a file the model does not read, is a `RUN_ERROR` in the stream.",
53
+ description: "For a person, named by a trusted issuer's token or by `Nylorun-Subject`. The thread is one session per person, agent and thread, created on its first run with `forwardedProps.nylorun.session`. The trailing user message starts a turn (its id is the idempotency key); its media parts are files: bytes sent inline (`data`, at most 20 MiB each) are stored as artifacts of the session, a `file` source with provider `nylorun` names an artifact, and a URL is refused. `resume` answers interrupts. A busy session is a `RUN_ERROR` in the stream; any file type is accepted, and the agent's harness decides how its model sees it.",
55
54
  request: {
56
55
  params: agentId,
57
56
  body: {
@@ -65,7 +64,7 @@ export function agUiRoutes(api) {
65
64
  const { scope, subject, access } = callerOf(c);
66
65
  await startRun(c.env.tenant, scope, c.req.param("agentId"), { subject, access },
67
66
  // A message may carry files inline.
68
- await readJson(c.req.raw, INLINE_BODY_MAX_BYTES), c.env.outgoing, traceContextOf(c.req.raw.headers));
67
+ await readJson(c, "inline"), c.env.outgoing, traceContextOf(c.req.raw.headers));
69
68
  return RESPONSE_ALREADY_SENT;
70
69
  });
71
70
  tenantRoute(api, FOR_A_PERSON, {
@@ -13,8 +13,8 @@
13
13
  *
14
14
  * Each thread maps to one session per subject, agent and thread. The message id is the
15
15
  * idempotency key, a message's media parts become file parts (bytes sent inline are stored as
16
- * artifacts of the session, `../inbound-files.ts`; a file the model does not read is a
17
- * `RUN_ERROR`), approvals become interrupts resumed through `resume`, and the last AG-UI
16
+ * artifacts of the session, `../inbound-files.ts`; any type goes, and the harness decides how
17
+ * the model sees it), approvals become interrupts resumed through `resume`, and the last AG-UI
18
18
  * event made from each Runtime event carries its cursor as the SSE id. A run's session is
19
19
  * created on its first run with the options in `forwardedProps.nylorun.session` and never
20
20
  * changed afterwards. A stream opened with an issuer token ends at the token's expiry with
@@ -36,8 +36,8 @@ import { fail, HttpError } from "../../tenant/http.js";
36
36
  import { observeSession, readHistory, StreamClosed, streamHolderOf, } from "../../tenant/session-streams.js";
37
37
  import { putSession, sessionView } from "../../tenant/sessions.js";
38
38
  import { mayUseAgent } from "../../tenant/auth.js";
39
- import { environmentGrantsOf } from "../../tenant/environments.js";
40
- const HEARTBEAT_MS = 15_000;
39
+ import { agentGrantsOf } from "../../tenant/agents.js";
40
+ import { hostTuning } from "../../tuning.js";
41
41
  const TERMINAL = new Set([
42
42
  "turn.completed",
43
43
  "turn.paused",
@@ -111,10 +111,7 @@ function sessionOptions(input, scope) {
111
111
  ?.nylorun?.session;
112
112
  if (raw === undefined)
113
113
  return {};
114
- const parsed = PutSessionRequestSchema.pick({
115
- info: true,
116
- environment: true,
117
- })
114
+ const parsed = PutSessionRequestSchema.pick({ info: true })
118
115
  .strict()
119
116
  .safeParse(raw);
120
117
  if (!parsed.success)
@@ -203,7 +200,7 @@ async function stream(response, translator, source, preface = []) {
203
200
  if (!response.writableEnded && !response.write(text))
204
201
  response.destroy();
205
202
  };
206
- const heartbeat = setInterval(() => write(SSE_HEARTBEAT), HEARTBEAT_MS);
203
+ const heartbeat = setInterval(() => write(SSE_HEARTBEAT), hostTuning().api.agUiHeartbeatMs);
207
204
  heartbeat.unref();
208
205
  try {
209
206
  write(sseFrame(translator.started()));
@@ -282,12 +279,12 @@ trace) {
282
279
  const id = sessionIdFor(caller.subject, agentId, input.threadId);
283
280
  await putSession(ctx, id, {
284
281
  requestId: randomUUID(),
285
- agentId,
282
+ agent: agentId,
286
283
  ownerUserId: caller.subject,
287
284
  ...sessionOptions(input, scope),
288
285
  }, caller.access, {
289
286
  createOnly: true,
290
- ...(environmentGrantsOf(scope) === undefined ? {} : { environmentGrants: environmentGrantsOf(scope) }),
287
+ ...(agentGrantsOf(scope) === undefined ? {} : { agentGrants: agentGrantsOf(scope) }),
291
288
  });
292
289
  const translator = new RunTranslator(input.threadId, input.runId);
293
290
  let cursor;