@nylorun/runtime 0.23.0-beta → 0.25.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 (301) hide show
  1. package/CHANGELOG.md +252 -0
  2. package/README.md +87 -28
  3. package/dist/adapters/execution/restate.js +1 -1
  4. package/dist/adapters/replication/pgoutput.d.ts +2 -0
  5. package/dist/adapters/replication/pgoutput.js +6 -3
  6. package/dist/adapters/sandbox/local.d.ts +9 -1
  7. package/dist/adapters/sandbox/local.js +16 -4
  8. package/dist/adapters/sandbox/virtual.js +4 -1
  9. package/dist/api/a2a/card.d.ts +11 -1
  10. package/dist/api/a2a/card.js +26 -2
  11. package/dist/api/a2a/endpoint.js +9 -3
  12. package/dist/api/a2a/protocol.d.ts +25 -2
  13. package/dist/api/a2a/protocol.js +20 -3
  14. package/dist/api/a2a/routes.d.ts +6 -1
  15. package/dist/api/a2a/routes.js +67 -9
  16. package/dist/api/a2a/tasks.js +2 -1
  17. package/dist/api/ag-ui/endpoint.js +8 -3
  18. package/dist/api/ag-ui/history.d.ts +6 -1
  19. package/dist/api/ag-ui/history.js +39 -3
  20. package/dist/api/ag-ui/routes.d.ts +4 -1
  21. package/dist/api/ag-ui/routes.js +63 -20
  22. package/dist/api/ag-ui/translate.js +3 -2
  23. package/dist/api/components.d.ts +5327 -1091
  24. package/dist/api/components.js +40 -16
  25. package/dist/api/gate/keys.d.ts +2 -1
  26. package/dist/api/gate/keys.js +14 -1
  27. package/dist/api/gate/routes.d.ts +6 -0
  28. package/dist/api/gate/routes.js +52 -3
  29. package/dist/api/http/app.js +17 -6
  30. package/dist/api/http/body.d.ts +3 -3
  31. package/dist/api/http/body.js +7 -7
  32. package/dist/api/http/define.d.ts +6 -0
  33. package/dist/api/http/define.js +13 -1
  34. package/dist/api/http/respond.js +1 -1
  35. package/dist/api/http/routes/artifacts.js +35 -8
  36. package/dist/api/http/routes/coverage.d.ts +9 -0
  37. package/dist/api/http/routes/coverage.js +34 -0
  38. package/dist/api/http/routes/environment-manifests.d.ts +9 -0
  39. package/dist/api/http/routes/environment-manifests.js +118 -0
  40. package/dist/api/http/routes/environments.d.ts +11 -0
  41. package/dist/api/http/routes/environments.js +332 -0
  42. package/dist/api/http/routes/mcp.d.ts +1 -1
  43. package/dist/api/http/routes/mcp.js +2 -2
  44. package/dist/api/http/routes/me.js +1 -1
  45. package/dist/api/http/routes/reads.d.ts +94 -9
  46. package/dist/api/http/routes/reads.js +54 -5
  47. package/dist/api/http/routes/sessions.js +24 -9
  48. package/dist/api/http/routes/tenant.js +65 -15
  49. package/dist/api/inbound-files.d.ts +65 -0
  50. package/dist/api/inbound-files.js +115 -0
  51. package/dist/api/openapi.js +48 -28
  52. package/dist/artifacts/disk.d.ts +59 -0
  53. package/dist/artifacts/disk.js +569 -0
  54. package/dist/artifacts/export.d.ts +1 -1
  55. package/dist/artifacts/export.js +2 -3
  56. package/dist/artifacts/folders.d.ts +6 -3
  57. package/dist/artifacts/folders.js +17 -12
  58. package/dist/artifacts/media-types.d.ts +15 -0
  59. package/dist/artifacts/media-types.js +56 -4
  60. package/dist/artifacts/parts.d.ts +12 -3
  61. package/dist/artifacts/parts.js +15 -4
  62. package/dist/artifacts/service.d.ts +2 -1
  63. package/dist/artifacts/service.js +6 -1
  64. package/dist/artifacts/workspace.d.ts +5 -5
  65. package/dist/artifacts/workspace.js +7 -19
  66. package/dist/core/flow-host.d.ts +3 -4
  67. package/dist/core/flow-host.js +5 -2
  68. package/dist/core/provider.d.ts +3 -2
  69. package/dist/core/provider.js +5 -37
  70. package/dist/core/sandbox-routes.d.ts +2 -21
  71. package/dist/core/sandbox-routes.js +11 -44
  72. package/dist/core/turn-manifest.d.ts +3 -2
  73. package/dist/core/turn-manifest.js +29 -5
  74. package/dist/execution/types.d.ts +1 -1
  75. package/dist/gates/contract.d.ts +3 -24
  76. package/dist/gates/contract.js +1 -36
  77. package/dist/gates/egress-credentials.d.ts +9 -0
  78. package/dist/gates/egress-credentials.js +11 -4
  79. package/dist/gates/egress.d.ts +22 -1
  80. package/dist/gates/egress.js +116 -10
  81. package/dist/gates/fixture-model.d.ts +28 -0
  82. package/dist/gates/fixture-model.js +92 -0
  83. package/dist/gates/handler.js +4 -4
  84. package/dist/gates/http-tool.d.ts +9 -6
  85. package/dist/gates/http-tool.js +11 -17
  86. package/dist/gates/in-process.d.ts +5 -0
  87. package/dist/gates/in-process.js +12 -1
  88. package/dist/gates/journal.d.ts +30 -0
  89. package/dist/gates/journal.js +51 -0
  90. package/dist/gates/mcp-handler.d.ts +4 -0
  91. package/dist/gates/mcp-handler.js +7 -4
  92. package/dist/gates/meter.d.ts +10 -2
  93. package/dist/gates/meter.js +20 -5
  94. package/dist/gates/policy.d.ts +49 -0
  95. package/dist/gates/policy.js +132 -0
  96. package/dist/gates/tenant-vaults.d.ts +7 -7
  97. package/dist/gates/tenant-vaults.js +5 -5
  98. package/dist/gates/tool-calls.d.ts +10 -5
  99. package/dist/gates/tool-calls.js +28 -10
  100. package/dist/gates/tool-client.d.ts +8 -0
  101. package/dist/gates/tool-client.js +27 -11
  102. package/dist/gates/tool-contract.d.ts +11 -69
  103. package/dist/gates/tool-contract.js +1 -85
  104. package/dist/gates/tool-gate.d.ts +1 -1
  105. package/dist/harness/calls.d.ts +14 -7
  106. package/dist/harness/calls.js +30 -24
  107. package/dist/harness/executors.js +12 -9
  108. package/dist/harness/main.js +24 -5
  109. package/dist/harness/pod.d.ts +39 -0
  110. package/dist/harness/pod.js +46 -0
  111. package/dist/harness/service.d.ts +0 -1
  112. package/dist/harness/service.js +17 -9
  113. package/dist/harness/setup.d.ts +29 -0
  114. package/dist/harness/setup.js +174 -0
  115. package/dist/harness/ws-client.js +3 -2
  116. package/dist/harness/ws-port.d.ts +1 -5
  117. package/dist/harness/ws-port.js +1 -5
  118. package/dist/harness-api/in-process.js +3 -3
  119. package/dist/harness-api/record.d.ts +15 -1
  120. package/dist/harness-api/record.js +180 -50
  121. package/dist/harness-api/redact.d.ts +3 -0
  122. package/dist/harness-api/redact.js +45 -0
  123. package/dist/harness-api/server.d.ts +35 -4
  124. package/dist/harness-api/server.js +130 -17
  125. package/dist/harness-api/start.d.ts +10 -3
  126. package/dist/harness-api/start.js +40 -10
  127. package/dist/harness-api/tool-journal.d.ts +105 -0
  128. package/dist/harness-api/tool-journal.js +132 -0
  129. package/dist/harness-api/tool-status.d.ts +13 -0
  130. package/dist/harness-api/tool-status.js +26 -0
  131. package/dist/harness-api/workspace.d.ts +12 -7
  132. package/dist/harness-api/workspace.js +47 -25
  133. package/dist/harness-api/ws-server.d.ts +11 -3
  134. package/dist/harness-api/ws-server.js +94 -15
  135. package/dist/host/gates.d.ts +2 -1
  136. package/dist/host/gates.js +10 -2
  137. package/dist/host/main.js +54 -5
  138. package/dist/host/operate.js +67 -5
  139. package/dist/host/stack-config.d.ts +64 -0
  140. package/dist/host/stack-config.js +62 -2
  141. package/dist/keys/client.js +4 -1
  142. package/dist/keys/keys.d.ts +13 -6
  143. package/dist/keys/keys.js +9 -8
  144. package/dist/management-openapi.json +1264 -2171
  145. package/dist/mcp/connect.d.ts +26 -22
  146. package/dist/mcp/connect.js +30 -34
  147. package/dist/mcp/pool.d.ts +3 -6
  148. package/dist/mcp/pool.js +14 -28
  149. package/dist/mcp/preview.d.ts +3 -3
  150. package/dist/mcp/preview.js +10 -21
  151. package/dist/mcp/snapshot.d.ts +16 -24
  152. package/dist/mcp/snapshot.js +33 -45
  153. package/dist/model/capabilities.d.ts +26 -0
  154. package/dist/model/capabilities.js +44 -0
  155. package/dist/model/catalog.d.ts +34 -3
  156. package/dist/model/catalog.js +38 -2
  157. package/dist/model/models.d.ts +2 -0
  158. package/dist/model/models.js +1 -1
  159. package/dist/model/native-blocks.d.ts +35 -0
  160. package/dist/model/native-blocks.js +170 -0
  161. package/dist/model/pi-model.js +114 -94
  162. package/dist/openapi.json +12822 -3943
  163. package/dist/reads/types.d.ts +16 -3
  164. package/dist/record/append.d.ts +3 -1
  165. package/dist/record/append.js +1 -0
  166. package/dist/record/envelope.d.ts +5 -1
  167. package/dist/record/envelope.js +7 -3
  168. package/dist/record/environment.d.ts +25 -0
  169. package/dist/record/environment.js +44 -0
  170. package/dist/record/index.d.ts +1 -1
  171. package/dist/record/index.js +1 -1
  172. package/dist/sandbox/disk-fs.d.ts +95 -0
  173. package/dist/sandbox/disk-fs.js +206 -0
  174. package/dist/sandbox/join.d.ts +17 -18
  175. package/dist/sandbox/join.js +46 -15
  176. package/dist/sandbox/manager.d.ts +47 -21
  177. package/dist/sandbox/manager.js +162 -107
  178. package/dist/sandbox/placement.d.ts +14 -13
  179. package/dist/sandbox/placement.js +31 -14
  180. package/dist/sandbox/pods/client.d.ts +9 -2
  181. package/dist/sandbox/pods/lifecycle.d.ts +36 -27
  182. package/dist/sandbox/pods/lifecycle.js +29 -26
  183. package/dist/sandbox/pods/reconcile.js +18 -12
  184. package/dist/sandbox/pods/spec.d.ts +15 -13
  185. package/dist/sandbox/pods/spec.js +17 -20
  186. package/dist/sandbox/records.d.ts +2 -2
  187. package/dist/sandbox/records.js +3 -3
  188. package/dist/sandbox/resolve.d.ts +37 -27
  189. package/dist/sandbox/resolve.js +73 -41
  190. package/dist/sandbox/runtime-tools.d.ts +9 -0
  191. package/dist/sandbox/runtime-tools.js +16 -0
  192. package/dist/sandbox/session-sandbox.d.ts +4 -6
  193. package/dist/sandbox/session-sandbox.js +47 -94
  194. package/dist/sandbox/setup.d.ts +64 -0
  195. package/dist/sandbox/setup.js +160 -0
  196. package/dist/sandbox/share.d.ts +21 -26
  197. package/dist/sandbox/share.js +36 -63
  198. package/dist/sandbox/skills.d.ts +8 -6
  199. package/dist/sandbox/skills.js +24 -23
  200. package/dist/sandbox/tenant-config.d.ts +12 -14
  201. package/dist/sandbox/tenant-config.js +12 -17
  202. package/dist/sandbox/types.d.ts +6 -0
  203. package/dist/store/postgres/drizzle/0020_environments.sql +63 -0
  204. package/dist/store/postgres/drizzle/0021_disk_versions.sql +7 -0
  205. package/dist/store/postgres/drizzle/0022_model_usage_timing.sql +5 -0
  206. package/dist/store/postgres/drizzle/0023_artifact_pages.sql +1 -0
  207. package/dist/store/postgres/drizzle/0024_flat_manifest.sql +7 -0
  208. package/dist/store/postgres/drizzle/0025_environment_manifests.sql +14 -0
  209. package/dist/store/postgres/drizzle/0026_environment_forks.sql +1 -0
  210. package/dist/store/postgres/drizzle/0027_environment_image_digest.sql +1 -0
  211. package/dist/store/postgres/drizzle/meta/_journal.json +56 -0
  212. package/dist/store/postgres/reads.js +123 -17
  213. package/dist/store/postgres/record-writer.d.ts +4 -4
  214. package/dist/store/postgres/record-writer.js +9 -9
  215. package/dist/store/postgres/record.d.ts +7 -0
  216. package/dist/store/postgres/record.js +23 -2
  217. package/dist/store/postgres/schema.d.ts +1126 -736
  218. package/dist/store/postgres/schema.js +136 -73
  219. package/dist/store/postgres/store.js +195 -67
  220. package/dist/store/types.d.ts +165 -50
  221. package/dist/tenant/advance.d.ts +7 -6
  222. package/dist/tenant/advance.js +118 -42
  223. package/dist/tenant/artifact-tool.d.ts +1 -1
  224. package/dist/tenant/artifact-tool.js +46 -26
  225. package/dist/tenant/commands.d.ts +15 -2
  226. package/dist/tenant/commands.js +115 -14
  227. package/dist/tenant/context.d.ts +56 -24
  228. package/dist/tenant/context.js +4 -15
  229. package/dist/tenant/effects.d.ts +1 -1
  230. package/dist/tenant/effects.js +44 -29
  231. package/dist/tenant/environment-manifests.d.ts +57 -0
  232. package/dist/tenant/environment-manifests.js +200 -0
  233. package/dist/tenant/environments.d.ts +174 -0
  234. package/dist/tenant/environments.js +1044 -0
  235. package/dist/tenant/harness-tokens.d.ts +21 -0
  236. package/dist/tenant/harness-tokens.js +61 -0
  237. package/dist/tenant/host-token.d.ts +1 -1
  238. package/dist/tenant/host-token.js +2 -4
  239. package/dist/tenant/identity-file.d.ts +4 -4
  240. package/dist/tenant/identity-file.js +17 -8
  241. package/dist/tenant/issuers.js +3 -3
  242. package/dist/tenant/model-setting.d.ts +14 -0
  243. package/dist/tenant/model-setting.js +51 -0
  244. package/dist/tenant/principals.js +1 -1
  245. package/dist/tenant/reset.js +3 -3
  246. package/dist/tenant/runtime.d.ts +6 -1
  247. package/dist/tenant/runtime.js +7 -1
  248. package/dist/tenant/session.d.ts +3 -3
  249. package/dist/tenant/session.js +0 -14
  250. package/dist/tenant/sessions.d.ts +18 -14
  251. package/dist/tenant/sessions.js +99 -143
  252. package/dist/tenant/signing-keys.d.ts +5 -1
  253. package/dist/tenant/skill-tool.d.ts +3 -3
  254. package/dist/tenant/skill-tool.js +6 -11
  255. package/dist/tenant/status.js +3 -3
  256. package/dist/tenant/sweep.js +13 -7
  257. package/dist/tenant/tool-results.js +1 -1
  258. package/dist/tenant/tool-search.d.ts +7 -11
  259. package/dist/tenant/tool-search.js +8 -5
  260. package/dist/tenant/transcript.d.ts +245 -36
  261. package/dist/tenant/transcript.js +64 -12
  262. package/dist/tenant/turn-timing.d.ts +43 -0
  263. package/dist/tenant/turn-timing.js +39 -0
  264. package/dist/tenant/types.d.ts +2 -0
  265. package/dist/traces/ids.d.ts +41 -0
  266. package/dist/traces/ids.js +81 -0
  267. package/dist/traces/key.d.ts +6 -0
  268. package/dist/traces/key.js +37 -0
  269. package/dist/traces/map.d.ts +113 -0
  270. package/dist/traces/map.js +289 -0
  271. package/dist/traces/options.d.ts +7 -0
  272. package/dist/traces/options.js +1 -0
  273. package/dist/traces/otlp.d.ts +42 -0
  274. package/dist/traces/otlp.js +84 -0
  275. package/dist/traces/projector.d.ts +58 -0
  276. package/dist/traces/projector.js +200 -0
  277. package/dist/traces/read.d.ts +23 -0
  278. package/dist/traces/read.js +16 -0
  279. package/dist/vault/coverage.d.ts +26 -0
  280. package/dist/vault/coverage.js +62 -0
  281. package/dist/vault/error.d.ts +11 -1
  282. package/dist/vault/error.js +5 -1
  283. package/dist/vault/host-model.d.ts +4 -1
  284. package/dist/vault/host-model.js +10 -2
  285. package/dist/vault/service.d.ts +92 -48
  286. package/dist/vault/service.js +462 -376
  287. package/dist/vault/sources.d.ts +5 -16
  288. package/dist/vault/sources.js +6 -8
  289. package/dist/version.d.ts +1 -1
  290. package/dist/version.js +2 -2
  291. package/package.json +13 -13
  292. package/dist/api/http/routes/sandboxes.d.ts +0 -9
  293. package/dist/api/http/routes/sandboxes.js +0 -153
  294. package/dist/api/http/routes/vaults.d.ts +0 -10
  295. package/dist/api/http/routes/vaults.js +0 -139
  296. package/dist/record/sandbox.d.ts +0 -25
  297. package/dist/record/sandbox.js +0 -43
  298. package/dist/sandbox/capability.d.ts +0 -3
  299. package/dist/sandbox/capability.js +0 -10
  300. package/dist/tenant/sandboxes.d.ts +0 -123
  301. package/dist/tenant/sandboxes.js +0 -566
@@ -1,11 +1,10 @@
1
1
  import type { EventPayload } from "@nylorun/core/contracts";
2
2
  import type { JsonObject } from "@nylorun/core/define";
3
- import { type AgentManifest } from "@nylorun/core/define";
3
+ import { type AgentManifest, type ResolvedMcpToolSettings } from "@nylorun/core/define";
4
4
  import type { DurableSessionTool, HostEffect } from "@nylorun/harness/run";
5
5
  export interface McpToolRecord {
6
6
  /** The agent used as a tool that declares the server; absent for the session's root agent. */
7
7
  readonly agentId?: string;
8
- readonly capabilityId: string;
9
8
  readonly serverName: string;
10
9
  /** The tool's name on its server, which the call sends. */
11
10
  readonly serverToolName: string;
@@ -14,14 +13,6 @@ export interface McpToolRecord {
14
13
  readonly description?: string;
15
14
  readonly inputSchema: JsonObject;
16
15
  readonly outputSchema?: JsonObject;
17
- /**
18
- * The server's hints that calling the tool again is safe (R2b C7, Q15): a call whose answer
19
- * was lost after it was sent is then `mcp.lost` to the model, not `uncertain`.
20
- */
21
- readonly annotations?: {
22
- readonly readOnlyHint?: boolean;
23
- readonly idempotentHint?: boolean;
24
- };
25
16
  /**
26
17
  * Out of the model's tool list for the session's life (R2b C10): core decides it once, when it
27
18
  * records the snapshot (`pinDeferral`), so every model call of the session lists the same tools.
@@ -31,7 +22,6 @@ export interface McpToolRecord {
31
22
  /** A server's own instructions (MCP `initialize`), for the note on its deferred tools (R2b C10). */
32
23
  export interface McpServerNote {
33
24
  readonly agentId?: string;
34
- readonly capabilityId: string;
35
25
  readonly serverName: string;
36
26
  /** Cut to `SERVER_INSTRUCTIONS_MAX_CHARS`. */
37
27
  readonly instructions: string;
@@ -46,7 +36,6 @@ export interface McpSnapshot {
46
36
  export interface McpDiagnostic {
47
37
  /** The agent used as a tool that declares the server; absent for the session's root agent. */
48
38
  readonly agentId?: string;
49
- readonly capabilityId: string;
50
39
  readonly serverName: string;
51
40
  readonly outcome: "connected" | "refused" | "failed";
52
41
  readonly message: string;
@@ -63,8 +52,11 @@ export interface McpRenamedTool {
63
52
  readonly serverToolName: string;
64
53
  readonly name: string;
65
54
  }
66
- /** The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot. */
67
- export declare function mcpDiscovered(snapshot: McpSnapshot, diagnostics: readonly McpDiagnostic[]): EventPayload<"mcp.discovered">;
55
+ /**
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).
58
+ */
59
+ export declare function mcpDiscovered(snapshot: McpSnapshot, diagnostics: readonly McpDiagnostic[], manifest?: AgentManifest): EventPayload<"mcp.discovered">;
68
60
  /** The longest tool name every model provider accepts (R2b C6, Q14). */
69
61
  export declare const MODEL_TOOL_NAME_MAX = 64;
70
62
  /**
@@ -77,17 +69,19 @@ export declare const MODEL_TOOL_NAME_MAX = 64;
77
69
  export declare function normalizeToolName(serverName: string, serverToolName: string, options?: {
78
70
  readonly suffixed?: boolean;
79
71
  }): string;
72
+ /** The names of the agent's tools: its own and those the Runtime pinned. */
80
73
  export declare function declaredToolNames(manifest: AgentManifest): Set<string>;
74
+ /** 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;
81
76
  /**
82
77
  * The tools of a snapshot, as the engine gets them for a turn whose manifest is `manifest` (the
83
78
  * session's pin, or a turn variant that tightened its MCP servers' tools):
84
79
  *
85
- * - a tool its settings disable is left out (R2b C9); one whose approval resolves to `always`
86
- * waits for approval on each call;
87
- * - a deferred tool (R2b C10) is marked so, out of the model's list, and its agent gets
88
- * `tool_search`, with the note on the servers it holds deferred tools of, and `tool_call` in
89
- * its `nylorun.tools` capability. An agent whose turn has no such capability keeps its tools in
90
- * its list.
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.
91
85
  *
92
86
  * Nothing here changes between the steps of a turn, so neither does the model's tool list.
93
87
  */
@@ -100,16 +94,14 @@ export declare const CHARS_PER_TOKEN = 4;
100
94
  * The snapshot with its deferred tools marked (R2b C10, Q21), decided once for the session when
101
95
  * core records it. A tool's own setting, then `"*"`'s, then its server's, decides; a tool none
102
96
  * sets is deferred when the JSON of its agent's MCP tools that would be listed passes a tenth of
103
- * the model's context window (`contextWindow` tokens, at 4 characters a token). An agent without
104
- * the `nylorun.tools` capability (its definition names a tool `tool_search` or `tool_call`, or the
105
- * session was opened before it existed) defers nothing.
97
+ * the model's context window (`contextWindow` tokens, at 4 characters a token).
106
98
  */
107
99
  export declare function pinDeferral(snapshot: McpSnapshot, manifest: AgentManifest, contextWindow: number): McpSnapshot;
108
100
  /**
109
101
  * The snapshot's record of an MCP tool call, or undefined when the call is not an MCP tool. With
110
102
  * the turn's `manifest`, a tool its settings disable is not one either (R2b C9).
111
103
  */
112
- export declare function mcpToolOf(snapshot: McpSnapshot | undefined, request: Pick<HostEffect, "agent" | "capabilityId" | "toolName">, manifest?: AgentManifest): McpToolRecord | undefined;
104
+ export declare function mcpToolOf(snapshot: McpSnapshot | undefined, request: Pick<HostEffect, "agent" | "toolName">, manifest?: AgentManifest): McpToolRecord | undefined;
113
105
  /** True when the tool's settings in `manifest` leave it enabled (R2b C9). */
114
106
  export declare function isEnabledIn(manifest: AgentManifest, tool: McpToolRecord): boolean;
115
107
  /** The manifest of the agent an effect belongs to: the root, or an agent it uses as a tool. */
@@ -1,8 +1,14 @@
1
1
  import { createHash } from "node:crypto";
2
- import { TOOLS_CAPABILITY_ID, deferredToolsInstructions, deferredToolsTools, delegateManifest, mcpToolSettings, } from "@nylorun/core/define";
3
- /** The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot. */
4
- export function mcpDiscovered(snapshot, diagnostics) {
5
- const key = (item) => JSON.stringify([item.agentId ?? null, item.capabilityId, item.serverName]);
2
+ import { delegatesOf, pluginOf, deferredToolsInstructions, deferredToolsTools, delegateManifest, mcpToolSettings, } from "@nylorun/core/define";
3
+ /**
4
+ * The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot,
5
+ * and the Agent Plugin that brought the server (from `manifest`, the session's pinned one).
6
+ */
7
+ export function mcpDiscovered(snapshot, diagnostics, manifest) {
8
+ const agents = new Map(manifest === undefined
9
+ ? []
10
+ : [[undefined, manifest], ...delegatesOf(manifest).map(({ manifest: child }) => [child.id, child])]);
11
+ const key = (item) => JSON.stringify([item.agentId ?? null, item.serverName]);
6
12
  const tools = new Map();
7
13
  const deferred = new Map();
8
14
  for (const tool of snapshot.mcpTools) {
@@ -13,8 +19,8 @@ export function mcpDiscovered(snapshot, diagnostics) {
13
19
  return {
14
20
  servers: diagnostics.map((item) => ({
15
21
  ...(item.agentId === undefined ? {} : { agentId: item.agentId }),
16
- capabilityId: item.capabilityId,
17
22
  serverName: item.serverName,
23
+ ...withPlugin(pluginOf(agents.get(item.agentId), { server: item.serverName })),
18
24
  outcome: item.outcome,
19
25
  message: item.message,
20
26
  tools: tools.get(key(item)) ?? 0,
@@ -26,6 +32,9 @@ export function mcpDiscovered(snapshot, diagnostics) {
26
32
  })),
27
33
  };
28
34
  }
35
+ function withPlugin(plugin) {
36
+ return plugin === undefined ? {} : { plugin };
37
+ }
29
38
  /** The longest tool name every model provider accepts (R2b C6, Q14). */
30
39
  export const MODEL_TOOL_NAME_MAX = 64;
31
40
  /**
@@ -45,38 +54,29 @@ export function normalizeToolName(serverName, serverToolName, options = {}) {
45
54
  .slice(0, 8);
46
55
  return `${name.slice(0, MODEL_TOOL_NAME_MAX - 9)}_${hash}`;
47
56
  }
57
+ /** The names of the agent's tools: its own and those the Runtime pinned. */
48
58
  export function declaredToolNames(manifest) {
49
- const names = new Set();
50
- for (const capability of manifest.capabilities)
51
- for (const tool of capability.tools ?? [])
52
- names.add(tool.name);
53
- return names;
59
+ return new Set([...(manifest.tools ?? []), ...(manifest.runtime?.tools ?? [])].map((tool) => tool.name));
54
60
  }
55
61
  /** The declaration of the server a tool of the snapshot comes from, in `manifest`. */
56
62
  function serverOf(manifest, tool) {
57
63
  const agent = tool.agentId === undefined ? manifest : delegateManifest(manifest, tool.agentId);
58
- return agent?.capabilities.find((item) => item.id === tool.capabilityId)?.mcpServers?.[tool.serverName];
64
+ return agent?.mcpServers?.[tool.serverName];
59
65
  }
60
66
  /** The tool's settings in `manifest` (R2b C9); the defaults when its server is not there. */
61
- function settingsOf(manifest, tool) {
67
+ export function mcpToolSettingsIn(manifest, tool) {
62
68
  const server = serverOf(manifest, tool);
63
69
  return server ? mcpToolSettings(server, tool.serverToolName) : { enabled: true, approval: "never" };
64
70
  }
65
- /** True when the agent the tool belongs to has `tool_search` and `tool_call` (`nylorun.tools`). */
66
- function reachesDeferred(manifest, agentId) {
67
- const agent = agentId === undefined ? manifest : delegateManifest(manifest, agentId);
68
- return agent?.capabilities.some((capability) => capability.id === TOOLS_CAPABILITY_ID) === true;
69
- }
70
71
  /**
71
72
  * The tools of a snapshot, as the engine gets them for a turn whose manifest is `manifest` (the
72
73
  * session's pin, or a turn variant that tightened its MCP servers' tools):
73
74
  *
74
- * - a tool its settings disable is left out (R2b C9); one whose approval resolves to `always`
75
- * waits for approval on each call;
76
- * - a deferred tool (R2b C10) is marked so, out of the model's list, and its agent gets
77
- * `tool_search`, with the note on the servers it holds deferred tools of, and `tool_call` in
78
- * its `nylorun.tools` capability. An agent whose turn has no such capability keeps its tools in
79
- * its list.
75
+ * - a tool its settings disable is left out (R2b C9); the Tool Gate holds a call its approval
76
+ * or the Tenant's tool policy asks a person about (R5 step 2);
77
+ * - a deferred tool (R2b C10) is marked so, out of the model's list, and its agent gets the
78
+ * session tools `tool_search`, with the note on the servers it holds deferred tools of, and
79
+ * `tool_call`. Their names are reserved: no tool of the agent's own takes them.
80
80
  *
81
81
  * Nothing here changes between the steps of a turn, so neither does the model's tool list.
82
82
  */
@@ -87,18 +87,16 @@ export function sessionToolsOf(snapshot, manifest) {
87
87
  const deferred = new Map();
88
88
  const notes = new Map();
89
89
  for (const tool of snapshot.mcpTools) {
90
- const settings = settingsOf(manifest, tool);
90
+ const settings = mcpToolSettingsIn(manifest, tool);
91
91
  if (!settings.enabled)
92
92
  continue;
93
- const defer = tool.deferred === true && reachesDeferred(manifest, tool.agentId);
93
+ const defer = tool.deferred === true;
94
94
  const entry = {
95
95
  ...(tool.agentId === undefined ? {} : { agentId: tool.agentId }),
96
- capabilityId: tool.capabilityId,
97
96
  name: tool.name,
98
97
  ...(tool.description === undefined ? {} : { description: tool.description }),
99
98
  inputSchema: tool.inputSchema,
100
99
  ...(tool.outputSchema === undefined ? {} : { outputSchema: tool.outputSchema }),
101
- ...(settings.approval === "always" ? { approval: "always" } : {}),
102
100
  ...(defer ? { deferred: true } : {}),
103
101
  };
104
102
  if (!defer) {
@@ -110,7 +108,7 @@ export function sessionToolsOf(snapshot, manifest) {
110
108
  servers.set(tool.serverName, (servers.get(tool.serverName) ?? 0) + 1);
111
109
  notes.set(tool.agentId, servers);
112
110
  }
113
- const platform = [];
111
+ const session = [];
114
112
  for (const [agentId, tools] of deferred) {
115
113
  const servers = [...notes.get(agentId)].map(([serverName, count]) => {
116
114
  const instructions = snapshot.servers?.find((item) => item.agentId === agentId && item.serverName === serverName)?.instructions;
@@ -121,14 +119,10 @@ export function sessionToolsOf(snapshot, manifest) {
121
119
  { ...search, instructions: [deferredToolsInstructions(servers)] },
122
120
  call,
123
121
  ])
124
- platform.push({
125
- ...(agentId === undefined ? {} : { agentId }),
126
- capabilityId: TOOLS_CAPABILITY_ID,
127
- ...tool,
128
- });
129
- platform.push(...tools);
122
+ session.push({ ...(agentId === undefined ? {} : { agentId }), ...tool });
123
+ session.push(...tools);
130
124
  }
131
- return [...inline, ...platform];
125
+ return [...inline, ...session];
132
126
  }
133
127
  /** The share of the model's context window past which an agent's MCP tools are deferred (Q21). */
134
128
  export const DEFER_CONTEXT_SHARE = 0.1;
@@ -138,14 +132,12 @@ export const CHARS_PER_TOKEN = 4;
138
132
  * The snapshot with its deferred tools marked (R2b C10, Q21), decided once for the session when
139
133
  * core records it. A tool's own setting, then `"*"`'s, then its server's, decides; a tool none
140
134
  * sets is deferred when the JSON of its agent's MCP tools that would be listed passes a tenth of
141
- * the model's context window (`contextWindow` tokens, at 4 characters a token). An agent without
142
- * the `nylorun.tools` capability (its definition names a tool `tool_search` or `tool_call`, or the
143
- * session was opened before it existed) defers nothing.
135
+ * the model's context window (`contextWindow` tokens, at 4 characters a token).
144
136
  */
145
137
  export function pinDeferral(snapshot, manifest, contextWindow) {
146
138
  const limit = contextWindow * CHARS_PER_TOKEN * DEFER_CONTEXT_SHARE;
147
139
  const listed = new Map();
148
- const set = snapshot.mcpTools.map((tool) => settingsOf(manifest, tool).deferred);
140
+ const set = snapshot.mcpTools.map((tool) => mcpToolSettingsIn(manifest, tool).deferred);
149
141
  snapshot.mcpTools.forEach((tool, i) => {
150
142
  if (set[i] === true)
151
143
  return;
@@ -154,8 +146,6 @@ export function pinDeferral(snapshot, manifest, contextWindow) {
154
146
  });
155
147
  const mcpTools = snapshot.mcpTools.map((tool, i) => {
156
148
  const { deferred: _, ...rest } = tool;
157
- if (!reachesDeferred(manifest, tool.agentId))
158
- return rest;
159
149
  const defer = set[i] ?? (listed.get(tool.agentId) ?? 0) > limit;
160
150
  return defer ? { ...rest, deferred: true } : rest;
161
151
  });
@@ -166,16 +156,14 @@ export function pinDeferral(snapshot, manifest, contextWindow) {
166
156
  * the turn's `manifest`, a tool its settings disable is not one either (R2b C9).
167
157
  */
168
158
  export function mcpToolOf(snapshot, request, manifest) {
169
- const tool = snapshot?.mcpTools.find((tool) => tool.agentId === request.agent?.id &&
170
- tool.capabilityId === request.capabilityId &&
171
- tool.name === request.toolName);
159
+ const tool = snapshot?.mcpTools.find((tool) => tool.agentId === request.agent?.id && tool.name === request.toolName);
172
160
  if (tool && manifest && !isEnabledIn(manifest, tool))
173
161
  return undefined;
174
162
  return tool;
175
163
  }
176
164
  /** True when the tool's settings in `manifest` leave it enabled (R2b C9). */
177
165
  export function isEnabledIn(manifest, tool) {
178
- return settingsOf(manifest, tool).enabled;
166
+ return mcpToolSettingsIn(manifest, tool).enabled;
179
167
  }
180
168
  /** The manifest of the agent an effect belongs to: the root, or an agent it uses as a tool. */
181
169
  export function manifestFor(manifest, agent) {
@@ -0,0 +1,26 @@
1
+ /**
2
+ * What a model reads (protocol 12): its pi-ai catalog's `input` (text, image) and what the
3
+ * operator added. One function, `capabilitiesOf`, serves the catalog, the accept check, the Model
4
+ * Gate and `read_artifact`.
5
+ *
6
+ * The operator may add only an input our provider path sends natively for the model's API
7
+ * (`NATIVE_INPUTS`): an image on every API; a PDF on the APIs below; Office documents on the
8
+ * OpenAI Responses APIs; audio and video on Google's APIs and OpenAI-compatible completions.
9
+ */
10
+ import type { Api, Model } from "@earendil-works/pi-ai";
11
+ import { type ModelInput } from "@nylorun/core/contracts";
12
+ /** What `capabilitiesOf` reads of a pi-ai model. */
13
+ export type ModelShape = Pick<Model<Api>, "api" | "input">;
14
+ /** The inputs each API carries natively, beyond text. Any other API: images only. */
15
+ export declare const NATIVE_INPUTS: Readonly<Record<string, readonly ModelInput[]>>;
16
+ /** What the operator may add to `model`: the inputs its API carries that its catalog lacks. */
17
+ export declare function addableInputs(model: ModelShape): ModelInput[];
18
+ /**
19
+ * What `model` reads: text, its catalog's inputs and those of `added` its API carries, in
20
+ * `MODEL_INPUTS` order.
21
+ */
22
+ export declare function capabilitiesOf(model: ModelShape, added?: readonly ModelInput[]): {
23
+ readonly inputs: ModelInput[];
24
+ };
25
+ /** Why `inputs` cannot be set for `model`, or undefined when they can. */
26
+ export declare function inputsError(model: ModelShape, inputs: readonly ModelInput[]): string | undefined;
@@ -0,0 +1,44 @@
1
+ import { MODEL_INPUTS } from "@nylorun/core/contracts";
2
+ /** The inputs each API carries natively, beyond text. Any other API: images only. */
3
+ export const NATIVE_INPUTS = {
4
+ "anthropic-messages": ["image", "pdf"],
5
+ "openai-responses": ["image", "pdf", "office"],
6
+ "azure-openai-responses": ["image", "pdf", "office"],
7
+ "openai-completions": ["image", "pdf", "audio", "video"],
8
+ "google-generative-ai": ["image", "pdf", "audio", "video"],
9
+ "google-vertex": ["image", "pdf", "audio", "video"],
10
+ };
11
+ function nativeInputs(model) {
12
+ return NATIVE_INPUTS[model.api] ?? ["image"];
13
+ }
14
+ function ordered(inputs) {
15
+ const set = new Set(inputs);
16
+ return MODEL_INPUTS.filter((input) => set.has(input));
17
+ }
18
+ /** What the operator may add to `model`: the inputs its API carries that its catalog lacks. */
19
+ export function addableInputs(model) {
20
+ const own = model.input;
21
+ return ordered(nativeInputs(model).filter((input) => !own.includes(input)));
22
+ }
23
+ /**
24
+ * What `model` reads: text, its catalog's inputs and those of `added` its API carries, in
25
+ * `MODEL_INPUTS` order.
26
+ */
27
+ export function capabilitiesOf(model, added = []) {
28
+ const native = nativeInputs(model);
29
+ return {
30
+ inputs: ordered([
31
+ "text",
32
+ ...model.input,
33
+ ...added.filter((input) => native.includes(input)),
34
+ ]),
35
+ };
36
+ }
37
+ /** Why `inputs` cannot be set for `model`, or undefined when they can. */
38
+ export function inputsError(model, inputs) {
39
+ const allowed = new Set(["text", ...model.input, ...nativeInputs(model)]);
40
+ const refused = ordered(inputs.filter((input) => !allowed.has(input)));
41
+ if (refused.length === 0)
42
+ return undefined;
43
+ return `This model's API (${model.api}) cannot carry ${refused.join(", ")}; it can read ${ordered(allowed).join(", ")}.`;
44
+ }
@@ -1,4 +1,6 @@
1
- import type { HostModelCatalog } from "@nylorun/core/contracts";
1
+ import type { Api, Model } from "@earendil-works/pi-ai";
2
+ import type { HostModelCatalog, HostModelView, ModelInput } from "@nylorun/core/contracts";
3
+ import type { SessionStore } from "../store/types.js";
2
4
  export type { HostModelCatalog };
3
5
  /**
4
6
  * The context window, in tokens, of the Tenant's model (`GET /v1/tenant/model`'s view): the
@@ -14,5 +16,34 @@ export declare function contextWindowOf(view: {
14
16
  contextWindow?: number;
15
17
  };
16
18
  }): number;
17
- /** Public provider and model names. No credentials. */
18
- export declare function hostModelCatalog(): HostModelCatalog;
19
+ /**
20
+ * Public provider and model names, and what each model reads with the operator's additions
21
+ * (`added`, by `<provider>/<model>`) and what may be added (protocol 12). No credentials.
22
+ */
23
+ export declare function hostModelCatalog(added?: Readonly<Record<string, readonly ModelInput[]>>): HostModelCatalog;
24
+ /** A catalog model, by provider and id; undefined for one the catalog does not know. */
25
+ export declare function catalogModel(provider: string, model: string): Model<Api> | undefined;
26
+ /**
27
+ * What a configured model reads (protocol 12): a custom endpoint's `settings.inputs` (text only
28
+ * by default), else its catalog's inputs and the operator's additions (`added`). Undefined for no
29
+ * model, or one the catalog does not know.
30
+ */
31
+ export declare function inputsOfHostModel(view: {
32
+ configured: boolean;
33
+ provider?: string;
34
+ model?: string;
35
+ baseUrl?: string;
36
+ settings?: {
37
+ inputs?: readonly ModelInput[];
38
+ };
39
+ }, added?: Readonly<Record<string, readonly ModelInput[]>>): ModelInput[] | undefined;
40
+ /**
41
+ * What the Tenant's model reads now, for the accept check and `read_artifact`: undefined when no
42
+ * model is in the vault (a test's fake provider, say), and the check is skipped.
43
+ */
44
+ export declare function currentModelInputs(ctx: {
45
+ readonly store: SessionStore;
46
+ readonly vault: {
47
+ getHostModel(): Promise<HostModelView>;
48
+ };
49
+ }): Promise<ModelInput[] | undefined>;
@@ -1,3 +1,5 @@
1
+ import { readAddedInputs } from "../tenant/model-setting.js";
2
+ import { addableInputs, capabilitiesOf } from "./capabilities.js";
1
3
  import { CUSTOM_CONTEXT_WINDOW, modelsFor } from "./models.js";
2
4
  const emptyStore = {
3
5
  async read() {
@@ -24,8 +26,11 @@ export function contextWindowOf(view) {
24
26
  const models = modelsFor({ provider: "", model: "" }, emptyStore, { environment: false });
25
27
  return models.getModel(view.provider, view.model)?.contextWindow ?? CUSTOM_CONTEXT_WINDOW;
26
28
  }
27
- /** Public provider and model names. No credentials. */
28
- export function hostModelCatalog() {
29
+ /**
30
+ * Public provider and model names, and what each model reads with the operator's additions
31
+ * (`added`, by `<provider>/<model>`) and what may be added (protocol 12). No credentials.
32
+ */
33
+ export function hostModelCatalog(added = {}) {
29
34
  const models = modelsFor({ provider: "", model: "" }, emptyStore, {
30
35
  environment: false,
31
36
  });
@@ -36,7 +41,38 @@ export function hostModelCatalog() {
36
41
  models: models.getModels(provider.id).map((model) => ({
37
42
  id: model.id,
38
43
  name: model.name,
44
+ inputs: capabilitiesOf(model, added[`${provider.id}/${model.id}`]).inputs,
45
+ addableInputs: addableInputs(model),
39
46
  })),
40
47
  })),
41
48
  };
42
49
  }
50
+ /** A catalog model, by provider and id; undefined for one the catalog does not know. */
51
+ export function catalogModel(provider, model) {
52
+ return modelsFor({ provider: "", model: "" }, emptyStore, { environment: false }).getModel(provider, model);
53
+ }
54
+ /**
55
+ * What a configured model reads (protocol 12): a custom endpoint's `settings.inputs` (text only
56
+ * by default), else its catalog's inputs and the operator's additions (`added`). Undefined for no
57
+ * model, or one the catalog does not know.
58
+ */
59
+ export function inputsOfHostModel(view, added = {}) {
60
+ if (!view.configured || !view.provider || !view.model)
61
+ return undefined;
62
+ if (view.baseUrl) {
63
+ const inputs = view.settings?.inputs ?? [];
64
+ return capabilitiesOf({ api: "openai-completions", input: inputs.includes("image") ? ["text", "image"] : ["text"] }, inputs).inputs;
65
+ }
66
+ const model = catalogModel(view.provider, view.model);
67
+ return model && capabilitiesOf(model, added[`${view.provider}/${view.model}`]).inputs;
68
+ }
69
+ /**
70
+ * What the Tenant's model reads now, for the accept check and `read_artifact`: undefined when no
71
+ * model is in the vault (a test's fake provider, say), and the check is skipped.
72
+ */
73
+ export async function currentModelInputs(ctx) {
74
+ const view = await ctx.vault.getHostModel();
75
+ if (!view.configured)
76
+ return undefined;
77
+ return inputsOfHostModel(view, await ctx.store.tx((t) => readAddedInputs(t)));
78
+ }
@@ -8,6 +8,8 @@ export type Selection = Readonly<{
8
8
  contextWindow?: number;
9
9
  maxTokens?: number;
10
10
  reasoning?: boolean;
11
+ /** What the endpoint reads (protocol 12); text only unless it says so. */
12
+ inputs?: readonly string[];
11
13
  compat?: Readonly<Record<string, unknown>>;
12
14
  }>;
13
15
  }>;
@@ -25,7 +25,7 @@ export function modelsFor(selection, credentials, options = {}) {
25
25
  provider: "custom",
26
26
  baseUrl: selection.custom.baseUrl,
27
27
  reasoning: selection.custom.reasoning ?? false,
28
- input: ["text", "image"],
28
+ input: selection.custom.inputs?.includes("image") ? ["text", "image"] : ["text"],
29
29
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
30
30
  contextWindow: selection.custom.contextWindow ?? CUSTOM_CONTEXT_WINDOW,
31
31
  maxTokens: selection.custom.maxTokens ?? CUSTOM_MAX_TOKENS,
@@ -0,0 +1,35 @@
1
+ import type { TextContent } from "@earendil-works/pi-ai";
2
+ /** The kinds of file a native block carries; images are pi-ai's own. */
3
+ export type NativeFileKind = "pdf" | "office" | "audio" | "video";
4
+ /** A file for one model call: its kind, media type, name and base64 bytes. */
5
+ export interface NativeFile {
6
+ readonly kind: NativeFileKind;
7
+ readonly mediaType: string;
8
+ readonly name: string;
9
+ /** The bytes, base64-encoded. */
10
+ readonly data: string;
11
+ }
12
+ /**
13
+ * The kinds each pi-ai API has a native block for here: the model inputs an operator may add
14
+ * (`NATIVE_INPUTS`), images aside, so the two tables never disagree.
15
+ */
16
+ export declare const NATIVE_FILE_KINDS: Readonly<Record<string, readonly NativeFileKind[]>>;
17
+ /** The kinds of file `api` carries in a native block; none for an API without a rewriter. */
18
+ export declare function nativeKindsOf(api: string): readonly NativeFileKind[];
19
+ export declare class NativeBlocks {
20
+ private readonly files;
21
+ /** Why the last `rewrite` could not carry every file; undefined when it did. */
22
+ error?: string;
23
+ /** How many files this call carries. */
24
+ get size(): number;
25
+ /** A text part standing for `file` in pi-ai's context, replaced by `rewrite`. */
26
+ add(file: NativeFile): TextContent;
27
+ /**
28
+ * `payload` (an `onPayload` request body for `api`) with each marker block replaced by its
29
+ * native block. Rewrites in place and returns the same payload; sets `error` when a file
30
+ * could not be carried.
31
+ */
32
+ rewrite(payload: unknown, api: string): unknown;
33
+ /** The native block for a marker block of ours; undefined for any other block. */
34
+ private replace;
35
+ }