@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
@@ -1,10 +1,6 @@
1
1
  import type { AgentManifest, McpServerManifest } from "@nylorun/core/define";
2
- import type { OutboundPolicy } from "../tenant/outbound.js";
3
- import type { AuthorizeResult } from "../vault/service.js";
4
- import { openMcpServer, type LiveConnection, type McpToolOutcome } from "./connect.js";
5
- import { type McpDiagnostic, type McpSnapshot, type McpToolRecord } from "./snapshot.js";
6
- /** A connection unused this long is closed by the sweep; the next call opens it again. */
7
- export declare const DEFAULT_MCP_IDLE_MS: number;
2
+ import { type LiveConnection, type McpToolOutcome } from "./connect.js";
3
+ import type { McpDiagnostic, McpSnapshot } from "./snapshot.js";
8
4
  export declare class McpPool {
9
5
  private readonly options;
10
6
  private readonly live;
@@ -12,40 +8,44 @@ export declare class McpPool {
12
8
  private readonly opening;
13
9
  private readonly idleMs;
14
10
  private readonly now;
15
- private readonly open;
16
11
  constructor(options: {
17
- readonly authorize: (sessionId: string, request: {
18
- url: string;
19
- serverName: string;
20
- agentId?: string;
21
- }) => Promise<AuthorizeResult>;
22
- /** Default `DEFAULT_MCP_IDLE_MS`. */
12
+ /**
13
+ * A connection unused this long is closed by the sweep; the next call opens it again.
14
+ * Default `harness.mcpIdleMs` (Host tuning, 15 min).
15
+ */
23
16
  readonly idleMs?: number;
24
17
  readonly now?: () => number;
25
- /** Tests replace how a declared server is opened. */
26
- readonly open?: typeof openMcpServer;
27
- /** How remote servers opened in this process are reached (`TenantConfig.delivery`). */
28
- readonly policy?: OutboundPolicy;
29
18
  /**
30
- * Opens a remote (`streamable-http` or `sse`) server somewhere else: the gates service
31
- * holds the connection and its credential, and the loop never sees either (F4.1).
32
- * Absent: they are opened in this process, with `authorize`.
19
+ * Opens a declared remote (`streamable-http` or `sse`) server through a Tool Gate
20
+ * (`ToolGate.openMcp`): the gate finds it in the session's pinned manifest and holds its
21
+ * credential, and the pool never sees either (F4.1, protocol 15).
33
22
  */
34
- readonly openRemote?: (server: McpServerRef) => Promise<LiveConnection>;
23
+ readonly openRemote: (server: McpServerRef) => Promise<LiveConnection>;
35
24
  });
25
+ /**
26
+ * Opens each declared server of the session and lists its tools (protocol 15): the snapshot
27
+ * holds every server that connected, with its instructions and its tools as it named them.
28
+ * Instructions past `maxInstructionBytes` (the Runtime limit `recordEntryBytes`) are left out,
29
+ * and the server's diagnostic says so.
30
+ */
36
31
  discover(input: {
37
32
  sessionId: string;
38
33
  manifest: AgentManifest;
39
34
  manifestHash: string;
35
+ maxInstructionBytes: number;
40
36
  signal?: AbortSignal;
41
37
  }): Promise<{
42
38
  snapshot: McpSnapshot;
43
39
  diagnostics: McpDiagnostic[];
44
40
  }>;
41
+ /** Opens again each server of the snapshot this process holds no connection to. */
45
42
  reconnect(input: {
46
43
  sessionId: string;
47
44
  manifest: AgentManifest;
48
- tools: readonly McpToolRecord[];
45
+ servers: readonly {
46
+ readonly agentId?: string;
47
+ readonly name: string;
48
+ }[];
49
49
  signal?: AbortSignal;
50
50
  }): Promise<McpDiagnostic[]>;
51
51
  call(input: {
@@ -59,6 +59,11 @@ export declare class McpPool {
59
59
  effectId?: string;
60
60
  /** The call's span context (R7.4), sent as `traceparent` on a connection this process holds. */
61
61
  traceparent?: string;
62
+ /**
63
+ * The largest answer kept on a connection this process holds: the Runtime limit
64
+ * `toolAnswerBytes` (`turn.start.limits`). The gates service reads its own.
65
+ */
66
+ maxResultBytes: number;
62
67
  signal?: AbortSignal;
63
68
  }): Promise<McpToolOutcome>;
64
69
  /** The session's connection to the server, opened when there is none, or why it cannot be. */
package/dist/mcp/pool.js CHANGED
@@ -1,8 +1,6 @@
1
1
  import { delegatesOf } from "@nylorun/core/define";
2
- import { callMcpTool, diagnosticFromError, listMcpTools, McpConnectionStale, openMcpServer, unreachable, } from "./connect.js";
3
- import { declaredToolNames, } from "./snapshot.js";
4
- /** A connection unused this long is closed by the sweep; the next call opens it again. */
5
- export const DEFAULT_MCP_IDLE_MS = 15 * 60_000;
2
+ import { callMcpTool, diagnosticFromError, listMcpTools, McpConnectionStale, unreachable, } from "./connect.js";
3
+ import { hostTuning } from "../tuning.js";
6
4
  export class McpPool {
7
5
  options;
8
6
  live = new Map();
@@ -10,18 +8,19 @@ export class McpPool {
10
8
  opening = new Map();
11
9
  idleMs;
12
10
  now;
13
- open;
14
11
  constructor(options) {
15
12
  this.options = options;
16
- this.idleMs = options.idleMs ?? DEFAULT_MCP_IDLE_MS;
13
+ this.idleMs = options.idleMs ?? hostTuning().harness.mcpIdleMs;
17
14
  this.now = options.now ?? Date.now;
18
- this.open = options.open ?? openMcpServer;
19
15
  }
16
+ /**
17
+ * Opens each declared server of the session and lists its tools (protocol 15): the snapshot
18
+ * holds every server that connected, with its instructions and its tools as it named them.
19
+ * Instructions past `maxInstructionBytes` (the Runtime limit `recordEntryBytes`) are left out,
20
+ * and the server's diagnostic says so.
21
+ */
20
22
  async discover(input) {
21
- // Each agent names its own tools, so collisions are checked per agent.
22
- const taken = new Map();
23
- const tools = [];
24
- const notes = [];
23
+ const servers = [];
25
24
  const diagnostics = [];
26
25
  for (const declared of serversOf(input.manifest)) {
27
26
  input.signal?.throwIfAborted();
@@ -31,20 +30,18 @@ export class McpPool {
31
30
  continue;
32
31
  }
33
32
  try {
34
- if (!taken.has(declared.agentId))
35
- taken.set(declared.agentId, declaredToolNames(declared.manifest));
36
33
  const listed = await listMcpTools(opened.connection.client, {
37
34
  serverName: declared.server.name,
38
- taken: taken.get(declared.agentId),
39
35
  server: declared.server,
40
36
  ...(input.signal ? { signal: input.signal } : {}),
41
37
  });
42
- tools.push(...listed.tools.map((tool) => owned(declared, tool)));
43
- if (opened.connection.instructions)
44
- notes.push(owned(declared, {
45
- serverName: declared.server.name,
46
- instructions: opened.connection.instructions,
47
- }));
38
+ const text = opened.connection.instructions;
39
+ const tooLong = text !== undefined && Buffer.byteLength(text) > input.maxInstructionBytes;
40
+ servers.push(owned(declared, {
41
+ name: declared.server.name,
42
+ ...(text === undefined || tooLong ? {} : { instructions: text }),
43
+ tools: listed.tools,
44
+ }));
48
45
  diagnostics.push({
49
46
  ...ownerOf(declared),
50
47
  serverName: declared.server.name,
@@ -55,8 +52,12 @@ export class McpPool {
55
52
  ...(listed.unknownTools.length === 0
56
53
  ? []
57
54
  : [`Its tools settings name tools it does not list: ${listed.unknownTools.join(", ")}`]),
55
+ ...(tooLong
56
+ ? [
57
+ `Its instructions are ${Buffer.byteLength(text)} bytes, more than a record entry holds (the Runtime limit recordEntryBytes, ${input.maxInstructionBytes} bytes), and are left out`,
58
+ ]
59
+ : []),
58
60
  ].join(". "),
59
- ...(listed.renamed.length === 0 ? {} : { renamed: listed.renamed }),
60
61
  ...(listed.disabled === 0 ? {} : { disabled: listed.disabled }),
61
62
  ...(listed.unknownTools.length === 0 ? {} : { unknownTools: listed.unknownTools }),
62
63
  });
@@ -68,20 +69,16 @@ export class McpPool {
68
69
  }
69
70
  }
70
71
  return {
71
- snapshot: {
72
- snapshotSchemaVersion: 1,
73
- manifestHash: input.manifestHash,
74
- mcpTools: tools,
75
- ...(notes.length === 0 ? {} : { servers: notes }),
76
- },
72
+ snapshot: { snapshotSchemaVersion: 2, manifestHash: input.manifestHash, servers },
77
73
  diagnostics,
78
74
  };
79
75
  }
76
+ /** Opens again each server of the snapshot this process holds no connection to. */
80
77
  async reconnect(input) {
81
78
  const diagnostics = [];
82
79
  const seen = new Set();
83
- for (const tool of input.tools) {
84
- const key = this.liveKey(input.sessionId, tool.agentId, tool.serverName);
80
+ for (const server of input.servers) {
81
+ const key = this.liveKey(input.sessionId, server.agentId, server.name);
85
82
  if (seen.has(key))
86
83
  continue;
87
84
  seen.add(key);
@@ -92,11 +89,11 @@ export class McpPool {
92
89
  continue;
93
90
  }
94
91
  input.signal?.throwIfAborted();
95
- const declared = findServer(input.manifest, tool.agentId, tool.serverName);
92
+ const declared = findServer(input.manifest, server.agentId, server.name);
96
93
  if (!declared) {
97
94
  diagnostics.push({
98
- ...(tool.agentId === undefined ? {} : { agentId: tool.agentId }),
99
- serverName: tool.serverName,
95
+ ...(server.agentId === undefined ? {} : { agentId: server.agentId }),
96
+ serverName: server.name,
100
97
  outcome: "failed",
101
98
  message: "Declared MCP server is missing from the pinned manifest",
102
99
  });
@@ -124,6 +121,7 @@ export class McpPool {
124
121
  ...(input.effectId === undefined ? {} : { key: input.effectId }),
125
122
  ...(input.signal ? { signal: input.signal } : {}),
126
123
  ...(input.traceparent === undefined ? {} : { traceparent: input.traceparent }),
124
+ maxResultBytes: input.maxResultBytes,
127
125
  });
128
126
  }
129
127
  catch (error) {
@@ -213,22 +211,10 @@ export class McpPool {
213
211
  }
214
212
  async connectDeclared(input, declared) {
215
213
  try {
216
- if (this.options.openRemote) {
217
- const connection = await this.options.openRemote({
218
- sessionId: input.sessionId,
219
- ...ownerOf(declared),
220
- serverName: declared.server.name,
221
- });
222
- return { ok: true, connection };
223
- }
224
- const connection = await this.open({
225
- server: declared.server,
226
- ...(this.options.policy ? { policy: this.options.policy } : {}),
227
- authorize: (url) => this.options.authorize(input.sessionId, {
228
- url,
229
- serverName: declared.server.name,
230
- ...ownerOf(declared),
231
- }),
214
+ const connection = await this.options.openRemote({
215
+ sessionId: input.sessionId,
216
+ ...ownerOf(declared),
217
+ serverName: declared.server.name,
232
218
  });
233
219
  return { ok: true, connection };
234
220
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * A remote MCP server's tools before an agent names it (R2b C12, `POST /v1/tenant/mcp/preview`,
3
- * `nylorun mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
3
+ * `nylorun tenant mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
4
4
  * the keys service (`keys/keys.ts`, `previewMcp`), in the gateway or in process.
5
5
  *
6
6
  * One connection: `initialize` and `tools/list` with the Environment's credential for the
@@ -8,19 +8,26 @@
8
8
  * It never calls a tool, and sends no identity header: no person asked. A server that answers
9
9
  * `401` is `authRequired`, with its RFC 9728 protected-resource metadata when it publishes any,
10
10
  * read under the same policy. No credential value sent is in the answer (`scrubValues`, C8).
11
+ *
12
+ * Each tool's `modelName` is the name Nylorun's engine would give it (`mcpToolNames` of
13
+ * `@nylorun/harness`, protocol 15): the Runtime itself names no tool, and a harness of your own
14
+ * names them its way.
11
15
  */
12
- import { type McpPreview, type McpPreviewRequest } from "@nylorun/core/contracts";
16
+ import { type McpPreview, type McpPreviewRequest, type RuntimeLimits } from "@nylorun/core/contracts";
13
17
  import { type OutboundPolicy } from "../tenant/outbound.js";
14
18
  import type { VaultService } from "../vault/service.js";
15
19
  import { openMcpServer } from "./connect.js";
16
- /** How long a preview may take, `initialize` and every `tools/list` page together. */
17
- export declare const MCP_PREVIEW_TIMEOUT_MS = 15000;
18
20
  export interface McpPreviewOptions {
19
21
  readonly vault: Pick<VaultService, "authorize" | "listEnvironmentSecrets">;
20
22
  /** The Host's address policy for developer URLs (`TenantConfig.delivery`). */
21
23
  readonly policy: OutboundPolicy;
22
- /** Default `MCP_PREVIEW_TIMEOUT_MS`. */
23
- readonly timeoutMs?: number;
24
+ /**
25
+ * The Tenant's Runtime limits a preview keeps to: `mcpPreviewMs` (how long it may take,
26
+ * `initialize` and every `tools/list` page together), `mcpMetadataBytes` (the largest
27
+ * protected-resource metadata document read) and `errorExcerptChars` (how much of a failure
28
+ * its message quotes).
29
+ */
30
+ readonly limits: Pick<RuntimeLimits, "mcpPreviewMs" | "mcpMetadataBytes" | "errorExcerptChars">;
24
31
  /** Tests replace how the server is opened. */
25
32
  readonly open?: typeof openMcpServer;
26
33
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * A remote MCP server's tools before an agent names it (R2b C12, `POST /v1/tenant/mcp/preview`,
3
- * `nylorun mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
3
+ * `nylorun tenant mcp inspect`, an Environment's Secrets tab in Studio). It runs where plaintext credentials live:
4
4
  * the keys service (`keys/keys.ts`, `previewMcp`), in the gateway or in process.
5
5
  *
6
6
  * One connection: `initialize` and `tools/list` with the Environment's credential for the
@@ -8,18 +8,21 @@
8
8
  * It never calls a tool, and sends no identity header: no person asked. A server that answers
9
9
  * `401` is `authRequired`, with its RFC 9728 protected-resource metadata when it publishes any,
10
10
  * read under the same policy. No credential value sent is in the answer (`scrubValues`, C8).
11
+ *
12
+ * Each tool's `modelName` is the name Nylorun's engine would give it (`mcpToolNames` of
13
+ * `@nylorun/harness`, protocol 15): the Runtime itself names no tool, and a harness of your own
14
+ * names them its way.
11
15
  */
12
16
  import { McpPreviewRequestSchema, } from "@nylorun/core/contracts";
17
+ import { schemaFromJSON } from "@nylorun/core/define";
18
+ import { mcpToolNames } from "@nylorun/harness";
13
19
  import { scrubValues } from "../redact.js";
14
20
  import { HttpError } from "../tenant/http.js";
15
21
  import { guardedFetch, OutboundRefused } from "../tenant/outbound.js";
16
22
  import { VaultError } from "../vault/error.js";
17
23
  import { credentialSecrets } from "../vault/headers.js";
18
24
  import { CredentialRejected, listMcpTools, McpCallFailed, openMcpServer, } from "./connect.js";
19
- /** How long a preview may take, `initialize` and every `tools/list` page together. */
20
- export const MCP_PREVIEW_TIMEOUT_MS = 15_000;
21
- /** The largest protected-resource metadata document read. */
22
- const RESOURCE_METADATA_MAX_BYTES = 64 * 1024;
25
+ import { MODEL_TOOL_NAME_MAX } from "@nylorun/core/define";
23
26
  /** Host labels that name a service's role rather than the service. */
24
27
  const GENERIC_LABELS = new Set(["mcp", "www", "api"]);
25
28
  /**
@@ -39,7 +42,7 @@ export function previewServerName(url) {
39
42
  named.shift();
40
43
  name = named.at(-1);
41
44
  }
42
- return name.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 64) || "server";
45
+ return name.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, MODEL_TOOL_NAME_MAX) || "server";
43
46
  }
44
47
  /** Lists the server's tools as an agent's session would see them; never calls one. */
45
48
  export async function previewMcpServer(body, options) {
@@ -51,7 +54,8 @@ export async function previewMcpServer(body, options) {
51
54
  const secrets = authorized.status === "authorized" ? credentialSecrets(authorized.headers) : [];
52
55
  const credentialSent = authorized.status === "authorized";
53
56
  const base = { name, url: request.url, type, credentialSent };
54
- const signal = AbortSignal.timeout(options.timeoutMs ?? MCP_PREVIEW_TIMEOUT_MS);
57
+ const { limits } = options;
58
+ const signal = AbortSignal.timeout(limits.mcpPreviewMs);
55
59
  const open = options.open ?? openMcpServer;
56
60
  let connection;
57
61
  try {
@@ -60,6 +64,7 @@ export async function previewMcpServer(body, options) {
60
64
  // Read once: one audit row, and the same credential for every request.
61
65
  authorize: async () => authorized,
62
66
  policy: options.policy,
67
+ errorExcerptChars: limits.errorExcerptChars,
63
68
  signal,
64
69
  });
65
70
  const pages = [];
@@ -71,12 +76,10 @@ export async function previewMcpServer(body, options) {
71
76
  },
72
77
  callTool: () => Promise.reject(new Error("A preview never calls a tool")),
73
78
  };
74
- const listed = await listMcpTools(listing, {
75
- serverName: name,
76
- taken: new Set(),
77
- signal,
78
- });
79
- const modelNames = new Map(listed.tools.map((tool) => [tool.serverToolName, tool.name]));
79
+ const listed = await listMcpTools(listing, { serverName: name, signal });
80
+ // The names Nylorun's engine gives the tools whose schemas it can use.
81
+ const named = mcpToolNames(name, listed.tools.filter((tool) => compiles(tool.inputSchema)).map((tool) => tool.name), new Set());
82
+ const modelNames = named.names;
80
83
  const tools = pages
81
84
  .flatMap((page) => page.tools)
82
85
  .filter((tool) => typeof tool.name === "string" && tool.name.length > 0)
@@ -99,7 +102,7 @@ export async function previewMcpServer(body, options) {
99
102
  ...(connection.serverInfo === undefined ? {} : { serverInfo: { ...connection.serverInfo } }),
100
103
  ...(connection.instructions === undefined ? {} : { instructions: connection.instructions }),
101
104
  tools,
102
- renamed: listed.renamed.map(({ serverToolName, name: renamedTo }) => ({
105
+ renamed: named.renamed.map(({ serverToolName, name: renamedTo }) => ({
103
106
  serverToolName,
104
107
  name: renamedTo,
105
108
  })),
@@ -108,10 +111,10 @@ export async function previewMcpServer(body, options) {
108
111
  }
109
112
  catch (error) {
110
113
  if (error instanceof CredentialRejected) {
111
- const authRequired = await protectedResource(request.url, error.challenge, options.policy, signal);
114
+ const authRequired = await protectedResource(request.url, error.challenge, options.policy, signal, limits);
112
115
  return scrubValues({ ...base, tools: [], renamed: [], authRequired }, secrets).value;
113
116
  }
114
- throw failed(name, error, signal, secrets, options.timeoutMs ?? MCP_PREVIEW_TIMEOUT_MS);
117
+ throw failed(name, error, signal, secrets, limits);
115
118
  }
116
119
  finally {
117
120
  await connection?.close().catch(() => undefined);
@@ -132,7 +135,8 @@ async function credentialFor(vault, request) {
132
135
  throw new HttpError(409, `Environment ${request.environmentId}'s credential for this URL cannot be used (${result.reason})`, { code: "request_rejected", details: { reason: result.reason, credentialIds: result.credentialIds } });
133
136
  }
134
137
  /** A preview that listed nothing: `mcp_preview_failed`, with the code a tool call would have had. */
135
- function failed(server, error, signal, secrets, timeoutMs) {
138
+ function failed(server, error, signal, secrets, limits) {
139
+ const timeoutMs = limits.mcpPreviewMs;
136
140
  if (error instanceof HttpError || error instanceof VaultError)
137
141
  return error;
138
142
  const failure = signal.aborted
@@ -145,7 +149,7 @@ function failed(server, error, signal, secrets, timeoutMs) {
145
149
  ? `The MCP server '${server}' was not called: ${refusedBy(error).message}`
146
150
  : `The MCP server '${server}' could not be listed: ${error instanceof Error ? error.message : String(error)}`,
147
151
  };
148
- const message = scrubValues(failure.message.slice(0, 2_000), secrets).value;
152
+ const message = scrubValues(failure.message.slice(0, limits.errorExcerptChars), secrets).value;
149
153
  return new HttpError(502, message, { code: "mcp_preview_failed", details: { failure: failure.code } });
150
154
  }
151
155
  /** The Host's refusal of the address, when that is why the server was not reached. */
@@ -159,7 +163,7 @@ function refusedBy(error) {
159
163
  * `resource_metadata`, else the one at the URL's well-known path (with the URL's path, then at
160
164
  * the origin). Absent fields when the server publishes none.
161
165
  */
162
- async function protectedResource(url, challenge, policy, signal) {
166
+ async function protectedResource(url, challenge, policy, signal, limits) {
163
167
  const named = challenge === undefined ? undefined : resourceMetadataParam(challenge);
164
168
  const target = new URL(url);
165
169
  const wellKnown = "/.well-known/oauth-protected-resource";
@@ -167,7 +171,10 @@ async function protectedResource(url, challenge, policy, signal) {
167
171
  const candidates = named
168
172
  ? [named]
169
173
  : [...(path ? [`${target.origin}${wellKnown}${path}`] : []), `${target.origin}${wellKnown}`];
170
- const fetchMetadata = guardedFetch(policy, { maxResponseBytes: RESOURCE_METADATA_MAX_BYTES });
174
+ const fetchMetadata = guardedFetch(policy, {
175
+ maxResponseBytes: limits.mcpMetadataBytes,
176
+ timeoutMs: limits.mcpPreviewMs,
177
+ });
171
178
  for (const candidate of candidates) {
172
179
  let resolved;
173
180
  try {
@@ -199,6 +206,16 @@ function resourceMetadataParam(challenge) {
199
206
  const value = match?.[1] ?? match?.[2];
200
207
  return value ? value : undefined;
201
208
  }
209
+ /** True when Nylorun's engine can check calls against `schema`. */
210
+ function compiles(schema) {
211
+ try {
212
+ schemaFromJSON(schema);
213
+ return true;
214
+ }
215
+ catch {
216
+ return false;
217
+ }
218
+ }
202
219
  function isRecord(value) {
203
220
  return !!value && typeof value === "object" && !Array.isArray(value);
204
221
  }
@@ -1,38 +1,15 @@
1
+ /**
2
+ * A session's MCP snapshot (protocol 15): what its remote MCP servers listed at discovery, raw
3
+ * (`McpSnapshot`, `@nylorun/core/harness-api`), pinned on the session. The Runtime never names a
4
+ * tool for the model: it states facts per turn (`mcpFactsOf`, `turn.start.mcp`), and checks a
5
+ * call by its identity (`{server, tool}` of its agent): discovered (`mcpToolIn`) and left enabled
6
+ * by the turn's manifest (`isEnabledIn`, R2b C9).
7
+ */
1
8
  import type { EventPayload } from "@nylorun/core/contracts";
2
- import type { JsonObject } from "@nylorun/core/define";
3
9
  import { type AgentManifest, type ResolvedMcpToolSettings } from "@nylorun/core/define";
4
- import type { DurableSessionTool, HostEffect } from "@nylorun/harness/run";
5
- export interface McpToolRecord {
6
- /** The agent used as a tool that declares the server; absent for the session's root agent. */
7
- readonly agentId?: string;
8
- readonly serverName: string;
9
- /** The tool's name on its server, which the call sends. */
10
- readonly serverToolName: string;
11
- /** The name the model knows it by (`normalizeToolName`). */
12
- readonly name: string;
13
- readonly description?: string;
14
- readonly inputSchema: JsonObject;
15
- readonly outputSchema?: JsonObject;
16
- /**
17
- * Out of the model's tool list for the session's life (R2b C10): core decides it once, when it
18
- * records the snapshot (`pinDeferral`), so every model call of the session lists the same tools.
19
- */
20
- readonly deferred?: true;
21
- }
22
- /** A server's own instructions (MCP `initialize`), for the note on its deferred tools (R2b C10). */
23
- export interface McpServerNote {
24
- readonly agentId?: string;
25
- readonly serverName: string;
26
- /** Cut to `SERVER_INSTRUCTIONS_MAX_CHARS`. */
27
- readonly instructions: string;
28
- }
29
- export interface McpSnapshot {
30
- readonly snapshotSchemaVersion: 1;
31
- readonly manifestHash: string;
32
- readonly mcpTools: readonly McpToolRecord[];
33
- /** The servers that gave instructions; absent when none did. */
34
- readonly servers?: readonly McpServerNote[];
35
- }
10
+ import type { McpFacts, McpSnapshot, McpToolRecord } from "@nylorun/core/harness-api";
11
+ import type { HostEffect } from "@nylorun/harness/run";
12
+ export type { McpFacts, McpServerRecord, McpSnapshot, McpToolRecord } from "@nylorun/core/harness-api";
36
13
  export interface McpDiagnostic {
37
14
  /** The agent used as a tool that declares the server; absent for the session's root agent. */
38
15
  readonly agentId?: string;
@@ -40,69 +17,41 @@ export interface McpDiagnostic {
40
17
  readonly outcome: "connected" | "refused" | "failed";
41
18
  readonly message: string;
42
19
  readonly credentialIds?: readonly string[];
43
- /** Tools the model knows by another name than `server__tool` (R2b C6). */
44
- readonly renamed?: readonly McpRenamedTool[];
45
20
  /** How many listed tools the server's `tools` settings disable (R2b C9). */
46
21
  readonly disabled?: number;
47
22
  /** Keys of the server's `tools` settings that name no tool it listed (R2b C9). */
48
23
  readonly unknownTools?: readonly string[];
49
24
  }
50
- /** A tool whose model-facing name is not `server__tool` (`normalizeToolName`). */
51
- export interface McpRenamedTool {
52
- readonly serverToolName: string;
53
- readonly name: string;
54
- }
55
25
  /**
56
- * The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot,
57
- * and the Agent Plugin that brought the server (from `manifest`, the session's pinned one).
26
+ * The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot
27
+ * that its settings in `manifest` (the session's pinned one) leave enabled, and the Agent Plugin
28
+ * that brought the server.
58
29
  */
59
30
  export declare function mcpDiscovered(snapshot: McpSnapshot, diagnostics: readonly McpDiagnostic[], manifest?: AgentManifest): EventPayload<"mcp.discovered">;
60
- /** The longest tool name every model provider accepts (R2b C6, Q14). */
61
- export declare const MODEL_TOOL_NAME_MAX = 64;
62
- /**
63
- * The name the model knows an MCP tool by (R2b C6, Q13): `server__tool`, with each character
64
- * outside `[A-Za-z0-9_-]` replaced by `_`, since MCP allows `.` and 128 characters and OpenAI,
65
- * Bedrock and Gemini on Vertex do not. A name over 64 characters, or one that collides
66
- * (`suffixed`), keeps 55 and adds `_` and 8 hex characters of the SHA-256 of the raw
67
- * `server/tool`.
68
- */
69
- export declare function normalizeToolName(serverName: string, serverToolName: string, options?: {
70
- readonly suffixed?: boolean;
71
- }): string;
72
- /** The names of the agent's tools: its own and those the Runtime pinned. */
73
- export declare function declaredToolNames(manifest: AgentManifest): Set<string>;
31
+ /** The tool `tool` of server `server` of agent `agentId` (the root when absent), as discovered. */
32
+ export declare function mcpToolIn(snapshot: McpSnapshot | undefined, agentId: string | undefined, server: string, tool: string): McpToolRecord | undefined;
74
33
  /** The tool's settings in `manifest` (R2b C9); the defaults when its server is not there. */
75
- export declare function mcpToolSettingsIn(manifest: AgentManifest, tool: McpToolRecord): ResolvedMcpToolSettings;
76
- /**
77
- * The tools of a snapshot, as the engine gets them for a turn whose manifest is `manifest` (the
78
- * session's pin, or a turn variant that tightened its MCP servers' tools):
79
- *
80
- * - a tool its settings disable is left out (R2b C9); the Tool Gate holds a call its approval
81
- * or the Tenant's tool policy asks a person about (R5 step 2);
82
- * - a deferred tool (R2b C10) is marked so, out of the model's list, and its agent gets the
83
- * session tools `tool_search`, with the note on the servers it holds deferred tools of, and
84
- * `tool_call`. Their names are reserved: no tool of the agent's own takes them.
85
- *
86
- * Nothing here changes between the steps of a turn, so neither does the model's tool list.
87
- */
88
- export declare function sessionToolsOf(snapshot: McpSnapshot | undefined, manifest: AgentManifest): readonly DurableSessionTool[] | undefined;
89
- /** The share of the model's context window past which an agent's MCP tools are deferred (Q21). */
90
- export declare const DEFER_CONTEXT_SHARE = 0.1;
91
- /** Characters per token, to estimate what tool definitions take of a context window (Q21). */
92
- export declare const CHARS_PER_TOKEN = 4;
93
- /**
94
- * The snapshot with its deferred tools marked (R2b C10, Q21), decided once for the session when
95
- * core records it. A tool's own setting, then `"*"`'s, then its server's, decides; a tool none
96
- * sets is deferred when the JSON of its agent's MCP tools that would be listed passes a tenth of
97
- * the model's context window (`contextWindow` tokens, at 4 characters a token).
98
- */
99
- export declare function pinDeferral(snapshot: McpSnapshot, manifest: AgentManifest, contextWindow: number): McpSnapshot;
34
+ export declare function mcpToolSettingsIn(manifest: AgentManifest, agentId: string | undefined, server: string, tool: string): ResolvedMcpToolSettings;
35
+ /** True when the tool's settings in `manifest` leave it enabled (R2b C9). */
36
+ export declare function isEnabledIn(manifest: AgentManifest, agentId: string | undefined, server: string, tool: string): boolean;
100
37
  /**
101
- * The snapshot's record of an MCP tool call, or undefined when the call is not an MCP tool. With
102
- * the turn's `manifest`, a tool its settings disable is not one either (R2b C9).
38
+ * The snapshot's facts for a turn whose manifest is `manifest` (the session's pin, or a turn
39
+ * variant that tightened its MCP servers' tools): each tool with whether its settings leave it
40
+ * `enabled` and, when they say, whether to defer it. A server the turn's manifest no longer
41
+ * declares is left out.
103
42
  */
104
- export declare function mcpToolOf(snapshot: McpSnapshot | undefined, request: Pick<HostEffect, "agent" | "toolName">, manifest?: AgentManifest): McpToolRecord | undefined;
105
- /** True when the tool's settings in `manifest` leave it enabled (R2b C9). */
106
- export declare function isEnabledIn(manifest: AgentManifest, tool: McpToolRecord): boolean;
43
+ export declare function mcpFactsOf(snapshot: McpSnapshot, manifest: AgentManifest): McpFacts;
107
44
  /** The manifest of the agent an effect belongs to: the root, or an agent it uses as a tool. */
108
45
  export declare function manifestFor(manifest: AgentManifest, agent: HostEffect["agent"]): AgentManifest | undefined;
46
+ /**
47
+ * `snapshot` within the Tenant's Runtime limit `mcpSnapshotBytes` (its JSON, which every
48
+ * `turn.start.mcp` carries): its servers in order while they fit. A server that does not is left
49
+ * out, so the session never offers its tools, and its diagnostic says so (`failed`, replacing
50
+ * the one it had). Unchanged when the whole snapshot fits.
51
+ */
52
+ export declare function fitSnapshot(snapshot: McpSnapshot, diagnostics: readonly McpDiagnostic[], limitBytes: number): {
53
+ snapshot: McpSnapshot;
54
+ diagnostics: McpDiagnostic[];
55
+ };
56
+ /** True for a snapshot of the shape this Runtime pins (`snapshotSchemaVersion` 2). */
57
+ export declare function isSnapshot(value: unknown): value is McpSnapshot;