@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
@@ -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. */
@@ -16,12 +16,7 @@
16
16
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
17
17
  import { randomUUID } from "node:crypto";
18
18
  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;
19
+ import { hostTuning } from "../tuning.js";
25
20
  async function readText(path) {
26
21
  try {
27
22
  return (await readFile(path, "utf8")).trim();
@@ -83,7 +78,7 @@ async function runOnce(options, setup) {
83
78
  }
84
79
  if (result.exitCode !== 0) {
85
80
  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) };
81
+ return { status: "failed", index, exitCode: result.exitCode, output: output.slice(-hostTuning().harness.setupReportTailChars) };
87
82
  }
88
83
  }
89
84
  return { status: "ok" };
@@ -105,7 +100,7 @@ export async function prepareDisk(options) {
105
100
  setup = state.setup;
106
101
  break;
107
102
  }
108
- await new Promise((resolve) => setTimeout(resolve, options.pollMs ?? AFTER_SEED_POLL_MS));
103
+ await new Promise((resolve) => setTimeout(resolve, options.pollMs ?? hostTuning().harness.setupAfterSeedPollMs));
109
104
  }
110
105
  if (!setup) {
111
106
  // Nothing to run: say so, so the fork's turns may start.
@@ -157,7 +152,7 @@ export async function prepareDisk(options) {
157
152
  for (;;) {
158
153
  if (!reported)
159
154
  reported = await options.host.reportSetup(report).then(() => true, () => false);
160
- await new Promise((resolve) => setTimeout(resolve, options.pollMs ?? SETUP_RETRY_POLL_MS));
155
+ await new Promise((resolve) => setTimeout(resolve, options.pollMs ?? hostTuning().harness.setupRetryPollMs));
161
156
  if (options.signal?.aborted)
162
157
  return;
163
158
  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;