@nylorun/runtime 0.16.0-beta → 0.19.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 (256) hide show
  1. package/CHANGELOG.md +207 -0
  2. package/README.md +105 -63
  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/endpoint.js +1 -2
  9. package/dist/api/ag-ui/routes.d.ts +1 -1
  10. package/dist/api/ag-ui/routes.js +11 -13
  11. package/dist/api/ag-ui/translate.d.ts +1 -3
  12. package/dist/api/ag-ui/translate.js +2 -17
  13. package/dist/api/components.d.ts +4783 -2588
  14. package/dist/api/components.js +19 -21
  15. package/dist/api/gate/routes.d.ts +7 -8
  16. package/dist/api/gate/routes.js +58 -52
  17. package/dist/api/http/app.d.ts +6 -0
  18. package/dist/api/http/app.js +20 -14
  19. package/dist/api/http/define.d.ts +22 -13
  20. package/dist/api/http/define.js +43 -39
  21. package/dist/api/http/routes/access.d.ts +3 -19
  22. package/dist/api/http/routes/access.js +25 -184
  23. package/dist/api/http/routes/artifacts.js +3 -7
  24. package/dist/api/http/routes/files.d.ts +8 -0
  25. package/dist/api/http/routes/files.js +77 -0
  26. package/dist/api/http/routes/keys.d.ts +10 -0
  27. package/dist/api/http/routes/keys.js +64 -0
  28. package/dist/api/http/routes/me.d.ts +13 -0
  29. package/dist/api/http/routes/me.js +48 -0
  30. package/dist/api/http/routes/reads.d.ts +66 -0
  31. package/dist/api/http/routes/reads.js +127 -0
  32. package/dist/api/http/routes/sandboxes.d.ts +2 -2
  33. package/dist/api/http/routes/sandboxes.js +8 -7
  34. package/dist/api/http/routes/sessions.js +31 -20
  35. package/dist/api/http/routes/tenant.js +15 -18
  36. package/dist/api/http/routes/vaults.d.ts +13 -3
  37. package/dist/api/http/routes/vaults.js +136 -64
  38. package/dist/api/openapi.d.ts +10 -11
  39. package/dist/api/openapi.js +292 -68
  40. package/dist/artifacts/links.js +6 -6
  41. package/dist/artifacts/service.js +1 -1
  42. package/dist/core/flow-host.d.ts +44 -23
  43. package/dist/core/flow-host.js +88 -106
  44. package/dist/core/provider.d.ts +4 -1
  45. package/dist/core/provider.js +6 -1
  46. package/dist/core/sandbox-routes.d.ts +0 -9
  47. package/dist/core/sandbox-routes.js +2 -21
  48. package/dist/execution/memory.d.ts +4 -5
  49. package/dist/execution/memory.js +11 -25
  50. package/dist/execution/types.d.ts +3 -33
  51. package/dist/execution/types.js +2 -12
  52. package/dist/gates/http-tool.d.ts +86 -0
  53. package/dist/gates/http-tool.js +197 -0
  54. package/dist/gates/mcp-handler.d.ts +3 -0
  55. package/dist/gates/mcp-handler.js +6 -4
  56. package/dist/gates/meter.d.ts +2 -2
  57. package/dist/gates/meter.js +6 -0
  58. package/dist/gates/tenant-vaults.d.ts +19 -14
  59. package/dist/gates/tenant-vaults.js +17 -12
  60. package/dist/gates/tool-calls.d.ts +7 -15
  61. package/dist/gates/tool-calls.js +4 -4
  62. package/dist/gates/tool-client.d.ts +1 -1
  63. package/dist/gates/tool-client.js +23 -47
  64. package/dist/gates/tool-contract.d.ts +27 -39
  65. package/dist/gates/tool-contract.js +30 -21
  66. package/dist/gates/tool-gate.d.ts +25 -24
  67. package/dist/gates/tool-gate.js +11 -7
  68. package/dist/harness/calls.d.ts +10 -4
  69. package/dist/harness/calls.js +15 -6
  70. package/dist/harness/executors.d.ts +1 -1
  71. package/dist/harness/executors.js +17 -12
  72. package/dist/harness/main.d.ts +2 -2
  73. package/dist/harness/main.js +5 -13
  74. package/dist/harness/service.d.ts +4 -5
  75. package/dist/harness/service.js +9 -2
  76. package/dist/harness-api/in-process.js +2 -2
  77. package/dist/harness-api/record.d.ts +6 -3
  78. package/dist/harness-api/record.js +65 -72
  79. package/dist/harness-api/server.d.ts +1 -9
  80. package/dist/harness-api/server.js +19 -17
  81. package/dist/harness-api/start.js +1 -5
  82. package/dist/harness-api/workspace.js +2 -3
  83. package/dist/harness-api/ws-server.js +1 -1
  84. package/dist/host/app.d.ts +2 -10
  85. package/dist/host/app.js +24 -44
  86. package/dist/host/config-for.d.ts +5 -5
  87. package/dist/host/config-for.js +2 -3
  88. package/dist/host/config.d.ts +0 -11
  89. package/dist/host/create-host.d.ts +3 -40
  90. package/dist/host/create-host.js +18 -91
  91. package/dist/host/environment.d.ts +0 -3
  92. package/dist/host/environment.js +0 -9
  93. package/dist/host/gates.d.ts +4 -1
  94. package/dist/host/gates.js +9 -3
  95. package/dist/host/http.d.ts +1 -2
  96. package/dist/host/http.js +1 -7
  97. package/dist/host/index.d.ts +2 -2
  98. package/dist/host/index.js +2 -2
  99. package/dist/host/main.js +55 -40
  100. package/dist/host/operate.d.ts +29 -0
  101. package/dist/host/operate.js +223 -0
  102. package/dist/host/stack-config.d.ts +23 -20
  103. package/dist/host/stack-config.js +28 -44
  104. package/dist/index.d.ts +4 -1
  105. package/dist/index.js +3 -1
  106. package/dist/infra/workers.d.ts +1 -1
  107. package/dist/keys/client.js +9 -1
  108. package/dist/keys/keys.d.ts +12 -2
  109. package/dist/keys/keys.js +10 -2
  110. package/dist/management-openapi.json +6491 -0
  111. package/dist/mcp/connect.d.ts +8 -4
  112. package/dist/mcp/connect.js +8 -27
  113. package/dist/mcp/pool.d.ts +6 -9
  114. package/dist/mcp/pool.js +8 -18
  115. package/dist/mcp/snapshot.d.ts +8 -2
  116. package/dist/mcp/snapshot.js +29 -2
  117. package/dist/media.d.ts +1 -1
  118. package/dist/media.js +1 -1
  119. package/dist/model/pi-model.js +3 -0
  120. package/dist/openapi.json +6228 -15615
  121. package/dist/reads/access.d.ts +4 -0
  122. package/dist/reads/access.js +12 -0
  123. package/dist/reads/cursor.d.ts +11 -0
  124. package/dist/reads/cursor.js +80 -0
  125. package/dist/reads/types.d.ts +25 -0
  126. package/dist/reads/types.js +1 -0
  127. package/dist/sandbox/manager.d.ts +16 -0
  128. package/dist/sandbox/manager.js +40 -0
  129. package/dist/sandbox/session-sandbox.js +13 -3
  130. package/dist/sandbox/skills.d.ts +13 -0
  131. package/dist/sandbox/skills.js +46 -0
  132. package/dist/sandbox/types.d.ts +2 -2
  133. package/dist/store/ownership.d.ts +9 -0
  134. package/dist/store/ownership.js +13 -0
  135. package/dist/store/postgres/connect.d.ts +2 -0
  136. package/dist/store/postgres/connect.js +29 -0
  137. package/dist/store/postgres/drizzle/0008_installation_vaults.sql +2 -0
  138. package/dist/store/postgres/drizzle/0009_oauth_pending.sql +19 -0
  139. package/dist/store/postgres/drizzle/0010_oss_auth_removals.sql +3 -0
  140. package/dist/store/postgres/drizzle/0011_key_roles.sql +3 -0
  141. package/dist/store/postgres/drizzle/0012_session_reads.sql +8 -0
  142. package/dist/store/postgres/drizzle/0013_definition_files.sql +16 -0
  143. package/dist/store/postgres/drizzle/0014_action_endpoints_removed.sql +2 -0
  144. package/dist/store/postgres/drizzle/meta/_journal.json +49 -0
  145. package/dist/store/postgres/reads.d.ts +3 -0
  146. package/dist/store/postgres/reads.js +272 -0
  147. package/dist/store/postgres/schema.d.ts +423 -594
  148. package/dist/store/postgres/schema.js +84 -101
  149. package/dist/store/postgres/store.js +96 -248
  150. package/dist/store/postgres/tenant.d.ts +34 -2
  151. package/dist/store/postgres/tenant.js +16 -32
  152. package/dist/store/types.d.ts +44 -119
  153. package/dist/store/types.js +0 -1
  154. package/dist/streams/control.d.ts +0 -7
  155. package/dist/streams/control.js +0 -13
  156. package/dist/streams/types.d.ts +2 -20
  157. package/dist/streams/types.js +1 -1
  158. package/dist/tenant/advance.d.ts +3 -3
  159. package/dist/tenant/advance.js +10 -7
  160. package/dist/tenant/auth.d.ts +24 -15
  161. package/dist/tenant/auth.js +44 -55
  162. package/dist/tenant/cause.d.ts +3 -3
  163. package/dist/tenant/cause.js +1 -1
  164. package/dist/tenant/commands.d.ts +2 -18
  165. package/dist/tenant/commands.js +38 -179
  166. package/dist/tenant/context.d.ts +33 -45
  167. package/dist/tenant/definition-files.d.ts +24 -0
  168. package/dist/tenant/definition-files.js +103 -0
  169. package/dist/tenant/effects.d.ts +20 -18
  170. package/dist/tenant/effects.js +59 -133
  171. package/dist/tenant/ephemeral.d.ts +21 -8
  172. package/dist/tenant/ephemeral.js +11 -12
  173. package/dist/tenant/host-token.js +5 -5
  174. package/dist/tenant/identity-file.d.ts +75 -0
  175. package/dist/tenant/identity-file.js +202 -0
  176. package/dist/tenant/issuers.d.ts +48 -0
  177. package/dist/tenant/issuers.js +311 -0
  178. package/dist/tenant/jwt.js +3 -3
  179. package/dist/tenant/module.d.ts +1 -4
  180. package/dist/tenant/module.js +3 -12
  181. package/dist/tenant/operator-keys.d.ts +44 -0
  182. package/dist/tenant/operator-keys.js +87 -0
  183. package/dist/tenant/outbound.d.ts +40 -1
  184. package/dist/tenant/outbound.js +167 -18
  185. package/dist/tenant/paths.d.ts +1 -1
  186. package/dist/tenant/paths.js +1 -3
  187. package/dist/tenant/principals.d.ts +13 -13
  188. package/dist/tenant/principals.js +35 -36
  189. package/dist/tenant/run-token.js +6 -6
  190. package/dist/tenant/runtime.d.ts +5 -3
  191. package/dist/tenant/runtime.js +29 -15
  192. package/dist/tenant/sandboxes.d.ts +9 -6
  193. package/dist/tenant/sandboxes.js +16 -5
  194. package/dist/tenant/scheduler.d.ts +1 -5
  195. package/dist/tenant/scheduler.js +2 -5
  196. package/dist/tenant/session-streams.d.ts +8 -11
  197. package/dist/tenant/session-streams.js +48 -32
  198. package/dist/tenant/session.d.ts +8 -41
  199. package/dist/tenant/session.js +0 -37
  200. package/dist/tenant/sessions.d.ts +2 -2
  201. package/dist/tenant/sessions.js +17 -9
  202. package/dist/tenant/signing-keys.d.ts +3 -2
  203. package/dist/tenant/signing-keys.js +5 -5
  204. package/dist/tenant/skill-tool.d.ts +20 -0
  205. package/dist/tenant/skill-tool.js +72 -0
  206. package/dist/tenant/slim.d.ts +1 -1
  207. package/dist/tenant/slim.js +1 -1
  208. package/dist/tenant/status.js +7 -12
  209. package/dist/tenant/store-pg.d.ts +15 -0
  210. package/dist/tenant/store-pg.js +7 -3
  211. package/dist/tenant/streams.d.ts +3 -11
  212. package/dist/tenant/streams.js +2 -29
  213. package/dist/tenant/sweep.js +0 -5
  214. package/dist/tenant/transcript.d.ts +2 -2
  215. package/dist/tenant/transcript.js +2 -2
  216. package/dist/tenant/types.d.ts +33 -19
  217. package/dist/tenant/worker.d.ts +1 -3
  218. package/dist/tenant/worker.js +3 -8
  219. package/dist/vault/crypto.d.ts +7 -0
  220. package/dist/vault/crypto.js +16 -0
  221. package/dist/vault/oauth.d.ts +55 -0
  222. package/dist/vault/oauth.js +186 -0
  223. package/dist/vault/service.d.ts +54 -7
  224. package/dist/vault/service.js +261 -17
  225. package/dist/vault/sources.d.ts +60 -0
  226. package/dist/vault/sources.js +196 -0
  227. package/dist/version.d.ts +1 -1
  228. package/dist/version.js +1 -1
  229. package/package.json +5 -4
  230. package/dist/admin-openapi.json +0 -604
  231. package/dist/api/http/routes/actions.d.ts +0 -8
  232. package/dist/api/http/routes/actions.js +0 -76
  233. package/dist/api/http/routes/endpoints.d.ts +0 -7
  234. package/dist/api/http/routes/endpoints.js +0 -100
  235. package/dist/host/admin-api.d.ts +0 -23
  236. package/dist/host/admin-api.js +0 -74
  237. package/dist/host/cors.d.ts +0 -27
  238. package/dist/host/cors.js +0 -64
  239. package/dist/mcp/stdio.d.ts +0 -17
  240. package/dist/mcp/stdio.js +0 -82
  241. package/dist/tenant/access-policy.d.ts +0 -30
  242. package/dist/tenant/access-policy.js +0 -52
  243. package/dist/tenant/actions.d.ts +0 -14
  244. package/dist/tenant/actions.js +0 -29
  245. package/dist/tenant/browser.d.ts +0 -15
  246. package/dist/tenant/browser.js +0 -39
  247. package/dist/tenant/delivery-token.d.ts +0 -41
  248. package/dist/tenant/delivery-token.js +0 -104
  249. package/dist/tenant/delivery.d.ts +0 -62
  250. package/dist/tenant/delivery.js +0 -481
  251. package/dist/tenant/endpoints.d.ts +0 -67
  252. package/dist/tenant/endpoints.js +0 -90
  253. package/dist/tenant/subject-limits.d.ts +0 -16
  254. package/dist/tenant/subject-limits.js +0 -45
  255. package/dist/tenant/tokens.d.ts +0 -14
  256. package/dist/tenant/tokens.js +0 -187
@@ -5,8 +5,7 @@
5
5
  *
6
6
  * Business code changes state only inside `ctx.store.tx(async (t) => …)` and follows the
7
7
  * seam rules: events through `t.event(...)` (the relay appends them to Durable Streams after
8
- * commit), deliveries through `t.afterCommit(() => ctx.deliver(actionId))`, and advances through
9
- * `t.afterCommit(() => ctx.wake(id, { reason, dedupeKey }))`. It never publishes or notifies
8
+ * commit), and advances through `t.afterCommit(() => ctx.wake(id, { reason, dedupeKey }))`. It never publishes or notifies
10
9
  * itself; `runtime.ts` wires the streams with `wireStreams()`. No external I/O runs inside a
11
10
  * tx.
12
11
  *
@@ -14,7 +13,7 @@
14
13
  * under ownership (§10.6); `abortLocal` aborts an advance running on this process.
15
14
  */
16
15
  import type { SessionHistory } from "./history.js";
17
- import type { RoleLimits, SubjectScope, TenantEnvelope } from "@nylorun/core/contracts";
16
+ import type { IssuerScope, SubjectScope, TenantEnvelope } from "@nylorun/core/contracts";
18
17
  import type { DurableCheckpoint, FlowCheckpoint } from "@nylorun/harness/run";
19
18
  import type { AgentManifest, JsonValue, SandboxManifest } from "@nylorun/core/define";
20
19
  import type { CredentialSelection } from "@nylorun/core/contracts";
@@ -25,6 +24,7 @@ import type { ModelGate } from "../gates/model-gate.js";
25
24
  import type { ToolGate } from "../gates/tool-gate.js";
26
25
  import type { Keys } from "../keys/keys.js";
27
26
  import type { VaultService } from "../vault/service.js";
27
+ import type { CredentialSources } from "../vault/sources.js";
28
28
  import type { McpPool } from "../mcp/pool.js";
29
29
  import type { McpDiagnostic, McpSnapshot } from "../mcp/snapshot.js";
30
30
  import type { HarnessApiServer } from "../harness-api/server.js";
@@ -71,7 +71,6 @@ export interface Session {
71
71
  creation: unknown;
72
72
  vaultIds?: readonly string[];
73
73
  credentialSelections?: readonly CredentialSelection[];
74
- pluginRoots?: Readonly<Record<string, string>>;
75
74
  mcpSnapshot?: McpSnapshot;
76
75
  mcpDiagnostics?: readonly McpDiagnostic[];
77
76
  /** Session id that keys the shared sandbox; absent means this session owns it. */
@@ -95,22 +94,33 @@ export type AuthScope = {
95
94
  principalId: string;
96
95
  }
97
96
  /**
98
- * A subject token (Host feature `subject-tokens`): one subject, the role's scopes and agents
99
- * narrowed by the token, until `expiresAt` (ms) or the subject's epoch moves past `epoch`.
97
+ * A management key (role `management`), or Studio's key on a Management API route: the
98
+ * principal acting as itself, never for a subject. It reaches only the Management API
99
+ * (`/v1/tenant/*`) and `/v1/me`.
100
+ */
101
+ | {
102
+ kind: "management";
103
+ principalId: string;
104
+ }
105
+ /**
106
+ * A trusted issuer's token (Host feature `trusted-issuers`, F9-D12): one subject, with the
107
+ * issuer's scopes, agents and sandbox grants, until `expiresAt` (ms). Only its expiry ends it.
100
108
  */
101
109
  | {
102
110
  kind: "token";
111
+ /** The identity file's issuer that signed it. */
112
+ issuer: string;
103
113
  subject: string;
104
- scopes: ReadonlySet<SubjectScope>;
114
+ /** The issuer's scopes the token holds, which may add `studio`. */
115
+ scopes: ReadonlySet<IssuerScope>;
105
116
  agents: ReadonlySet<string> | "*";
106
- role: string;
107
- limits?: RoleLimits;
108
- /** The token's `sbx` grants: the sandboxes it reaches. Absent reaches none. */
117
+ /** The sandboxes it reaches: exact ids or `p/*` prefixes. Absent or empty reaches none. */
109
118
  sandboxes?: readonly string[];
110
- epoch: number;
111
119
  expiresAt: number;
120
+ /** The token's `jti`, or a hash of it. */
112
121
  tokenId: string;
113
- keyId: string;
122
+ /** The issuer key's `kid`, when it has one. */
123
+ keyId?: string;
114
124
  }
115
125
  /** An application principal acting for `subject` (`Nylorun-Subject`), narrowed to `scopes`. */
116
126
  | {
@@ -122,35 +132,18 @@ export type AuthScope = {
122
132
  /** No credential, on a route that serves public data (`RouteAccess.anonymous`). */
123
133
  | {
124
134
  kind: "anonymous";
125
- }
126
- /**
127
- * A delivery token (Action endpoints): the Runtime's own token for one delivery of one
128
- * Action, presented back by the Action endpoint on that Action's callbacks only.
129
- */
130
- | {
131
- kind: "delivery";
132
- actionId: string;
133
- agentId: string;
134
- generation: number;
135
- expiresAt: number;
136
- tokenId: string;
137
- keyId: string;
138
- }
139
- /**
140
- * A publishable key with no bearer (Host feature `browser-access`): what the policy grants
141
- * `anon`, at most `agents:read`. It owns no session or vault.
142
- */
143
- | {
144
- kind: "publishable";
145
- keyId: string;
146
- scopes: ReadonlySet<SubjectScope>;
147
- agents: ReadonlySet<string> | "*";
148
135
  };
149
136
  export interface TenantContext {
137
+ readonly reads?: import("../reads/types.js").ReadStore;
150
138
  readonly config: TenantConfig;
151
139
  readonly envelope: TenantEnvelope;
152
140
  readonly store: SessionStore;
153
141
  readonly vault: VaultService;
142
+ /**
143
+ * A session's MCP credentials, for the in-process MCP pool: its attached vaults, then the
144
+ * operator's credential resolver (`TenantConfig.resolver`, F9 C1).
145
+ */
146
+ readonly credentials: CredentialSources;
154
147
  /**
155
148
  * The MCP pool of the Tenant's in-process harness. Absent when harnesses run elsewhere
156
149
  * (`NYLORUN_HARNESS=remote`): each keeps its own (F6.2).
@@ -168,8 +161,8 @@ export interface TenantContext {
168
161
  /** Serves vault-backed model calls (blueprint §15): in this process, or the gates service. */
169
162
  readonly modelGate: ModelGate;
170
163
  /**
171
- * Serves remote MCP servers and Action deliveries (blueprint §12, F4.1): in this process, or
172
- * the gates service.
164
+ * Serves remote MCP servers and HTTP tools (blueprint §12, F4.1): in this process, or the
165
+ * gates service.
173
166
  */
174
167
  readonly toolGate: ToolGate;
175
168
  /**
@@ -208,7 +201,7 @@ export interface TenantContext {
208
201
  readonly work: WorkState;
209
202
  /** Live delivery over Durable Streams: one `SessionStream` per observed session, and the streams wiring. */
210
203
  readonly sessionStreams: SessionStreams;
211
- /** The Tenant's signing keys for subject tokens. */
204
+ /** The Tenant's signing keys: capability links, run and host tokens. */
212
205
  readonly signingKeys: SigningKeys;
213
206
  /** The Worker id this process writes as session `owner` (§10.6). */
214
207
  readonly workerId: string;
@@ -225,11 +218,6 @@ export interface TenantContext {
225
218
  * an advance of that turn (a cancel signal names the turn it cancelled).
226
219
  */
227
220
  abortLocal(sessionId: string, turnId?: string): void;
228
- /**
229
- * Seam: deliver an Action to its agent's Action endpoint (`DurableExecution.deliver`). Call it
230
- * from `t.afterCommit`. Dropped while the Tenant is closing; the sweep re-sends it.
231
- */
232
- deliver(actionId: string): Promise<void>;
233
221
  /**
234
222
  * Sandbox pods (F7.2): the sandboxes service and the Runtime image pods copy the engine from.
235
223
  * Absent without a cluster (`nylorun sandbox enable`): kind `pod` is `sandbox_unavailable`.
@@ -248,8 +236,8 @@ export interface TenantContext {
248
236
  onSweep(hook: () => Promise<void>): () => void;
249
237
  }
250
238
  /**
251
- * What a request acting for a person may reach: that person's sessions and vaults, and, for a
252
- * subject token, only sessions of the agents its role allows. Undefined means the whole Tenant.
239
+ * What a request acting for a person may reach: that person's sessions, and, for a token
240
+ * caller, only sessions of the agents its issuer allows. Undefined means the whole Tenant.
253
241
  */
254
242
  export interface SessionAccess {
255
243
  readonly owner: string;
@@ -0,0 +1,24 @@
1
+ import { type DefinitionFileView } from "@nylorun/core/contracts";
2
+ import type { BlobStore } from "../blob/index.js";
3
+ import type { Tx } from "../store/types.js";
4
+ import type { TenantContext } from "./context.js";
5
+ /** Where a definition file's bytes are in the Object store. */
6
+ export declare function definitionFileKey(sha256: string): string;
7
+ /** Whether the Tenant holds definition file `file` (`sha256:<hex>`). */
8
+ export declare function hasDefinitionFile(ctx: TenantContext, file: string): Promise<boolean>;
9
+ /**
10
+ * Stores the bytes of definition file `file`: `201` when they are new, `200` when the Tenant
11
+ * holds them already (the body is not read). Bytes that do not hash to `file` are a `400`.
12
+ */
13
+ export declare function putDefinitionFile(ctx: TenantContext, file: string, request: {
14
+ body: ReadableStream<Uint8Array> | null;
15
+ declaredBytes?: number;
16
+ contentType?: string;
17
+ }, signal?: AbortSignal): Promise<{
18
+ status: 200 | 201;
19
+ view: DefinitionFileView;
20
+ }>;
21
+ /** The definition files `document` names that the Tenant does not hold, in order. */
22
+ export declare function missingDefinitionFiles(t: Tx, document: unknown): Promise<string[]>;
23
+ /** A definition file's bytes, or undefined when the Object store does not have them. */
24
+ export declare function readDefinitionFile(blobs: BlobStore, sha256: string, signal?: AbortSignal): Promise<Uint8Array | undefined>;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Definition files (track R2 M4): the files a definition names by the SHA-256 of their bytes,
3
+ * today a skill's folder (`SkillManifest.files`). A client uploads each one once
4
+ * (`PUT /v1/files/sha256:<hex>`); its bytes go to the Object store at
5
+ * `definitions/sha256/<hex>`, and a `definition_files` row says the Tenant holds it. A
6
+ * definition naming a file the Tenant does not hold is refused (`definition_files_missing`).
7
+ * The Runtime reads them to serve the skill tools and to give a sandbox the skills' files.
8
+ *
9
+ * Files are never deleted here: `definition_file_uses` records which definition version names
10
+ * which file, for a later sweep.
11
+ */
12
+ import { createHash } from "node:crypto";
13
+ import { DEFINITION_FILE_MAX_BYTES, definitionFilesOf, isDefinitionFileHash, } from "@nylorun/core/contracts";
14
+ import { fail } from "./http.js";
15
+ /** Where a definition file's bytes are in the Object store. */
16
+ export function definitionFileKey(sha256) {
17
+ return `definitions/sha256/${sha256.slice("sha256:".length)}`;
18
+ }
19
+ function checkHash(file) {
20
+ if (!isDefinitionFileHash(file))
21
+ fail(400, "A definition file is named sha256:<64 lowercase hex>", { code: "invalid_request" });
22
+ return file;
23
+ }
24
+ /** Whether the Tenant holds definition file `file` (`sha256:<hex>`). */
25
+ export async function hasDefinitionFile(ctx, file) {
26
+ const sha256 = checkHash(file);
27
+ return (await ctx.store.tx((t) => t.definitionFile(sha256))) !== undefined;
28
+ }
29
+ /** The body, at most `DEFINITION_FILE_MAX_BYTES`; past it, `413 limit_exceeded`. */
30
+ async function readBody(body, declared) {
31
+ const tooLarge = () => fail(413, `A definition file may hold at most ${DEFINITION_FILE_MAX_BYTES} bytes`, {
32
+ code: "limit_exceeded",
33
+ details: { limitBytes: DEFINITION_FILE_MAX_BYTES },
34
+ });
35
+ if (declared !== undefined && declared > DEFINITION_FILE_MAX_BYTES) {
36
+ await body?.cancel().catch(() => undefined);
37
+ tooLarge();
38
+ }
39
+ if (body === null)
40
+ return new Uint8Array();
41
+ const chunks = [];
42
+ let size = 0;
43
+ const reader = body.getReader();
44
+ for (;;) {
45
+ const { done, value } = await reader.read();
46
+ if (done)
47
+ break;
48
+ size += value.byteLength;
49
+ if (size > DEFINITION_FILE_MAX_BYTES) {
50
+ await reader.cancel().catch(() => undefined);
51
+ tooLarge();
52
+ }
53
+ chunks.push(value);
54
+ }
55
+ return Buffer.concat(chunks);
56
+ }
57
+ /**
58
+ * Stores the bytes of definition file `file`: `201` when they are new, `200` when the Tenant
59
+ * holds them already (the body is not read). Bytes that do not hash to `file` are a `400`.
60
+ */
61
+ export async function putDefinitionFile(ctx, file, request, signal) {
62
+ const sha256 = checkHash(file);
63
+ const held = await ctx.store.tx((t) => t.definitionFile(sha256));
64
+ if (held) {
65
+ await request.body?.cancel().catch(() => undefined);
66
+ return { status: 200, view: { sha256, size: held.size } };
67
+ }
68
+ const bytes = await readBody(request.body, request.declaredBytes);
69
+ const actual = `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
70
+ if (actual !== sha256)
71
+ fail(400, `The body's SHA-256 is ${actual}, not ${sha256}: upload a file at its own hash`, {
72
+ code: "invalid_request",
73
+ details: { expected: sha256, actual },
74
+ });
75
+ // The key is the content's hash: a concurrent upload of the same file writes the same bytes.
76
+ await ctx.blobs.put(definitionFileKey(sha256), bytes, {
77
+ ...(request.contentType === undefined ? {} : { contentType: request.contentType }),
78
+ ...(signal ? { signal } : {}),
79
+ });
80
+ const inserted = await ctx.store.tx((t) => t.insertDefinitionFile({
81
+ sha256,
82
+ kind: "skill",
83
+ size: bytes.byteLength,
84
+ contentType: request.contentType ?? null,
85
+ createdAt: new Date().toISOString(),
86
+ }));
87
+ return { status: inserted ? 201 : 200, view: { sha256, size: bytes.byteLength } };
88
+ }
89
+ /** The definition files `document` names that the Tenant does not hold, in order. */
90
+ export async function missingDefinitionFiles(t, document) {
91
+ const named = [...definitionFilesOf(document)].sort();
92
+ if (named.length === 0)
93
+ return [];
94
+ const held = await t.heldDefinitionFiles(named);
95
+ return named.filter((sha256) => !held.has(sha256));
96
+ }
97
+ /** A definition file's bytes, or undefined when the Object store does not have them. */
98
+ export async function readDefinitionFile(blobs, sha256, signal) {
99
+ const got = await blobs.get(definitionFileKey(sha256), signal ? { signal } : {});
100
+ if (!got)
101
+ return undefined;
102
+ return new Uint8Array(await new Response(got.body).arrayBuffer());
103
+ }
@@ -1,18 +1,20 @@
1
1
  /**
2
2
  * Core's side of effects: `resolveNewFlowEffect` journals and dispatches new workflow effects
3
- * (linked agent sessions, tool nodes, fn, verify); the takeover helpers say which calls their
4
- * gate recovers. Also vault authorization for MCP servers. The journal of a run's effects is
5
- * `harness-api/record.ts`; a harness readies the session's MCP servers itself (`session.mcp`).
3
+ * (linked agent sessions; a tool node without `http` fails, as it would run the developer's
4
+ * code); the takeover helpers say which calls their gate recovers. Also vault authorization
5
+ * for MCP servers and HTTP tools. The journal of a run's effects is `harness-api/record.ts`; a
6
+ * harness readies the session's MCP servers itself (`session.mcp`).
6
7
  *
7
8
  * Every journal write runs in a transaction that locks the effect's session first and checks
8
9
  * the advance's ownership epoch (`ownedSession`): after another Worker takes over, the next
9
- * write throws `ownership.lost` and nothing is written. The model, MCP, sandbox and vault
10
+ * write throws `ownership.lost` and nothing is written. The model, MCP, HTTP, sandbox and vault
10
11
  * calls run between transactions, never inside one.
11
12
  */
12
- import type { ActionOutcome } from "@nylorun/core/contracts";
13
+ import type { EffectOutcome } from "@nylorun/core/contracts";
13
14
  import type { EffectResolution, HostEffect } from "@nylorun/harness/run";
14
15
  import type { Tx } from "../store/types.js";
15
16
  import type { AuthorizeResult } from "../vault/service.js";
17
+ import type { McpCredentialRequest } from "../vault/sources.js";
16
18
  import { type Lease, type Session, type TenantContext } from "./context.js";
17
19
  /**
18
20
  * The outcome of a flow `agent` effect once the linked turn it started ended, or undefined
@@ -21,25 +23,25 @@ import { type Lease, type Session, type TenantContext } from "./context.js";
21
23
  export declare function linkedOutcome(t: Tx, effect: {
22
24
  request: HostEffect;
23
25
  agentSessionId?: string;
24
- }, agent: Session | undefined): Promise<ActionOutcome | undefined>;
26
+ }, agent: Session | undefined): Promise<EffectOutcome | undefined>;
25
27
  /**
26
- * True when this Tenant's remote MCP calls outlive the process that sent them (the gates
27
- * service, F4.1 G3): after a takeover or a shutdown, the journaled call is re-sent and joins
28
- * the running call or gets its answer, instead of becoming `uncertain`.
28
+ * True when this Tenant's remote MCP and HTTP tool calls outlive the process that sent them
29
+ * (the gates service, F4.1 G3): after a takeover or a shutdown, the journaled call is re-sent
30
+ * and joins the running call or gets its answer, instead of becoming `uncertain`.
29
31
  */
30
- export declare function recoversMcpCalls(ctx: TenantContext): boolean;
31
- /** True when `request` calls a tool of a remote (`streamable-http` or `sse`) MCP server. */
32
- export declare function isRemoteMcpEffect(s: Session, request: HostEffect): boolean;
32
+ export declare function recoversToolCalls(ctx: TenantContext): boolean;
33
+ /** True when `request` calls a tool of a declared MCP server (every one is remote) or an HTTP tool. */
34
+ export declare function isGateToolEffect(s: Session, request: HostEffect): boolean;
33
35
  /**
34
36
  * True when this Tenant's vault-backed model calls outlive the process that sent them (the
35
37
  * gates service, P1.2): after a takeover or a shutdown, the journaled call is re-sent and joins
36
38
  * the running call or gets its outcome, instead of becoming `uncertain`.
37
39
  */
38
40
  export declare function recoversModelCalls(ctx: TenantContext): boolean;
39
- /** Journal and dispatch a new flow effect (agent / tool node / fn / verify). */
41
+ /** Journal and dispatch a new flow effect (agent or tool node). */
40
42
  export declare function resolveNewFlowEffect(ctx: TenantContext, request: HostEffect, signal: AbortSignal, lease: Lease): Promise<EffectResolution>;
41
- /** Vault authorization for an MCP server request made on behalf of a session. */
42
- export declare function authorize(ctx: TenantContext, sessionId: string, request: {
43
- url: string;
44
- serverName?: string;
45
- }): Promise<AuthorizeResult>;
43
+ /**
44
+ * The credential of an MCP server or HTTP tool request made on behalf of a session: from its
45
+ * attached vaults, else the operator's credential resolver (`vault/sources.ts`).
46
+ */
47
+ export declare function authorize(ctx: TenantContext, sessionId: string, request: McpCredentialRequest): Promise<AuthorizeResult>;