@nylorun/runtime 0.25.0-beta → 0.27.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 (326) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +26 -16
  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.js +1 -1
  12. package/dist/api/a2a/endpoint.js +3 -4
  13. package/dist/api/a2a/protocol.js +4 -0
  14. package/dist/api/a2a/routes.d.ts +2 -6
  15. package/dist/api/a2a/routes.js +12 -18
  16. package/dist/api/ag-ui/endpoint.js +2 -3
  17. package/dist/api/ag-ui/routes.js +4 -4
  18. package/dist/api/components.d.ts +326 -45
  19. package/dist/api/components.js +5 -1
  20. package/dist/api/gate/keys.js +7 -4
  21. package/dist/api/gate/routes.d.ts +6 -2
  22. package/dist/api/gate/routes.js +15 -11
  23. package/dist/api/http/app.d.ts +2 -2
  24. package/dist/api/http/app.js +2 -2
  25. package/dist/api/http/body.d.ts +15 -3
  26. package/dist/api/http/body.js +15 -7
  27. package/dist/api/http/define.d.ts +1 -1
  28. package/dist/api/http/respond.js +7 -3
  29. package/dist/api/http/routes/access.js +5 -4
  30. package/dist/api/http/routes/artifacts.js +19 -7
  31. package/dist/api/http/routes/coverage.js +1 -1
  32. package/dist/api/http/routes/environment-manifests.js +1 -1
  33. package/dist/api/http/routes/environments.js +6 -6
  34. package/dist/api/http/routes/files.d.ts +2 -1
  35. package/dist/api/http/routes/files.js +31 -5
  36. package/dist/api/http/routes/mcp.js +1 -1
  37. package/dist/api/http/routes/reads.d.ts +35 -0
  38. package/dist/api/http/routes/reads.js +50 -22
  39. package/dist/api/http/routes/sessions.js +12 -11
  40. package/dist/api/http/routes/tenant.d.ts +2 -2
  41. package/dist/api/http/routes/tenant.js +69 -16
  42. package/dist/api/inbound-files.d.ts +3 -9
  43. package/dist/api/inbound-files.js +18 -24
  44. package/dist/api/openapi.js +6 -2
  45. package/dist/artifacts/disk.d.ts +0 -4
  46. package/dist/artifacts/disk.js +77 -73
  47. package/dist/artifacts/files.d.ts +13 -4
  48. package/dist/artifacts/files.js +27 -9
  49. package/dist/artifacts/folder-upload.d.ts +75 -0
  50. package/dist/artifacts/folder-upload.js +263 -0
  51. package/dist/artifacts/folders.d.ts +14 -8
  52. package/dist/artifacts/folders.js +19 -11
  53. package/dist/artifacts/links.js +7 -6
  54. package/dist/artifacts/parts.d.ts +9 -14
  55. package/dist/artifacts/parts.js +11 -9
  56. package/dist/artifacts/pipe.d.ts +15 -0
  57. package/dist/artifacts/pipe.js +71 -0
  58. package/dist/artifacts/quota.d.ts +36 -0
  59. package/dist/artifacts/quota.js +44 -0
  60. package/dist/artifacts/service.d.ts +25 -1
  61. package/dist/artifacts/service.js +70 -25
  62. package/dist/blob/fs.js +2 -1
  63. package/dist/blob/s3.d.ts +6 -2
  64. package/dist/blob/s3.js +9 -7
  65. package/dist/blob/types.d.ts +1 -1
  66. package/dist/blob/types.js +1 -1
  67. package/dist/core/limits.d.ts +11 -35
  68. package/dist/core/limits.js +5 -73
  69. package/dist/core/sandbox-routes.js +0 -1
  70. package/dist/core/turn-manifest.d.ts +1 -2
  71. package/dist/core/turn-manifest.js +4 -28
  72. package/dist/execution/memory.d.ts +8 -5
  73. package/dist/execution/memory.js +8 -6
  74. package/dist/execution/types.d.ts +1 -6
  75. package/dist/execution/types.js +0 -5
  76. package/dist/gates/contract.d.ts +3 -2
  77. package/dist/gates/contract.js +1 -1
  78. package/dist/gates/egress-credentials.js +4 -3
  79. package/dist/gates/egress.d.ts +9 -9
  80. package/dist/gates/egress.js +19 -19
  81. package/dist/gates/fixture-model.js +13 -2
  82. package/dist/gates/handler.d.ts +1 -3
  83. package/dist/gates/handler.js +4 -3
  84. package/dist/gates/http-client.d.ts +4 -3
  85. package/dist/gates/http-client.js +5 -7
  86. package/dist/gates/http-tool.d.ts +24 -4
  87. package/dist/gates/http-tool.js +53 -17
  88. package/dist/gates/in-process.d.ts +2 -1
  89. package/dist/gates/in-process.js +17 -9
  90. package/dist/gates/inflight.d.ts +2 -2
  91. package/dist/gates/inflight.js +3 -2
  92. package/dist/gates/journal.js +5 -7
  93. package/dist/gates/mcp-handler.d.ts +4 -3
  94. package/dist/gates/mcp-handler.js +15 -5
  95. package/dist/gates/model-gate.d.ts +11 -2
  96. package/dist/gates/policy.d.ts +28 -5
  97. package/dist/gates/policy.js +60 -17
  98. package/dist/gates/provider-gate.d.ts +22 -0
  99. package/dist/gates/provider-gate.js +30 -0
  100. package/dist/gates/tool-calls.d.ts +1 -3
  101. package/dist/gates/tool-calls.js +2 -3
  102. package/dist/gates/tool-client.d.ts +1 -1
  103. package/dist/gates/tool-client.js +5 -6
  104. package/dist/gates/tool-contract.d.ts +8 -5
  105. package/dist/gates/tool-contract.js +1 -1
  106. package/dist/gates/tool-gate.d.ts +18 -7
  107. package/dist/gates/tool-gate.js +49 -7
  108. package/dist/harness/calls.d.ts +27 -25
  109. package/dist/harness/calls.js +40 -46
  110. package/dist/harness/executors.d.ts +10 -3
  111. package/dist/harness/executors.js +53 -23
  112. package/dist/harness/main.js +2 -2
  113. package/dist/harness/pod.d.ts +0 -2
  114. package/dist/harness/pod.js +7 -6
  115. package/dist/harness/run-tokens.d.ts +4 -1
  116. package/dist/harness/run-tokens.js +6 -2
  117. package/dist/harness/service.d.ts +17 -14
  118. package/dist/harness/service.js +21 -35
  119. package/dist/harness/setup.d.ts +0 -2
  120. package/dist/harness/setup.js +4 -9
  121. package/dist/harness/ws-client.d.ts +2 -2
  122. package/dist/harness/ws-client.js +7 -5
  123. package/dist/harness/ws-port.d.ts +3 -4
  124. package/dist/harness/ws-port.js +3 -4
  125. package/dist/harness-api/artifacts.d.ts +20 -0
  126. package/dist/harness-api/artifacts.js +478 -0
  127. package/dist/harness-api/in-process.d.ts +2 -2
  128. package/dist/harness-api/in-process.js +18 -16
  129. package/dist/harness-api/record.d.ts +10 -9
  130. package/dist/harness-api/record.js +102 -157
  131. package/dist/harness-api/renew.d.ts +1 -1
  132. package/dist/harness-api/renew.js +2 -2
  133. package/dist/harness-api/server.d.ts +1 -16
  134. package/dist/harness-api/server.js +82 -73
  135. package/dist/harness-api/start.d.ts +20 -2
  136. package/dist/harness-api/start.js +57 -18
  137. package/dist/harness-api/tool-journal.d.ts +15 -10
  138. package/dist/harness-api/tool-journal.js +26 -24
  139. package/dist/harness-api/workspace.d.ts +0 -4
  140. package/dist/harness-api/workspace.js +2 -45
  141. package/dist/harness-api/ws-server.js +10 -10
  142. package/dist/host/create-host.js +2 -3
  143. package/dist/host/execution.js +2 -3
  144. package/dist/host/gates.d.ts +2 -9
  145. package/dist/host/gates.js +15 -12
  146. package/dist/host/http.d.ts +0 -2
  147. package/dist/host/http.js +0 -27
  148. package/dist/host/main.js +10 -3
  149. package/dist/host/operate.js +12 -3
  150. package/dist/host/stack-config.d.ts +11 -0
  151. package/dist/host/stack-config.js +21 -1
  152. package/dist/index.d.ts +0 -1
  153. package/dist/index.js +0 -1
  154. package/dist/infra/index.js +2 -1
  155. package/dist/infra/readiness.d.ts +0 -2
  156. package/dist/infra/readiness.js +4 -3
  157. package/dist/keys/client.d.ts +1 -0
  158. package/dist/keys/client.js +2 -3
  159. package/dist/keys/contract.d.ts +1 -3
  160. package/dist/keys/contract.js +1 -3
  161. package/dist/keys/egress-ca.d.ts +0 -2
  162. package/dist/keys/egress-ca.js +2 -3
  163. package/dist/keys/keys.js +6 -1
  164. package/dist/keys/x509.d.ts +8 -4
  165. package/dist/keys/x509.js +14 -5
  166. package/dist/management-openapi.json +1961 -994
  167. package/dist/mcp/connect.d.ts +35 -26
  168. package/dist/mcp/connect.js +112 -141
  169. package/dist/mcp/pool.d.ts +27 -22
  170. package/dist/mcp/pool.js +34 -48
  171. package/dist/mcp/preview.d.ts +13 -6
  172. package/dist/mcp/preview.js +37 -20
  173. package/dist/mcp/snapshot.d.ts +35 -86
  174. package/dist/mcp/snapshot.js +93 -135
  175. package/dist/model/auth-store.js +5 -3
  176. package/dist/model/capabilities.d.ts +1 -1
  177. package/dist/model/catalog.d.ts +9 -36
  178. package/dist/model/catalog.js +6 -33
  179. package/dist/model/descriptor.d.ts +51 -0
  180. package/dist/model/descriptor.js +83 -0
  181. package/dist/model/models.d.ts +0 -3
  182. package/dist/model/models.js +3 -5
  183. package/dist/model/native-blocks.js +1 -1
  184. package/dist/model/pi-model.d.ts +16 -5
  185. package/dist/model/pi-model.js +86 -105
  186. package/dist/openapi.json +866 -1218
  187. package/dist/reads/cursor.js +3 -1
  188. package/dist/record/append.d.ts +34 -2
  189. package/dist/record/append.js +50 -1
  190. package/dist/record/environment.d.ts +2 -0
  191. package/dist/record/environment.js +2 -0
  192. package/dist/record/index.d.ts +1 -1
  193. package/dist/record/index.js +1 -1
  194. package/dist/redact.d.ts +1 -1
  195. package/dist/redact.js +3 -2
  196. package/dist/sandbox/egress-token.d.ts +3 -3
  197. package/dist/sandbox/egress-token.js +3 -3
  198. package/dist/sandbox/join.js +3 -2
  199. package/dist/sandbox/manager.d.ts +41 -41
  200. package/dist/sandbox/manager.js +112 -44
  201. package/dist/sandbox/placement.d.ts +1 -1
  202. package/dist/sandbox/placement.js +5 -8
  203. package/dist/sandbox/pods/client.d.ts +1 -10
  204. package/dist/sandbox/pods/client.js +8 -4
  205. package/dist/sandbox/pods/lifecycle.d.ts +19 -11
  206. package/dist/sandbox/pods/lifecycle.js +45 -23
  207. package/dist/sandbox/pods/network-gate.d.ts +4 -5
  208. package/dist/sandbox/pods/network-gate.js +7 -7
  209. package/dist/sandbox/pods/reconcile.js +4 -1
  210. package/dist/sandbox/pods/spec.js +8 -5
  211. package/dist/sandbox/policy.d.ts +7 -1
  212. package/dist/sandbox/policy.js +10 -3
  213. package/dist/sandbox/resolve.d.ts +8 -3
  214. package/dist/sandbox/resolve.js +12 -2
  215. package/dist/sandbox/setup.d.ts +3 -1
  216. package/dist/sandbox/setup.js +34 -11
  217. package/dist/sandbox/share.d.ts +5 -14
  218. package/dist/sandbox/share.js +5 -34
  219. package/dist/sandbox/skills.d.ts +7 -13
  220. package/dist/sandbox/skills.js +16 -31
  221. package/dist/sandbox/tenant-config.d.ts +2 -2
  222. package/dist/sandbox/tenant-config.js +4 -3
  223. package/dist/sandbox/tools.d.ts +7 -1
  224. package/dist/sandbox/tools.js +26 -26
  225. package/dist/sandbox/types.d.ts +10 -3
  226. package/dist/sandbox/types.js +9 -0
  227. package/dist/store/postgres/connect.d.ts +6 -5
  228. package/dist/store/postgres/connect.js +14 -11
  229. package/dist/store/postgres/control.js +13 -13
  230. package/dist/store/postgres/drizzle/0028_artifact_write_keys.sql +2 -0
  231. package/dist/store/postgres/drizzle/0029_protocol_15.sql +11 -0
  232. package/dist/store/postgres/drizzle/0030_protocol_15_runtime_block.sql +11 -0
  233. package/dist/store/postgres/drizzle/0031_protocol_15_mcp_snapshot.sql +8 -0
  234. package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
  235. package/dist/store/postgres/migrate.js +1 -1
  236. package/dist/store/postgres/reads.js +10 -2
  237. package/dist/store/postgres/schema.d.ts +19 -0
  238. package/dist/store/postgres/schema.js +7 -0
  239. package/dist/store/postgres/store.js +55 -26
  240. package/dist/store/types.d.ts +17 -7
  241. package/dist/streams/relay/core.d.ts +3 -3
  242. package/dist/streams/relay/core.js +9 -10
  243. package/dist/tenant/advance.js +21 -31
  244. package/dist/tenant/commands.js +9 -16
  245. package/dist/tenant/context.d.ts +14 -17
  246. package/dist/tenant/definition-files.d.ts +25 -4
  247. package/dist/tenant/definition-files.js +85 -47
  248. package/dist/tenant/effects.js +9 -36
  249. package/dist/tenant/environment-manifests.js +9 -1
  250. package/dist/tenant/environments.d.ts +0 -2
  251. package/dist/tenant/environments.js +54 -30
  252. package/dist/tenant/ephemeral.d.ts +1 -1
  253. package/dist/tenant/ephemeral.js +2 -1
  254. package/dist/tenant/history.d.ts +1 -1
  255. package/dist/tenant/history.js +1 -1
  256. package/dist/tenant/host-token.d.ts +3 -3
  257. package/dist/tenant/host-token.js +12 -11
  258. package/dist/tenant/http.d.ts +5 -8
  259. package/dist/tenant/http.js +9 -0
  260. package/dist/tenant/identity-file.d.ts +24 -1
  261. package/dist/tenant/identity-file.js +35 -7
  262. package/dist/tenant/issuers.d.ts +5 -5
  263. package/dist/tenant/issuers.js +31 -23
  264. package/dist/tenant/jwt.d.ts +8 -2
  265. package/dist/tenant/jwt.js +10 -2
  266. package/dist/tenant/limits.d.ts +90 -0
  267. package/dist/tenant/limits.js +175 -0
  268. package/dist/tenant/module.d.ts +4 -1
  269. package/dist/tenant/module.js +9 -8
  270. package/dist/tenant/outbound.d.ts +17 -19
  271. package/dist/tenant/outbound.js +18 -21
  272. package/dist/tenant/run-grants.js +3 -2
  273. package/dist/tenant/run-token.d.ts +0 -4
  274. package/dist/tenant/run-token.js +6 -11
  275. package/dist/tenant/runtime-limits.d.ts +24 -0
  276. package/dist/tenant/runtime-limits.js +27 -0
  277. package/dist/tenant/runtime.js +30 -43
  278. package/dist/tenant/session-streams.js +7 -6
  279. package/dist/tenant/session.d.ts +1 -1
  280. package/dist/tenant/session.js +1 -1
  281. package/dist/tenant/sessions.js +32 -29
  282. package/dist/tenant/signing-keys.d.ts +1 -1
  283. package/dist/tenant/signing-keys.js +5 -6
  284. package/dist/tenant/status.js +4 -3
  285. package/dist/tenant/streams.js +18 -20
  286. package/dist/tenant/sweep.d.ts +1 -21
  287. package/dist/tenant/sweep.js +39 -48
  288. package/dist/tenant/transcript.d.ts +70 -23
  289. package/dist/tenant/transcript.js +28 -22
  290. package/dist/tenant/types.d.ts +11 -16
  291. package/dist/tenant/worker.d.ts +2 -10
  292. package/dist/tenant/worker.js +5 -14
  293. package/dist/traces/ids.js +5 -1
  294. package/dist/traces/map.d.ts +9 -6
  295. package/dist/traces/map.js +9 -11
  296. package/dist/traces/otlp.d.ts +3 -3
  297. package/dist/traces/otlp.js +5 -3
  298. package/dist/traces/projector.d.ts +9 -4
  299. package/dist/traces/projector.js +13 -7
  300. package/dist/traces/read.js +6 -1
  301. package/dist/tuning.d.ts +383 -0
  302. package/dist/tuning.js +658 -0
  303. package/dist/vault/headers.js +4 -2
  304. package/dist/version.d.ts +1 -1
  305. package/dist/version.js +1 -1
  306. package/package.json +3 -3
  307. package/dist/artifacts/export.d.ts +0 -8
  308. package/dist/artifacts/export.js +0 -204
  309. package/dist/artifacts/media-types.d.ts +0 -30
  310. package/dist/artifacts/media-types.js +0 -137
  311. package/dist/artifacts/workspace.d.ts +0 -60
  312. package/dist/artifacts/workspace.js +0 -45
  313. package/dist/media.d.ts +0 -10
  314. package/dist/media.js +0 -58
  315. package/dist/sandbox/runtime-tools.d.ts +0 -9
  316. package/dist/sandbox/runtime-tools.js +0 -16
  317. package/dist/sandbox/session-sandbox.d.ts +0 -16
  318. package/dist/sandbox/session-sandbox.js +0 -77
  319. package/dist/tenant/artifact-tool.d.ts +0 -13
  320. package/dist/tenant/artifact-tool.js +0 -243
  321. package/dist/tenant/skill-tool.d.ts +0 -20
  322. package/dist/tenant/skill-tool.js +0 -67
  323. package/dist/tenant/tool-results.d.ts +0 -57
  324. package/dist/tenant/tool-results.js +0 -298
  325. package/dist/tenant/tool-search.d.ts +0 -39
  326. package/dist/tenant/tool-search.js +0 -103
@@ -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 {
@@ -4,7 +4,7 @@
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 = {
@@ -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,28 @@
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
28
  import { loadSession, } from "../../tenant/context.js";
29
29
  import { HttpError, fail } from "../../tenant/http.js";
30
30
  import { observeSession, readHistory } from "../../tenant/session-streams.js";
31
31
  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;
32
+ import { readRuntimeLimits } from "../../tenant/runtime-limits.js";
37
33
  /**
38
34
  * `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.
35
+ * input modes name the files the Tenant's model reads natively: a hint, since any file is
36
+ * accepted and the agent's harness decides how its model sees it (protocol 15).
40
37
  */
41
38
  export async function a2aCard(ctx, scope, agentId) {
42
39
  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)));
40
+ // The files the Tenant's model reads now.
41
+ return agentCard(agentId, definition, inputModesFor((await currentModelDescriptor(ctx))?.inputs));
45
42
  }
46
43
  /**
47
44
  * `POST /v1/a2a/agents/:agent`: one A2A JSON-RPC call, for a subject. JSON-RPC answers (errors
@@ -155,11 +152,6 @@ conflict) {
155
152
  catch (error) {
156
153
  if (!(error instanceof HttpError))
157
154
  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
155
  if (error.status !== 409)
164
156
  throw error;
165
157
  if (error.message.startsWith("Idempotency key"))
@@ -320,14 +312,16 @@ async function cancelTask(caller, taskId) {
320
312
  return (await ownedTask(caller, taskId)).task;
321
313
  }
322
314
  /**
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
315
+ * Waits until the turn ends, pauses or has an uncertain effect, the caller hangs up, or the
316
+ * Tenant's Runtime limit `a2aWaitMs` passes: after it, the task is returned `WORKING` and keeps
317
+ * running, and the caller polls `GetTask`. Follows the session's shared stream from the command's
325
318
  * cursor, so the events the task is built from are there when it returns. A feed that ends
326
319
  * (reset, deleted, closing) ends the wait: the task says what the session says then.
327
320
  */
328
321
  async function settled(ctx, sessionId, turnId, cursor, signal) {
329
322
  const stop = new AbortController();
330
- const timer = setTimeout(() => stop.abort(), A2A_BLOCKING_WAIT_MS);
323
+ const { a2aWaitMs } = await ctx.store.tx((t) => readRuntimeLimits(t));
324
+ const timer = setTimeout(() => stop.abort(), a2aWaitMs);
331
325
  timer.unref();
332
326
  const hangup = () => stop.abort();
333
327
  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
@@ -37,7 +37,7 @@ import { observeSession, readHistory, StreamClosed, streamHolderOf, } from "../.
37
37
  import { putSession, sessionView } from "../../tenant/sessions.js";
38
38
  import { mayUseAgent } from "../../tenant/auth.js";
39
39
  import { environmentGrantsOf } from "../../tenant/environments.js";
40
- const HEARTBEAT_MS = 15_000;
40
+ import { hostTuning } from "../../tuning.js";
41
41
  const TERMINAL = new Set([
42
42
  "turn.completed",
43
43
  "turn.paused",
@@ -203,7 +203,7 @@ async function stream(response, translator, source, preface = []) {
203
203
  if (!response.writableEnded && !response.write(text))
204
204
  response.destroy();
205
205
  };
206
- const heartbeat = setInterval(() => write(SSE_HEARTBEAT), HEARTBEAT_MS);
206
+ const heartbeat = setInterval(() => write(SSE_HEARTBEAT), hostTuning().api.agUiHeartbeatMs);
207
207
  heartbeat.unref();
208
208
  try {
209
209
  write(sseFrame(translator.started()));