@nylorun/runtime 0.17.0-beta → 0.19.1-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 (223) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/README.md +89 -58
  3. package/dist/adapters/execution/restate.d.ts +1 -3
  4. package/dist/adapters/execution/restate.js +4 -31
  5. package/dist/adapters/replication/pgoutput.js +1 -1
  6. package/dist/adapters/sandbox/local.js +1 -1
  7. package/dist/adapters/sandbox/virtual.js +1 -1
  8. package/dist/api/ag-ui/routes.js +1 -1
  9. package/dist/api/ag-ui/translate.d.ts +1 -3
  10. package/dist/api/ag-ui/translate.js +2 -17
  11. package/dist/api/components.d.ts +4871 -2614
  12. package/dist/api/components.js +12 -11
  13. package/dist/api/gate/routes.d.ts +7 -8
  14. package/dist/api/gate/routes.js +58 -52
  15. package/dist/api/http/app.d.ts +6 -0
  16. package/dist/api/http/app.js +18 -14
  17. package/dist/api/http/define.d.ts +14 -2
  18. package/dist/api/http/define.js +34 -15
  19. package/dist/api/http/routes/access.d.ts +3 -3
  20. package/dist/api/http/routes/access.js +18 -17
  21. package/dist/api/http/routes/artifacts.js +2 -4
  22. package/dist/api/http/routes/files.d.ts +8 -0
  23. package/dist/api/http/routes/files.js +77 -0
  24. package/dist/api/http/routes/keys.d.ts +10 -0
  25. package/dist/api/http/routes/keys.js +64 -0
  26. package/dist/api/http/routes/me.js +5 -2
  27. package/dist/api/http/routes/reads.d.ts +66 -0
  28. package/dist/api/http/routes/reads.js +127 -0
  29. package/dist/api/http/routes/sandboxes.js +7 -4
  30. package/dist/api/http/routes/sessions.js +25 -8
  31. package/dist/api/http/routes/tenant.js +15 -18
  32. package/dist/api/http/routes/vaults.d.ts +10 -9
  33. package/dist/api/http/routes/vaults.js +27 -23
  34. package/dist/api/openapi.d.ts +10 -11
  35. package/dist/api/openapi.js +288 -63
  36. package/dist/artifacts/links.js +1 -1
  37. package/dist/core/flow-host.d.ts +44 -23
  38. package/dist/core/flow-host.js +88 -106
  39. package/dist/core/provider.d.ts +4 -1
  40. package/dist/core/provider.js +6 -1
  41. package/dist/core/sandbox-routes.d.ts +0 -9
  42. package/dist/core/sandbox-routes.js +2 -21
  43. package/dist/execution/memory.d.ts +4 -5
  44. package/dist/execution/memory.js +11 -25
  45. package/dist/execution/types.d.ts +3 -33
  46. package/dist/execution/types.js +2 -12
  47. package/dist/gates/http-tool.d.ts +86 -0
  48. package/dist/gates/http-tool.js +197 -0
  49. package/dist/gates/mcp-handler.d.ts +3 -0
  50. package/dist/gates/mcp-handler.js +1 -3
  51. package/dist/gates/meter.d.ts +2 -2
  52. package/dist/gates/meter.js +6 -0
  53. package/dist/gates/tenant-vaults.d.ts +5 -9
  54. package/dist/gates/tool-calls.d.ts +7 -15
  55. package/dist/gates/tool-calls.js +4 -4
  56. package/dist/gates/tool-client.d.ts +1 -1
  57. package/dist/gates/tool-client.js +23 -47
  58. package/dist/gates/tool-contract.d.ts +27 -39
  59. package/dist/gates/tool-contract.js +30 -21
  60. package/dist/gates/tool-gate.d.ts +25 -24
  61. package/dist/gates/tool-gate.js +11 -7
  62. package/dist/harness/calls.d.ts +10 -4
  63. package/dist/harness/calls.js +15 -6
  64. package/dist/harness/executors.d.ts +1 -1
  65. package/dist/harness/executors.js +17 -12
  66. package/dist/harness/main.d.ts +2 -2
  67. package/dist/harness/main.js +5 -13
  68. package/dist/harness/service.d.ts +4 -5
  69. package/dist/harness/service.js +9 -2
  70. package/dist/harness-api/in-process.js +2 -2
  71. package/dist/harness-api/record.d.ts +6 -3
  72. package/dist/harness-api/record.js +65 -72
  73. package/dist/harness-api/server.d.ts +1 -9
  74. package/dist/harness-api/server.js +19 -17
  75. package/dist/harness-api/start.js +1 -5
  76. package/dist/harness-api/workspace.js +2 -3
  77. package/dist/harness-api/ws-server.js +1 -1
  78. package/dist/host/app.d.ts +2 -9
  79. package/dist/host/app.js +15 -25
  80. package/dist/host/config-for.d.ts +1 -5
  81. package/dist/host/config-for.js +0 -3
  82. package/dist/host/config.d.ts +0 -5
  83. package/dist/host/create-host.d.ts +3 -33
  84. package/dist/host/create-host.js +18 -94
  85. package/dist/host/environment.d.ts +0 -3
  86. package/dist/host/environment.js +0 -9
  87. package/dist/host/gates.d.ts +4 -1
  88. package/dist/host/gates.js +3 -2
  89. package/dist/host/http.d.ts +1 -2
  90. package/dist/host/http.js +1 -7
  91. package/dist/host/index.d.ts +2 -2
  92. package/dist/host/index.js +2 -2
  93. package/dist/host/main.js +27 -34
  94. package/dist/host/operate.d.ts +29 -0
  95. package/dist/host/operate.js +223 -0
  96. package/dist/host/stack-config.d.ts +12 -12
  97. package/dist/host/stack-config.js +5 -32
  98. package/dist/index.d.ts +1 -1
  99. package/dist/index.js +1 -1
  100. package/dist/infra/workers.d.ts +1 -1
  101. package/dist/keys/keys.js +2 -2
  102. package/dist/management-openapi.json +6491 -0
  103. package/dist/mcp/connect.d.ts +8 -4
  104. package/dist/mcp/connect.js +6 -26
  105. package/dist/mcp/pool.d.ts +5 -9
  106. package/dist/mcp/pool.js +8 -19
  107. package/dist/mcp/snapshot.d.ts +8 -2
  108. package/dist/mcp/snapshot.js +29 -2
  109. package/dist/media.d.ts +1 -1
  110. package/dist/media.js +1 -1
  111. package/dist/model/pi-model.js +3 -0
  112. package/dist/openapi.json +9372 -17030
  113. package/dist/reads/access.d.ts +4 -0
  114. package/dist/reads/access.js +12 -0
  115. package/dist/reads/cursor.d.ts +11 -0
  116. package/dist/reads/cursor.js +80 -0
  117. package/dist/reads/types.d.ts +25 -0
  118. package/dist/reads/types.js +1 -0
  119. package/dist/sandbox/manager.d.ts +16 -0
  120. package/dist/sandbox/manager.js +40 -0
  121. package/dist/sandbox/session-sandbox.js +13 -3
  122. package/dist/sandbox/skills.d.ts +13 -0
  123. package/dist/sandbox/skills.js +46 -0
  124. package/dist/sandbox/types.d.ts +2 -2
  125. package/dist/store/ownership.d.ts +9 -0
  126. package/dist/store/ownership.js +13 -0
  127. package/dist/store/postgres/connect.d.ts +2 -0
  128. package/dist/store/postgres/connect.js +29 -0
  129. package/dist/store/postgres/drizzle/0011_key_roles.sql +3 -0
  130. package/dist/store/postgres/drizzle/0012_session_reads.sql +8 -0
  131. package/dist/store/postgres/drizzle/0013_definition_files.sql +16 -0
  132. package/dist/store/postgres/drizzle/0014_action_endpoints_removed.sql +2 -0
  133. package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
  134. package/dist/store/postgres/reads.d.ts +3 -0
  135. package/dist/store/postgres/reads.js +272 -0
  136. package/dist/store/postgres/schema.d.ts +294 -489
  137. package/dist/store/postgres/schema.js +41 -76
  138. package/dist/store/postgres/store.js +51 -154
  139. package/dist/store/postgres/tenant.d.ts +34 -2
  140. package/dist/store/postgres/tenant.js +16 -32
  141. package/dist/store/types.d.ts +27 -96
  142. package/dist/store/types.js +0 -1
  143. package/dist/streams/control.d.ts +0 -2
  144. package/dist/streams/control.js +0 -5
  145. package/dist/streams/types.d.ts +1 -10
  146. package/dist/tenant/advance.d.ts +3 -3
  147. package/dist/tenant/advance.js +10 -7
  148. package/dist/tenant/auth.d.ts +14 -9
  149. package/dist/tenant/auth.js +24 -28
  150. package/dist/tenant/cause.d.ts +3 -3
  151. package/dist/tenant/cause.js +1 -1
  152. package/dist/tenant/commands.d.ts +2 -18
  153. package/dist/tenant/commands.js +35 -172
  154. package/dist/tenant/context.d.ts +14 -24
  155. package/dist/tenant/definition-files.d.ts +24 -0
  156. package/dist/tenant/definition-files.js +103 -0
  157. package/dist/tenant/effects.d.ts +18 -20
  158. package/dist/tenant/effects.js +56 -119
  159. package/dist/tenant/ephemeral.d.ts +7 -6
  160. package/dist/tenant/ephemeral.js +3 -11
  161. package/dist/tenant/host-token.js +1 -1
  162. package/dist/tenant/jwt.js +1 -1
  163. package/dist/tenant/module.d.ts +1 -4
  164. package/dist/tenant/module.js +3 -12
  165. package/dist/tenant/operator-keys.d.ts +34 -8
  166. package/dist/tenant/operator-keys.js +50 -18
  167. package/dist/tenant/outbound.d.ts +10 -1
  168. package/dist/tenant/outbound.js +44 -27
  169. package/dist/tenant/paths.d.ts +1 -1
  170. package/dist/tenant/paths.js +1 -3
  171. package/dist/tenant/principals.d.ts +11 -2
  172. package/dist/tenant/principals.js +27 -8
  173. package/dist/tenant/run-token.js +3 -3
  174. package/dist/tenant/runtime.d.ts +4 -6
  175. package/dist/tenant/runtime.js +19 -18
  176. package/dist/tenant/sandboxes.d.ts +4 -1
  177. package/dist/tenant/sandboxes.js +11 -0
  178. package/dist/tenant/scheduler.d.ts +1 -5
  179. package/dist/tenant/scheduler.js +2 -5
  180. package/dist/tenant/session-streams.d.ts +2 -1
  181. package/dist/tenant/session-streams.js +39 -5
  182. package/dist/tenant/session.d.ts +8 -41
  183. package/dist/tenant/session.js +0 -37
  184. package/dist/tenant/sessions.js +16 -8
  185. package/dist/tenant/signing-keys.d.ts +3 -3
  186. package/dist/tenant/signing-keys.js +5 -5
  187. package/dist/tenant/skill-tool.d.ts +20 -0
  188. package/dist/tenant/skill-tool.js +72 -0
  189. package/dist/tenant/slim.d.ts +1 -1
  190. package/dist/tenant/slim.js +1 -1
  191. package/dist/tenant/status.js +7 -12
  192. package/dist/tenant/store-pg.d.ts +15 -0
  193. package/dist/tenant/store-pg.js +7 -3
  194. package/dist/tenant/streams.d.ts +3 -10
  195. package/dist/tenant/streams.js +1 -24
  196. package/dist/tenant/sweep.js +0 -5
  197. package/dist/tenant/transcript.d.ts +2 -2
  198. package/dist/tenant/transcript.js +2 -2
  199. package/dist/tenant/types.d.ts +15 -22
  200. package/dist/tenant/worker.d.ts +1 -3
  201. package/dist/tenant/worker.js +3 -8
  202. package/dist/vault/sources.d.ts +7 -1
  203. package/dist/vault/sources.js +22 -11
  204. package/dist/version.d.ts +1 -1
  205. package/dist/version.js +1 -1
  206. package/package.json +4 -4
  207. package/dist/admin-openapi.json +0 -904
  208. package/dist/api/http/routes/actions.d.ts +0 -8
  209. package/dist/api/http/routes/actions.js +0 -75
  210. package/dist/api/http/routes/endpoints.d.ts +0 -7
  211. package/dist/api/http/routes/endpoints.js +0 -100
  212. package/dist/host/admin-api.d.ts +0 -30
  213. package/dist/host/admin-api.js +0 -140
  214. package/dist/mcp/stdio.d.ts +0 -17
  215. package/dist/mcp/stdio.js +0 -82
  216. package/dist/tenant/actions.d.ts +0 -14
  217. package/dist/tenant/actions.js +0 -29
  218. package/dist/tenant/delivery-token.d.ts +0 -41
  219. package/dist/tenant/delivery-token.js +0 -104
  220. package/dist/tenant/delivery.d.ts +0 -62
  221. package/dist/tenant/delivery.js +0 -481
  222. package/dist/tenant/endpoints.d.ts +0 -67
  223. package/dist/tenant/endpoints.js +0 -90
@@ -1,5 +1,6 @@
1
1
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
2
  import type { McpServerManifest } from "@nylorun/core/define";
3
+ import { type OutboundPolicy } from "../tenant/outbound.js";
3
4
  import type { AuthorizeResult } from "../vault/service.js";
4
5
  import { type McpDiagnostic, type McpToolRecord } from "./snapshot.js";
5
6
  /** Options of one MCP request. */
@@ -47,10 +48,13 @@ export interface LiveConnection {
47
48
  export declare function sdkClient(client: Client): McpClient;
48
49
  export declare function openMcpServer(input: {
49
50
  server: McpServerManifest;
50
- authorize?: (url: string) => Promise<AuthorizeResult>;
51
- pluginRoot?: string;
52
- pluginData: string;
53
- childEnv?: Readonly<Record<string, string>>;
51
+ authorize: (url: string) => Promise<AuthorizeResult>;
52
+ /**
53
+ * How a remote server is reached: the Host's address policy for developer URLs
54
+ * (`TenantConfig.delivery`), so `localhost` means the Docker host in the local stack and a
55
+ * Host that refuses private addresses refuses them here too. Default: no limits.
56
+ */
57
+ policy?: OutboundPolicy;
54
58
  }): Promise<LiveConnection>;
55
59
  export declare function listMcpTools(client: McpClient, input: {
56
60
  capabilityId: string;
@@ -1,10 +1,9 @@
1
1
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
2
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
3
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
3
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
4
  import { schemaFromJSON } from "@nylorun/core/define";
5
+ import { guardedFetch } from "../tenant/outbound.js";
6
6
  import { modelToolName, } from "./snapshot.js";
7
- import { prepareStdioLaunch } from "./stdio.js";
8
7
  /** An SDK `Client` as an `McpClient`. */
9
8
  export function sdkClient(client) {
10
9
  return {
@@ -13,28 +12,7 @@ export function sdkClient(client) {
13
12
  };
14
13
  }
15
14
  export async function openMcpServer(input) {
16
- if (input.server.type === "stdio") {
17
- const launch = prepareStdioLaunch(input.server, {
18
- pluginRoot: input.pluginRoot,
19
- pluginData: input.pluginData,
20
- childEnv: input.childEnv,
21
- });
22
- const transport = new StdioClientTransport({
23
- command: launch.command,
24
- args: [...launch.args],
25
- cwd: launch.cwd,
26
- // Full explicit env so HOME/TMPDIR from the Tenant override getDefaultEnvironment().
27
- env: { ...launch.env },
28
- stderr: "pipe",
29
- });
30
- transport.stderr?.on("data", () => { });
31
- const client = createClient();
32
- await client.connect(transport);
33
- return { client: sdkClient(client), close: () => client.close() };
34
- }
35
15
  const authorize = input.authorize;
36
- if (!authorize)
37
- throw new Error("HTTP MCP server requires authorization");
38
16
  const initial = await authorize(input.server.url);
39
17
  if (initial.status === "refused") {
40
18
  const error = new Error(`MCP authorization refused: ${initial.reason}`);
@@ -42,7 +20,7 @@ export async function openMcpServer(input) {
42
20
  initial.credentialIds;
43
21
  throw error;
44
22
  }
45
- const fetchImpl = authorizedFetch(input.server, authorize);
23
+ const fetchImpl = authorizedFetch(input.server, authorize, input.policy ?? {});
46
24
  const url = new URL(input.server.url);
47
25
  const transport = input.server.type === "sse"
48
26
  ? new SSEClientTransport(url, { fetch: fetchImpl })
@@ -145,7 +123,8 @@ export function diagnosticFromError(capabilityId, serverName, error) {
145
123
  function createClient() {
146
124
  return new Client({ name: "nylorun-runtime", version: "0.6.0" }, { capabilities: {} });
147
125
  }
148
- function authorizedFetch(server, authorize) {
126
+ function authorizedFetch(server, authorize, policy) {
127
+ const send = guardedFetch(policy, { stream: true });
149
128
  return async (url, init) => {
150
129
  const target = typeof url === "string" ? url : url.href;
151
130
  if (!sameOrigin(target, server.url))
@@ -164,7 +143,8 @@ function authorizedFetch(server, authorize) {
164
143
  if (result.status === "authorized")
165
144
  for (const [key, value] of Object.entries(result.headers))
166
145
  headers.set(key, value);
167
- return fetch(target, { ...init, headers, redirect: "error" });
146
+ // No redirects, and the address checked on what is connected to (`tenant/outbound.ts`).
147
+ return send(target, { ...init, headers });
168
148
  };
169
149
  }
170
150
  function sameOrigin(requestUrl, serverUrl) {
@@ -1,4 +1,5 @@
1
1
  import type { AgentManifest, McpServerManifest } from "@nylorun/core/define";
2
+ import type { OutboundPolicy } from "../tenant/outbound.js";
2
3
  import type { AuthorizeResult } from "../vault/service.js";
3
4
  import { callMcpTool, openMcpServer, type LiveConnection } from "./connect.js";
4
5
  import { type McpDiagnostic, type McpSnapshot, type McpToolRecord } from "./snapshot.js";
@@ -13,9 +14,6 @@ export declare class McpPool {
13
14
  private readonly now;
14
15
  private readonly open;
15
16
  constructor(options: {
16
- /** Absolute Tenant `plugin-data` directory. */
17
- readonly pluginData: string;
18
- readonly childEnv: Readonly<Record<string, string>>;
19
17
  readonly authorize: (sessionId: string, request: {
20
18
  url: string;
21
19
  serverName: string;
@@ -26,11 +24,12 @@ export declare class McpPool {
26
24
  readonly now?: () => number;
27
25
  /** Tests replace how a declared server is opened. */
28
26
  readonly open?: typeof openMcpServer;
27
+ /** How remote servers opened in this process are reached (`TenantConfig.delivery`). */
28
+ readonly policy?: OutboundPolicy;
29
29
  /**
30
30
  * Opens a remote (`streamable-http` or `sse`) server somewhere else: the gates service
31
31
  * holds the connection and its credential, and the loop never sees either (F4.1).
32
- * Absent: remote servers are opened in this process, with `authorize`. Stdio servers
33
- * always run here.
32
+ * Absent: they are opened in this process, with `authorize`.
34
33
  */
35
34
  readonly openRemote?: (server: McpServerRef) => Promise<LiveConnection>;
36
35
  });
@@ -38,7 +37,6 @@ export declare class McpPool {
38
37
  sessionId: string;
39
38
  manifest: AgentManifest;
40
39
  manifestHash: string;
41
- pluginRoots: Readonly<Record<string, string>>;
42
40
  signal?: AbortSignal;
43
41
  }): Promise<{
44
42
  snapshot: McpSnapshot;
@@ -47,7 +45,6 @@ export declare class McpPool {
47
45
  reconnect(input: {
48
46
  sessionId: string;
49
47
  manifest: AgentManifest;
50
- pluginRoots: Readonly<Record<string, string>>;
51
48
  tools: readonly McpToolRecord[];
52
49
  signal?: AbortSignal;
53
50
  }): Promise<McpDiagnostic[]>;
@@ -59,14 +56,13 @@ export declare class McpPool {
59
56
  serverToolName: string;
60
57
  args: unknown;
61
58
  manifest: AgentManifest;
62
- pluginRoots: Readonly<Record<string, string>>;
63
59
  /** The effect id: a gate runs the call once under it (F4.1). */
64
60
  effectId?: string;
65
61
  signal?: AbortSignal;
66
62
  }): Promise<Awaited<ReturnType<typeof callMcpTool>>>;
67
63
  /**
68
64
  * Closes connections unused for the idle timeout (the Tenant sweep). A session that calls
69
- * one again reconnects, as after a restart; this bounds the stdio processes a Tenant keeps.
65
+ * one again reconnects, as after a restart; this bounds the connections a Tenant keeps.
70
66
  */
71
67
  sweep(): Promise<void>;
72
68
  close(): Promise<void>;
package/dist/mcp/pool.js CHANGED
@@ -1,4 +1,3 @@
1
- import { join } from "node:path";
2
1
  import { delegatesOf } from "@nylorun/core/define";
3
2
  import { callMcpTool, diagnosticFromError, listMcpTools, openMcpServer, } from "./connect.js";
4
3
  import { declaredToolNames, } from "./snapshot.js";
@@ -131,7 +130,7 @@ export class McpPool {
131
130
  }
132
131
  /**
133
132
  * Closes connections unused for the idle timeout (the Tenant sweep). A session that calls
134
- * one again reconnects, as after a restart; this bounds the stdio processes a Tenant keeps.
133
+ * one again reconnects, as after a restart; this bounds the connections a Tenant keeps.
135
134
  */
136
135
  async sweep() {
137
136
  const now = this.now();
@@ -173,7 +172,7 @@ export class McpPool {
173
172
  }
174
173
  async connectDeclared(input, declared) {
175
174
  try {
176
- if (declared.server.type !== "stdio" && this.options.openRemote) {
175
+ if (this.options.openRemote) {
177
176
  const connection = await this.options.openRemote({
178
177
  sessionId: input.sessionId,
179
178
  ...ownerOf(declared),
@@ -184,16 +183,12 @@ export class McpPool {
184
183
  }
185
184
  const connection = await this.open({
186
185
  server: declared.server,
187
- pluginRoot: input.pluginRoots[pluginKey(declared)],
188
- pluginData: join(this.options.pluginData, ...pluginKey(declared).split("/")),
189
- childEnv: this.options.childEnv,
190
- authorize: declared.server.type === "stdio"
191
- ? undefined
192
- : (url) => this.options.authorize(input.sessionId, {
193
- url,
194
- serverName: declared.server.name,
195
- ...ownerOf(declared),
196
- }),
186
+ ...(this.options.policy ? { policy: this.options.policy } : {}),
187
+ authorize: (url) => this.options.authorize(input.sessionId, {
188
+ url,
189
+ serverName: declared.server.name,
190
+ ...ownerOf(declared),
191
+ }),
197
192
  });
198
193
  return { ok: true, connection };
199
194
  }
@@ -228,12 +223,6 @@ export function findServer(manifest, agentId, capabilityId, serverName) {
228
223
  item.capabilityId === capabilityId &&
229
224
  item.server.name === serverName);
230
225
  }
231
- /** Plugin roots of agents used as tools are registered as `<agent>/<capability>`. */
232
- function pluginKey(declared) {
233
- return declared.agentId === undefined
234
- ? declared.capabilityId
235
- : `${declared.agentId}/${declared.capabilityId}`;
236
- }
237
226
  function ownerOf(declared) {
238
227
  return declared.agentId === undefined ? {} : { agentId: declared.agentId };
239
228
  }
@@ -1,3 +1,4 @@
1
+ import type { EventPayload } from "@nylorun/core/contracts";
1
2
  import type { JsonObject } from "@nylorun/core/define";
2
3
  import { type AgentManifest } from "@nylorun/core/define";
3
4
  import type { DurableSessionTool, HostEffect } from "@nylorun/harness/run";
@@ -26,10 +27,15 @@ export interface McpDiagnostic {
26
27
  readonly message: string;
27
28
  readonly credentialIds?: readonly string[];
28
29
  }
30
+ /** The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot. */
31
+ export declare function mcpDiscovered(snapshot: McpSnapshot, diagnostics: readonly McpDiagnostic[]): EventPayload<"mcp.discovered">;
29
32
  export declare function modelToolName(serverName: string, serverToolName: string): string;
30
33
  export declare function declaredToolNames(manifest: AgentManifest): Set<string>;
31
- /** The tools of a snapshot, as the engine advertises them. */
32
- export declare function sessionToolsOf(snapshot: McpSnapshot | undefined): readonly DurableSessionTool[] | undefined;
34
+ /**
35
+ * The tools of a snapshot, as the engine advertises them. A tool of a server whose `approval` is
36
+ * `always` in the session's `manifest` waits for approval on each call.
37
+ */
38
+ export declare function sessionToolsOf(snapshot: McpSnapshot | undefined, manifest: AgentManifest): readonly DurableSessionTool[] | undefined;
33
39
  /** The snapshot's record of an MCP tool call, or undefined when the call is not an MCP tool. */
34
40
  export declare function mcpToolOf(snapshot: McpSnapshot | undefined, request: Pick<HostEffect, "agent" | "capabilityId" | "toolName">): McpToolRecord | undefined;
35
41
  /** The manifest of the agent an effect belongs to: the root, or an agent it uses as a tool. */
@@ -1,4 +1,22 @@
1
1
  import { delegateManifest } from "@nylorun/core/define";
2
+ /** The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot. */
3
+ export function mcpDiscovered(snapshot, diagnostics) {
4
+ const key = (item) => JSON.stringify([item.agentId ?? null, item.capabilityId, item.serverName]);
5
+ const tools = new Map();
6
+ for (const tool of snapshot.mcpTools)
7
+ tools.set(key(tool), (tools.get(key(tool)) ?? 0) + 1);
8
+ return {
9
+ servers: diagnostics.map((item) => ({
10
+ ...(item.agentId === undefined ? {} : { agentId: item.agentId }),
11
+ capabilityId: item.capabilityId,
12
+ serverName: item.serverName,
13
+ outcome: item.outcome,
14
+ message: item.message,
15
+ tools: tools.get(key(item)) ?? 0,
16
+ ...(item.credentialIds === undefined ? {} : { credentialIds: [...item.credentialIds] }),
17
+ })),
18
+ };
19
+ }
2
20
  export function modelToolName(serverName, serverToolName) {
3
21
  return `${serverName}__${serverToolName}`;
4
22
  }
@@ -9,10 +27,18 @@ export function declaredToolNames(manifest) {
9
27
  names.add(tool.name);
10
28
  return names;
11
29
  }
12
- /** The tools of a snapshot, as the engine advertises them. */
13
- export function sessionToolsOf(snapshot) {
30
+ /**
31
+ * The tools of a snapshot, as the engine advertises them. A tool of a server whose `approval` is
32
+ * `always` in the session's `manifest` waits for approval on each call.
33
+ */
34
+ export function sessionToolsOf(snapshot, manifest) {
14
35
  if (!snapshot?.mcpTools.length)
15
36
  return undefined;
37
+ const approved = (tool) => {
38
+ const agent = tool.agentId === undefined ? manifest : delegateManifest(manifest, tool.agentId);
39
+ const server = agent?.capabilities.find((item) => item.id === tool.capabilityId)?.mcpServers?.[tool.serverName];
40
+ return server !== undefined && "approval" in server && server.approval === "always";
41
+ };
16
42
  return snapshot.mcpTools.map((tool) => ({
17
43
  ...(tool.agentId === undefined ? {} : { agentId: tool.agentId }),
18
44
  capabilityId: tool.capabilityId,
@@ -24,6 +50,7 @@ export function sessionToolsOf(snapshot) {
24
50
  ...(tool.outputSchema === undefined
25
51
  ? {}
26
52
  : { outputSchema: tool.outputSchema }),
53
+ ...(approved(tool) ? { approval: "always" } : {}),
27
54
  }));
28
55
  }
29
56
  /** The snapshot's record of an MCP tool call, or undefined when the call is not an MCP tool. */
package/dist/media.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Image checks for code that handles image bytes itself (an image tool in an Action endpoint):
2
+ * Image checks for code that handles image bytes itself (a service behind an HTTP tool):
3
3
  * the supported types, the size cap and a signature check. Storing images is the job of file
4
4
  * artifacts (`artifacts/`, protocol 6), which replaced `MediaStore`.
5
5
  */
package/dist/media.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Image checks for code that handles image bytes itself (an image tool in an Action endpoint):
2
+ * Image checks for code that handles image bytes itself (a service behind an HTTP tool):
3
3
  * the supported types, the size cap and a signature check. Storing images is the job of file
4
4
  * artifacts (`artifacts/`, protocol 6), which replaced `MediaStore`.
5
5
  */
@@ -207,6 +207,9 @@ export function piModel(options = {}) {
207
207
  evidence: {
208
208
  resolvedModel: response.responseModel ?? selected.id,
209
209
  extras: {
210
+ // pi-ai initializes missing counters to zero; reporting provenance is unknown.
211
+ tokensReported: null,
212
+ costKnown: !selection.custom,
210
213
  producer: {
211
214
  provider: selected.provider,
212
215
  api: selected.api,