@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,10 +1,9 @@
1
1
  import type { HarnessOptions } from "@nylorun/harness/api";
2
- import type { ModelProvider } from "../core/provider.js";
3
2
  import type { ModelGate } from "../gates/model-gate.js";
4
- import type { ToolGate } from "../gates/tool-gate.js";
5
- import { McpPool } from "../mcp/pool.js";
3
+ import { type ToolGate } from "../gates/tool-gate.js";
6
4
  import type { SandboxBackend } from "../sandbox/types.js";
7
5
  import { type HarnessClient, type HarnessClientOptions } from "./ws-client.js";
6
+ import { type EngineTuning } from "../tuning.js";
8
7
  export interface HarnessServiceOptions {
9
8
  readonly url: string;
10
9
  readonly token: HarnessClientOptions["token"];
@@ -12,24 +11,23 @@ export interface HarnessServiceOptions {
12
11
  readonly paths: {
13
12
  readonly sandboxes: string;
14
13
  };
15
- /** Vault-backed model calls (the gates service's client). */
14
+ /** Every model call (the gates service's client; a scripted model's gate in tests). */
16
15
  readonly modelGate: ModelGate;
17
- /** Models served without the vault; a harness process has none (`useVaultModel`). */
18
- readonly modelProvider?: ModelProvider;
19
- readonly useVaultModel: boolean;
20
- /** Remote MCP servers (`openMcp`) and keyed cancels; the gates service's client. */
21
- readonly toolGate: Pick<ToolGate, "recovers" | "cancel" | "openMcp" | "callHttp">;
22
16
  /**
23
- * Authorizes a remote MCP server opened in this process. A harness process has no vault: it
24
- * opens remote servers through the Tool Gate, and refuses them without one.
17
+ * Remote MCP servers (`openMcp`), HTTP tools and keyed cancels: the gates service's client. A
18
+ * harness process has no vault: it opens MCP servers only through the Tool Gate.
25
19
  */
26
- readonly authorize?: ConstructorParameters<typeof McpPool>[0]["authorize"];
27
- /** How remote MCP servers opened in this process are reached (`TenantConfig.delivery`). */
28
- readonly delivery?: ConstructorParameters<typeof McpPool>[0]["policy"];
20
+ readonly toolGate: Pick<ToolGate, "recovers" | "cancel" | "openMcp" | "callHttp">;
29
21
  /** Default: the virtual backend under `paths.sandboxes`. */
30
22
  readonly sandboxBackends?: readonly SandboxBackend[];
31
23
  /** Delete the workspaces on stop (an ephemeral Runtime's loopback harness). */
32
24
  readonly ephemeral?: boolean;
25
+ /**
26
+ * The sandbox tools' limits: what our engine's schemas name and what this harness runs them
27
+ * with. Default the Host tuning's `engine.sandboxTools`; each left out is its default
28
+ * (`DEFAULT_SANDBOX_TOOL_LIMITS`).
29
+ */
30
+ readonly sandboxTools?: HarnessOptions["sandboxTools"];
33
31
  readonly logger: HarnessClientOptions["logger"];
34
32
  readonly version?: string;
35
33
  readonly onGrant?: HarnessOptions["onGrant"];
@@ -41,4 +39,9 @@ export interface HarnessService {
41
39
  /** Stops leasing and gives runs back (at most `waitMs`), then closes MCP and sandboxes. */
42
40
  stop(waitMs?: number): Promise<void>;
43
41
  }
42
+ /**
43
+ * The options of `createHarness` the Host tuning's `engine` group sets (`tuning.ts`): only the
44
+ * ones set, so the engine keeps its own default for the rest.
45
+ */
46
+ export declare function engineOptionsOf(engine: EngineTuning): Pick<HarnessOptions, keyof EngineTuning>;
44
47
  export declare function startHarnessService(options: HarnessServiceOptions): HarnessService;
@@ -12,12 +12,14 @@
12
12
  import { fromWireOp, toWireAnswer } from "../sandbox/disk-fs.js";
13
13
  import { join } from "node:path";
14
14
  import { DEFAULT_HARNESS, HarnessApiError, } from "@nylorun/core/harness-api";
15
+ import { openMcpThrough } from "../gates/tool-gate.js";
15
16
  import { McpPool } from "../mcp/pool.js";
16
17
  import { SandboxManager } from "../sandbox/manager.js";
17
18
  import { fileSandboxRecords, workspacePrefix } from "../sandbox/records.js";
18
19
  import { defaultSandboxBackends } from "../sandbox/select.js";
19
20
  import { harnessExecutors } from "./executors.js";
20
21
  import { connectHarness } from "./ws-client.js";
22
+ import { hostTuning } from "../tuning.js";
21
23
  /** Which request runs each sandbox tool. */
22
24
  const METHODS = {
23
25
  bash: "workspace.exec",
@@ -27,8 +29,15 @@ const METHODS = {
27
29
  write: "workspace.write",
28
30
  edit: "workspace.write",
29
31
  };
30
- /** How often the harness closes MCP connections idle past their timeout. */
31
- const MCP_SWEEP_MS = 60_000;
32
+ /**
33
+ * The options of `createHarness` the Host tuning's `engine` group sets (`tuning.ts`): only the
34
+ * ones set, so the engine keeps its own default for the rest.
35
+ */
36
+ export function engineOptionsOf(engine) {
37
+ // Every key of the group is an option of `createHarness`, with a type it takes.
38
+ const options = engine;
39
+ return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined));
40
+ }
32
41
  /** The SandboxManager's view of the session a workspace request acts for. */
33
42
  function refOf(session) {
34
43
  return {
@@ -37,9 +46,6 @@ function refOf(session) {
37
46
  ...(session.environmentId === undefined ? {} : { environmentId: session.environmentId }),
38
47
  };
39
48
  }
40
- const noModel = async () => {
41
- throw new Error("This harness calls models only through the gates service");
42
- };
43
49
  export function startHarnessService(options) {
44
50
  const { logger } = options;
45
51
  const backends = options.sandboxBackends ?? defaultSandboxBackends({ root: options.paths.sandboxes });
@@ -51,28 +57,25 @@ export function startHarnessService(options) {
51
57
  throw new HarnessApiError("unavailable", "The harness has not said hello yet");
52
58
  return manager;
53
59
  };
54
- const pool = new McpPool({
55
- authorize: options.authorize ??
56
- (async () => {
57
- throw new Error("This harness opens remote MCP servers only through the gates service");
58
- }),
59
- ...(options.delivery ? { policy: options.delivery } : {}),
60
- ...(options.toolGate.openMcp ? { openRemote: (server) => options.toolGate.openMcp(server) } : {}),
61
- });
62
- const sweep = setInterval(() => void pool.sweep().catch(() => undefined), MCP_SWEEP_MS);
60
+ const pool = new McpPool({ openRemote: openMcpThrough(options.toolGate) });
61
+ // How often the harness closes MCP connections idle past their timeout.
62
+ const sweep = setInterval(() => void pool.sweep().catch(() => undefined), hostTuning().harness.mcpSweepMs);
63
63
  sweep.unref();
64
+ // Our engine's settings from the Host tuning (`engine`): the executors run the sandbox tools
65
+ // with the limits the engine writes into their schemas.
66
+ const engine = engineOptionsOf(hostTuning().engine);
67
+ const sandboxTools = options.sandboxTools ?? engine.sandboxTools;
64
68
  const executors = harnessExecutors({
65
69
  model: {
66
70
  get tenantId() {
67
71
  return tenantId;
68
72
  },
69
73
  modelGate: options.modelGate,
70
- modelProvider: options.modelProvider ?? noModel,
71
- useVaultModel: options.useVaultModel,
72
74
  },
73
75
  toolGate: options.toolGate,
74
76
  mcp: pool,
75
77
  sandbox,
78
+ ...(sandboxTools ? { sandboxTools } : {}),
76
79
  });
77
80
  const serve = async (method, params, signal) => {
78
81
  switch (method) {
@@ -85,17 +88,6 @@ export function startHarnessService(options) {
85
88
  const answer = await sandbox().disk(refOf(call.session), call.spec, fromWireOp(call.disk), signal);
86
89
  return "code" in answer ? answer : toWireAnswer(answer);
87
90
  }
88
- if (method === "workspace.read" && "list" in params) {
89
- const call = params;
90
- return sandbox().listFiles(refOf(call.session), call.spec, call.list.dir, call.list.maxEntries, signal);
91
- }
92
- if (method === "workspace.read" && "bytes" in params) {
93
- const call = params;
94
- const read = await sandbox().readBytes(refOf(call.session), call.spec, call.bytes.path, call.bytes.maxBytes, signal);
95
- return read.kind === "read"
96
- ? { kind: "read", path: read.path, base64: Buffer.from(read.bytes).toString("base64") }
97
- : read;
98
- }
99
91
  const call = params;
100
92
  if (METHODS[call.tool] !== method)
101
93
  throw new HarnessApiError("invalid", `${method} does not run ${call.tool}`);
@@ -139,6 +131,8 @@ export function startHarnessService(options) {
139
131
  name: DEFAULT_HARNESS,
140
132
  ...(options.version ? { version: options.version } : {}),
141
133
  features: { workspace: { backends: backends.map((backend) => backend.name) } },
134
+ ...engine,
135
+ ...(sandboxTools ? { sandboxTools } : {}),
142
136
  onHello(answer) {
143
137
  tenantId = answer.tenantId;
144
138
  manager ??= new SandboxManager({
@@ -147,14 +141,6 @@ export function startHarnessService(options) {
147
141
  backends,
148
142
  preference: answer.sandbox.backend ?? "auto",
149
143
  ephemeral: options.ephemeral === true,
150
- // A skill file's bytes come from core, for the run that made the call.
151
- definitionFile: async (sha256, session) => {
152
- const channel = client.channel();
153
- if (!channel || session.claim === undefined)
154
- throw new Error(`No run to fetch ${sha256} for`);
155
- const { base64 } = await channel.request("definition.file", { runId: session.claim, sha256 });
156
- return new Uint8Array(Buffer.from(base64, "base64"));
157
- },
158
144
  // A claim core refuses (its run ended, the session is gone) is dropped, as core's own
159
145
  // SandboxManager drops an event it cannot write.
160
146
  emit: async (sessionId, turnId, type, payload, meta) => {
@@ -1,7 +1,5 @@
1
1
  import type { ExecRequest, ExecResult } from "../sandbox/types.js";
2
2
  import type { PodHost } from "./pod.js";
3
- /** How often a failed setup asks whether to run again. */
4
- export declare const SETUP_RETRY_POLL_MS = 5000;
5
3
  export interface DiskSetupOptions {
6
4
  readonly host: Pick<PodHost, "setup" | "setupState" | "reportSetup" | "setupFile"> & {
7
5
  /** The volume starts from a disk version (R2d step 3): it holds what setup made. */
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * The disk's setup in a pod Environment's engine (R2d step 2): after it joins and before it takes
3
3
  * any turn, the engine copies the recipe's input files and runs its setup commands, once per
4
- * volume. A marker on the volume (`/harness/setup.json`, `{ volumeId, recipeVersion, status }`)
5
- * says it was done: a resume finds it and skips, a reset (a new volume, a new volume id) runs it
6
- * again. Commands run as the sandbox tools' do (`localExec`): `/bin/sh -c` in `cwd`, with the
4
+ * volume. A marker on the volume (`/harness/setup.json`, `{ volumeId, recipeVersion, setupHash,
5
+ * status }`) says it was done: a resume finds it and skips, a reset (a new volume, a new volume
6
+ * id) runs it again, and so does a start on a new version whose setup differs (`setupHash`,
7
+ * track T3). A marker without a hash (written before T3) counts as this setup's. Commands run as the sandbox tools' do (`localExec`): `/bin/sh -c` in `cwd`, with the
7
8
  * Environment's variables and secrets (as the sentinel) and egress through egress-gate.
8
9
  *
9
10
  * A failure is reported to core, which fails the pod and the turn waiting for it; the engine then
@@ -16,12 +17,16 @@
16
17
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
17
18
  import { randomUUID } from "node:crypto";
18
19
  import { dirname, posix } from "node:path";
19
- /** How often a failed setup asks whether to run again. */
20
- export const SETUP_RETRY_POLL_MS = 5_000;
21
- /** How often a fork's setup asks whether its disk version is written (Q17). */
22
- const AFTER_SEED_POLL_MS = 1_000;
23
- /** The end of a failed command's output kept in its report. */
24
- const REPORT_TAIL = 4 * 1024;
20
+ import { hostTuning } from "../tuning.js";
21
+ /** The marker of `setup` done on volume `volumeId`. */
22
+ function markerOf(volumeId, setup) {
23
+ return {
24
+ volumeId,
25
+ recipeVersion: setup?.recipeVersion ?? 0,
26
+ ...(setup?.setupHash === undefined ? {} : { setupHash: setup.setupHash }),
27
+ status: "ok",
28
+ };
29
+ }
25
30
  async function readText(path) {
26
31
  try {
27
32
  return (await readFile(path, "utf8")).trim();
@@ -83,7 +88,7 @@ async function runOnce(options, setup) {
83
88
  }
84
89
  if (result.exitCode !== 0) {
85
90
  const output = `${result.stdout}${result.stderr ? `\n${result.stderr}` : ""}${result.timedOut ? "\n[timed out]" : ""}`;
86
- return { status: "failed", index, exitCode: result.exitCode, output: output.slice(-REPORT_TAIL) };
91
+ return { status: "failed", index, exitCode: result.exitCode, output: output.slice(-hostTuning().harness.setupReportTailChars) };
87
92
  }
88
93
  }
89
94
  return { status: "ok" };
@@ -105,7 +110,7 @@ export async function prepareDisk(options) {
105
110
  setup = state.setup;
106
111
  break;
107
112
  }
108
- await new Promise((resolve) => setTimeout(resolve, options.pollMs ?? AFTER_SEED_POLL_MS));
113
+ await new Promise((resolve) => setTimeout(resolve, options.pollMs ?? hostTuning().harness.setupAfterSeedPollMs));
109
114
  }
110
115
  if (!setup) {
111
116
  // Nothing to run: say so, so the fork's turns may start.
@@ -116,7 +121,7 @@ export async function prepareDisk(options) {
116
121
  else if (options.host.seeded) {
117
122
  // A volume seeded from a disk version: the version holds what setup made, so mark it done.
118
123
  if (volumeId) {
119
- const done = { volumeId, recipeVersion: setup?.recipeVersion ?? 0, status: "ok" };
124
+ const done = markerOf(volumeId, setup);
120
125
  await writeAtomic(options.markerFile, new TextEncoder().encode(`${JSON.stringify(done)}\n`));
121
126
  }
122
127
  options.logger.info("environment_setup_skipped", { reason: "seeded" });
@@ -128,7 +133,8 @@ export async function prepareDisk(options) {
128
133
  if (marker && volumeId) {
129
134
  try {
130
135
  const done = JSON.parse(marker);
131
- if (done.volumeId === volumeId && done.status === "ok")
136
+ const same = done.setupHash === undefined || setup.setupHash === undefined || done.setupHash === setup.setupHash;
137
+ if (done.volumeId === volumeId && done.status === "ok" && same)
132
138
  return;
133
139
  }
134
140
  catch {
@@ -142,7 +148,7 @@ export async function prepareDisk(options) {
142
148
  const report = await runOnce(options, setup);
143
149
  if (report.status === "ok") {
144
150
  if (volumeId) {
145
- const done = { volumeId, recipeVersion: setup.recipeVersion, status: "ok" };
151
+ const done = markerOf(volumeId, setup);
146
152
  await writeAtomic(options.markerFile, new TextEncoder().encode(`${JSON.stringify(done)}\n`));
147
153
  }
148
154
  await options.host.reportSetup(report).catch((error) => options.logger.warn("environment_setup_report_failed", {
@@ -157,7 +163,7 @@ export async function prepareDisk(options) {
157
163
  for (;;) {
158
164
  if (!reported)
159
165
  reported = await options.host.reportSetup(report).then(() => true, () => false);
160
- await new Promise((resolve) => setTimeout(resolve, options.pollMs ?? SETUP_RETRY_POLL_MS));
166
+ await new Promise((resolve) => setTimeout(resolve, options.pollMs ?? hostTuning().harness.setupRetryPollMs));
161
167
  if (options.signal?.aborted)
162
168
  return;
163
169
  if (!reported)
@@ -4,7 +4,7 @@
4
4
  * header. Each connection runs one `createHarness`: it says `hello`, leases runs, and answers
5
5
  * core's `workspace.*` requests (`serve`). When the connection is lost its runs stop (core gives
6
6
  * their segments to the next advance, which resumes them by replay) and the client connects
7
- * again after a jittered backoff of 0.5 to 10 s.
7
+ * again after a jittered backoff (`harness.reconnect` in the Host tuning, 0.5 to 10 s).
8
8
  */
9
9
  import { type HarnessChannel, type RequestHandler } from "@nylorun/core/harness-api";
10
10
  import { type HarnessOptions } from "@nylorun/harness/api";
@@ -23,7 +23,7 @@ export interface HarnessClientOptions extends Omit<HarnessOptions, "channel" | "
23
23
  };
24
24
  /** Answers core's requests (`workspace.*`). */
25
25
  readonly serve?: RequestHandler;
26
- /** Reconnect backoff bounds. Default 500 ms to 10 s. */
26
+ /** Reconnect backoff bounds. Default `harness.reconnect` (Host tuning, 500 ms to 10 s). */
27
27
  readonly backoff?: {
28
28
  readonly minMs: number;
29
29
  readonly maxMs: number;
@@ -4,16 +4,18 @@
4
4
  * header. Each connection runs one `createHarness`: it says `hello`, leases runs, and answers
5
5
  * core's `workspace.*` requests (`serve`). When the connection is lost its runs stop (core gives
6
6
  * their segments to the next advance, which resumes them by replay) and the client connects
7
- * again after a jittered backoff of 0.5 to 10 s.
7
+ * again after a jittered backoff (`harness.reconnect` in the Host tuning, 0.5 to 10 s).
8
8
  */
9
9
  import { createChannel } from "@nylorun/core/harness-api";
10
10
  import { createHarness } from "@nylorun/harness/api";
11
11
  import { WebSocket } from "ws";
12
12
  import { HARNESS_API_HEADER, HARNESS_API_TRANSPORT, HARNESS_MAX_PAYLOAD } from "@nylorun/core/harness-api";
13
13
  import { wsPort } from "./ws-port.js";
14
+ import { hostTuning } from "../tuning.js";
14
15
  export function connectHarness(options) {
15
16
  const { logger } = options;
16
- const backoff = options.backoff ?? { minMs: 500, maxMs: 10_000 };
17
+ const tuning = hostTuning().harness;
18
+ const backoff = options.backoff ?? tuning.reconnect;
17
19
  let stopped = false;
18
20
  let connected = false;
19
21
  let current;
@@ -26,7 +28,7 @@ export function connectHarness(options) {
26
28
  const socket = new WebSocket(options.url, {
27
29
  headers: { authorization: `Bearer ${token}`, [HARNESS_API_HEADER]: HARNESS_API_TRANSPORT },
28
30
  maxPayload: HARNESS_MAX_PAYLOAD,
29
- handshakeTimeout: 10_000,
31
+ handshakeTimeout: tuning.handshakeTimeoutMs,
30
32
  });
31
33
  socket.once("open", () => {
32
34
  socket.removeAllListeners("error");
@@ -74,7 +76,7 @@ export function connectHarness(options) {
74
76
  connected = false;
75
77
  // The connection is gone: its runs were aborted with it; let them wind down.
76
78
  if (!stopped)
77
- await harness.stop(5_000);
79
+ await harness.stop(tuning.reconnectStopMs);
78
80
  channel.close("reconnecting");
79
81
  current = undefined;
80
82
  }
@@ -109,7 +111,7 @@ export function connectHarness(options) {
109
111
  return connected;
110
112
  },
111
113
  channel: () => current?.channel,
112
- async stop(waitMs = 10_000) {
114
+ async stop(waitMs = tuning.stopMs) {
113
115
  stopped = true;
114
116
  wake?.();
115
117
  const live = current;
@@ -1,14 +1,13 @@
1
1
  /**
2
2
  * The Harness API over a WebSocket (F6.2): one JSON text message per frame. Either end watches
3
- * the connection: core pings every `pingMs` (30 s), the harness answers (`ws` does it), and an
4
- * end that hears nothing from the other for `silenceMs` (90 s) drops the connection. A message
3
+ * the connection: core pings every `pingMs` (Host tuning `harness.pingMs`, 30 s), the harness
4
+ * answers (`ws` does it), and an end that hears nothing from the other for `silenceMs`
5
+ * (`harness.silenceMs`, 90 s) drops the connection. A message
5
6
  * that is not JSON closes it (1007); `createChannel({ validate: true })` checks the rest.
6
7
  */
7
8
  import type { Port } from "@nylorun/core/harness-api";
8
9
  import { WebSocket } from "ws";
9
10
  export { HARNESS_API_HEADER, HARNESS_API_PATH, HARNESS_API_TRANSPORT, HARNESS_MAX_PAYLOAD, } from "@nylorun/core/harness-api";
10
- export declare const DEFAULT_PING_MS = 30000;
11
- export declare const DEFAULT_SILENCE_MS = 90000;
12
11
  export interface WsPortOptions {
13
12
  /** Send pings (core's end). */
14
13
  readonly ping?: boolean;
@@ -1,11 +1,10 @@
1
1
  import { WebSocket } from "ws";
2
+ import { hostTuning } from "../tuning.js";
2
3
  export { HARNESS_API_HEADER, HARNESS_API_PATH, HARNESS_API_TRANSPORT, HARNESS_MAX_PAYLOAD, } from "@nylorun/core/harness-api";
3
- export const DEFAULT_PING_MS = 30_000;
4
- export const DEFAULT_SILENCE_MS = 90_000;
5
4
  export function wsPort(socket, options = {}) {
6
5
  const frames = [];
7
6
  const closes = [];
8
- const silenceMs = options.silenceMs ?? DEFAULT_SILENCE_MS;
7
+ const silenceMs = options.silenceMs ?? hostTuning().harness.silenceMs;
9
8
  let lastHeard = Date.now();
10
9
  let closed = false;
11
10
  let reason = "closed";
@@ -19,7 +18,7 @@ export function wsPort(socket, options = {}) {
19
18
  }
20
19
  else if (options.ping && socket.readyState === WebSocket.OPEN)
21
20
  socket.ping();
22
- }, Math.min(options.pingMs ?? DEFAULT_PING_MS, silenceMs));
21
+ }, Math.min(options.pingMs ?? hostTuning().harness.pingMs, silenceMs));
23
22
  watch.unref();
24
23
  socket.on("ping", heard);
25
24
  socket.on("pong", heard);
@@ -0,0 +1,20 @@
1
+ import { type ParamsOf, type ResultOf } from "@nylorun/core/harness-api";
2
+ import { type HarnessLimits } from "@nylorun/core/contracts";
3
+ import type { TenantContext } from "../tenant/context.js";
4
+ /** The run an artifact request is for, as the server holds it. */
5
+ export interface ArtifactScope {
6
+ readonly runId: string;
7
+ readonly sessionId: string;
8
+ readonly turnId: string;
9
+ /** The Runtime limits of the run's `turn.start`. */
10
+ readonly limits: HarnessLimits;
11
+ /** Core's abort of the advance: it stops the run's uploads. */
12
+ readonly runSignal: AbortSignal;
13
+ }
14
+ export interface ArtifactSeam {
15
+ read(scope: ArtifactScope, params: ParamsOf<"artifact.read">, signal: AbortSignal): Promise<ResultOf<"artifact.read">>;
16
+ write(scope: ArtifactScope, params: ParamsOf<"artifact.write">, signal: AbortSignal): Promise<ResultOf<"artifact.write">>;
17
+ /** The run ended: its open uploads stop, and nothing of them commits. */
18
+ endRun(runId: string): void;
19
+ }
20
+ export declare function createArtifactSeam(ctx: TenantContext): ArtifactSeam;