@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
@@ -14,7 +14,7 @@
14
14
  * error `fn` threw.
15
15
  * 2. **Session-scoped writes lock the session row first.** `lockSession` takes
16
16
  * a row lock (`SELECT … FOR UPDATE`) held until the transaction ends. Effect
17
- * intent and outcome, Action transitions, checkpoint settlement and event
17
+ * intent and outcome, checkpoint settlement and event
18
18
  * writes for one session are serialized through it. Idempotency comparisons
19
19
  * (`canonical(...)`) run inside the same locked transaction. `event` and the
20
20
  * ownership methods take the lock themselves.
@@ -25,7 +25,7 @@
25
25
  * generation, `streams/basin.ts`), and the cursor is
26
26
  * `base64url("<sessionId>:<seq>")` (see `record/cursor.ts`).
27
27
  * 4. **No external I/O inside `fn`.** No model, tool, MCP, sandbox, Restate or
28
- * S2 call, and no `fetch`, runs inside a transaction. Wakes and deliveries go
28
+ * S2 call, and no `fetch`, runs inside a transaction. Wakes go
29
29
  * through `afterCommit`, and events are delivered to commit listeners after
30
30
  * commit (seam rule 1 and 2).
31
31
  * 5. **No nested transactions.** Calling `store.tx` from inside `fn` rejects.
@@ -45,29 +45,28 @@
45
45
  * ## Typed queries, no scans
46
46
  *
47
47
  * There is no generic table scan. Every read the Runtime needs is a typed
48
- * method on `Tx` (`sessionsWithStatus`, `expiredDeliveries`, `pendingActions`,
49
- * `effectsForTurn`, `linkedSessions`, `counts`, …) that an implementation can
50
- * back with an index, and principals, endpoints, vaults and Tenant settings
48
+ * method on `Tx` (`sessionsWithStatus`, `effectsForTurn`, `linkedSessions`,
49
+ * `counts`, …) that an implementation can back with an index, and principals,
50
+ * vaults and Tenant settings
51
51
  * have their own methods rather than raw SQL outside the store. Session history
52
52
  * is not read from the store: every event is written to the record (Postgres
53
53
  * `nylorun_streams.session_events`) in its transaction, the stream relay
54
54
  * (`streams/relay/`) feeds Durable Streams from it, and history and SSE read
55
55
  * them there (`tenant/session-streams.ts`).
56
56
  */
57
+ import type { KeyRole } from "@nylorun/core/compatibility";
57
58
  import type { RecordReader } from "../streams/relay/types.js";
58
- import type { Action, EventPayload, EventType, LiveEvent, SandboxEvent, SandboxEventPayload, SandboxEventType, SandboxKind, SandboxPodDesired, SandboxPodObserved, SessionEventOf } from "@nylorun/core/contracts";
59
+ import type { EventPayload, EventType, LiveEvent, SandboxEvent, SandboxEventPayload, SandboxEventType, SandboxKind, SandboxPodDesired, SandboxPodObserved, SessionEventOf } from "@nylorun/core/contracts";
59
60
  import type { SandboxManifest } from "@nylorun/core/define";
60
61
  import type { HostEffect } from "@nylorun/harness/run";
61
- import type { ArtifactRow, ArtifactVersionRow, ModelBudgetRow, ModelUsageRow, PrincipalRow, ToolCrossingRow, PublishableKeyRow, SigningKeyRow, SubjectUsageRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow } from "./postgres/schema.js";
62
+ import type { ArtifactRow, ArtifactVersionRow, DefinitionFileRow, ModelBudgetRow, ModelUsageRow, ModelUsageWrite, PrincipalRow, ToolCrossingRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, OAuthPendingRow } from "./postgres/schema.js";
62
63
  /** Tables holding JSON documents keyed by `id`. */
63
- export type DocTable = "definitions" | "sessions" | "commands" | "effects" | "actions" | "sandboxes" | "links";
64
+ export type DocTable = "definitions" | "sessions" | "commands" | "effects" | "sandboxes" | "links";
64
65
  export declare const DOC_TABLES: readonly DocTable[];
65
66
  /** Session lifecycle (architecture §10.2). */
66
67
  export type SessionStatus = "idle" | "runnable" | "running" | "waiting" | "paused" | "uncertain" | "completed" | "failed" | "cancelled";
67
68
  /** Effect states (§10.3), plus the flow host's `queued` and `cancelled`. */
68
69
  export type EffectStatus = "pending" | "invoking" | "completed" | "uncertain" | "queued" | "cancelled";
69
- export type ActionStatus = Action["status"];
70
- export type ActionKind = Action["kind"];
71
70
  export type EffectKind = HostEffect["kind"];
72
71
  /**
73
72
  * Ownership of a session by a Worker (§10.6). Read with the session; written
@@ -103,8 +102,6 @@ export interface EffectDoc {
103
102
  request: HostEffect;
104
103
  status: EffectStatus | (string & {});
105
104
  }
106
- /** Actions are stored as the wire `Action`. Indexed: `sessionId`, `turnId`, `agentId`, `status`, `kind`, `deadlineAt`. */
107
- export type ActionDoc = Action;
108
105
  /** A workflow → agent session link, keyed by the linked agent session id. Indexed: `workflowSessionId`. */
109
106
  export interface LinkDoc {
110
107
  workflowSessionId: string;
@@ -192,60 +189,13 @@ export interface BasinGenerations {
192
189
  retired: number[];
193
190
  }
194
191
  export type CommitListener = (commit: Commit) => void;
195
- /**
196
- * An Action endpoint: the URL the Runtime delivers one agent's Actions to, and what recent
197
- * deliveries and the last ping say about it.
198
- */
199
- export interface EndpointRow {
200
- agentId: string;
201
- url: string;
202
- implementationVersion: string;
203
- manifestHash?: string;
204
- timeoutMs: number;
205
- maxConcurrent: number;
206
- /** Application principal that registered it, when known. */
207
- principalId?: string;
208
- lastDeliveryAt?: string;
209
- lastSuccessAt?: string;
210
- lastErrorCode?: string;
211
- lastErrorMessage?: string;
212
- consecutiveFailures: number;
213
- /** What the endpoint reported serving on the last ping. */
214
- servedImplementationVersion?: string;
215
- servedManifestHash?: string;
216
- createdAt: string;
217
- updatedAt: string;
218
- }
219
- /** The registration part of an endpoint, as `putEndpoint` writes it. */
220
- export type EndpointRegistrationRow = Pick<EndpointRow, "agentId" | "url" | "implementationVersion" | "manifestHash" | "timeoutMs" | "maxConcurrent" | "principalId" | "updatedAt">;
221
- /** One observation about an endpoint (`recordEndpointHealth`). */
222
- export type EndpointHealthUpdate =
223
- /** A delivery was answered. */
224
- {
225
- kind: "success";
226
- at: string;
227
- }
228
- /** A delivery failed: not reached, refused, or lost. */
229
- | {
230
- kind: "failure";
231
- at: string;
232
- code: string;
233
- message: string;
234
- }
235
- /** A ping was answered with what the endpoint serves. */
236
- | {
237
- kind: "served";
238
- implementationVersion: string;
239
- manifestHash?: string;
240
- };
241
192
  /**
242
193
  * The rows of the typed tables, inferred from the tables Drizzle defines
243
194
  * (`store/postgres/schema.ts`): a principal, a vault and its credentials (secrets sealed in
244
195
  * `bytea` columns, never inside a JSON body), the vault's audit and idempotency records, the
245
- * Tenant's signing keys, a subject's turn bucket, a publishable key, a model call in the usage
246
- * ledger and a model budget.
196
+ * Tenant's signing keys, a model call in the usage ledger and a model budget.
247
197
  */
248
- export type { ArtifactRow, ArtifactVersionRow, ModelBudgetRow, ModelUsageRow, ToolCrossingRow, PrincipalRow, PublishableKeyRow, SigningKeyRow, SubjectUsageRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, };
198
+ export type { ArtifactRow, ArtifactVersionRow, DefinitionFileRow, ModelBudgetRow, ModelUsageRow, ModelUsageWrite, ToolCrossingRow, PrincipalRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, OAuthPendingRow, };
249
199
  /** Which rows of the usage ledger a total covers. */
250
200
  export interface ModelUsageQuery {
251
201
  scope: "tenant" | "agent" | "turn";
@@ -266,18 +216,11 @@ export interface SessionEffectFilter {
266
216
  turnId?: string;
267
217
  statuses?: readonly (EffectStatus | (string & {}))[];
268
218
  }
269
- export interface SessionActionFilter {
270
- /** Only this turn. Absent means every turn. */
271
- turnId?: string;
272
- statuses?: readonly ActionStatus[];
273
- }
274
219
  /** Counts used by Tenant status, `summary` and `drain`. */
275
220
  export interface StoreCounts {
276
221
  sessions: number;
277
222
  /** Sessions `running` or `runnable`. */
278
223
  runningSessions: number;
279
- /** Actions `pending` or `delivering`. */
280
- pendingActions: number;
281
224
  /** Effects `uncertain`. */
282
225
  uncertainEffects: number;
283
226
  sandboxes: number;
@@ -440,18 +383,6 @@ export interface Tx {
440
383
  fromSeq?: number;
441
384
  limit?: number;
442
385
  }): Promise<SandboxEvent[]>;
443
- /** One agent's `pending` actions, delivered when its endpoint is registered. */
444
- pendingActions(agentId: string): Promise<ActionDoc[]>;
445
- /** How many of one agent's actions are `delivering` (Action endpoints). */
446
- deliveringCount(agentId: string): Promise<number>;
447
- /** `pending` actions of agents that have an Action endpoint, by id. */
448
- pendingActionsWithEndpoint(limit: number): Promise<ActionDoc[]>;
449
- /** `delivering` actions whose deadline is at or before `now`, earliest first. */
450
- expiredDeliveries(now: Date, limit: number): Promise<ActionDoc[]>;
451
- actionsForSession(sessionId: string, filter?: SessionActionFilter): Promise<ActionDoc[]>;
452
- actionsWithStatus(statuses: readonly ActionStatus[], filter?: {
453
- kinds?: readonly ActionKind[];
454
- }): Promise<ActionDoc[]>;
455
386
  /** `invoking` effects of one session; takeover turns them `uncertain`. */
456
387
  invokingEffects<T extends EffectDoc = EffectDoc>(sessionId: string): Promise<T[]>;
457
388
  effectsForSession<T extends EffectDoc = EffectDoc>(sessionId: string, filter?: SessionEffectFilter): Promise<T[]>;
@@ -465,26 +396,28 @@ export interface Tx {
465
396
  basinGenerations(): Promise<BasinGenerations>;
466
397
  /** Forgets a retired generation once its basin is deleted. */
467
398
  forgetRetiredGeneration(generation: number): Promise<void>;
468
- listEndpoints(): Promise<EndpointRow[]>;
469
- getEndpoint(agentId: string): Promise<EndpointRow | undefined>;
470
- /**
471
- * Inserts or updates by `agentId`, keeping `createdAt`. Health is kept, except that a new
472
- * `url` starts with none.
473
- */
474
- putEndpoint(row: EndpointRegistrationRow): Promise<void>;
475
- deleteEndpoint(agentId: string): Promise<void>;
476
- /** Records one observation. Nothing happens when the endpoint does not exist. */
477
- recordEndpointHealth(agentId: string, update: EndpointHealthUpdate): Promise<void>;
478
399
  /** Rejects when the id or token hash already exists. */
479
400
  insertPrincipal(row: PrincipalRow): Promise<void>;
480
401
  principalByTokenHash(tokenHash: string): Promise<PrincipalRow | undefined>;
481
402
  principalById(id: string): Promise<PrincipalRow | undefined>;
482
- applicationTokenHashes(): Promise<string[]>;
403
+ /** Every principal, ordered by id. */
404
+ listPrincipals(): Promise<PrincipalRow[]>;
405
+ /**
406
+ * Creates principal `id` with `tokenHash` and `role` (default `application`), or gives an
407
+ * existing one this hash (and `createdAt`): its previous key stops authenticating. Rejects
408
+ * when another principal holds the hash, and with `PrincipalRoleConflict` when `id` holds
409
+ * another role.
410
+ */
411
+ putPrincipal(id: string, tokenHash: string, createdAt: string, role?: KeyRole): Promise<PrincipalRow>;
412
+ /** Deletes principal `id`; false when there was none. */
413
+ deletePrincipal(id: string): Promise<boolean>;
483
414
  /** Rejects on a duplicate id, or a second `host` vault. */
484
415
  insertVault(row: VaultRow): Promise<void>;
485
416
  getVault(id: string): Promise<VaultRow | undefined>;
486
417
  /** User vaults of one owner, ordered by `createdAt`, then id. */
487
418
  vaultsByOwner(ownerUserId: string): Promise<VaultRow[]>;
419
+ /** Installation vaults (any session may attach them), ordered by `createdAt`, then id. */
420
+ installationVaults(): Promise<VaultRow[]>;
488
421
  updateVaultMetadata(id: string, metadataJson: string | null): Promise<void>;
489
422
  /** Deletes the vault and its credentials. */
490
423
  deleteVault(id: string): Promise<void>;
@@ -510,6 +443,12 @@ export interface Tx {
510
443
  getVaultIdempotency(id: string): Promise<VaultIdempotencyRow | undefined>;
511
444
  /** Rejects when the id exists. */
512
445
  insertVaultIdempotency(row: VaultIdempotencyRow): Promise<void>;
446
+ /** An MCP OAuth connect's start (F9 C2). Rejects on a duplicate state or an unknown vault. */
447
+ insertOAuthPending(row: OAuthPendingRow): Promise<void>;
448
+ /** Deletes and returns the pending connect of `stateHash`, expired or not: each is used once. */
449
+ takeOAuthPending(stateHash: string): Promise<OAuthPendingRow | undefined>;
450
+ /** Deletes the pending connects that expired before `now` (ISO); returns how many. */
451
+ deleteExpiredOAuthPending(now: string): Promise<number>;
513
452
  /**
514
453
  * Serializes signing key changes: held until the transaction ends. Take it before reading
515
454
  * the keys a change depends on, so concurrent first uses or rotations do not collide.
@@ -527,30 +466,8 @@ export interface Tx {
527
466
  */
528
467
  setSigningKeyState(id: string, from: SigningKeyRow["state"], to: SigningKeyRow["state"], at: string): Promise<boolean>;
529
468
  countSigningKeys(): Promise<number>;
530
- /** The subject's revocation epoch; 0 when it was never revoked. */
531
- subjectEpoch(subject: string): Promise<number>;
532
- /** The epochs of several subjects; subjects never revoked are absent. */
533
- subjectEpochs(subjects: readonly string[]): Promise<Map<string, number>>;
534
- /** Adds one to the subject's epoch and returns the new value. */
535
- bumpSubjectEpoch(subject: string, at: string): Promise<number>;
536
- /**
537
- * The subject's turn bucket, created from `initial` when missing, locked until the
538
- * transaction ends so concurrent commands of one subject serialize.
539
- */
540
- lockSubjectUsage(initial: SubjectUsageRow): Promise<SubjectUsageRow>;
541
- putSubjectUsage(row: SubjectUsageRow): Promise<void>;
542
- /** How many sessions of `ownerUserId` are in one of `statuses`. */
543
- countOwnerSessions(ownerUserId: string, statuses: readonly string[]): Promise<number>;
544
- /** Rejects on a duplicate id, key or name. */
545
- insertPublishableKey(row: PublishableKeyRow): Promise<void>;
546
- publishableKeyByKey(key: string): Promise<PublishableKeyRow | undefined>;
547
- publishableKey(id: string): Promise<PublishableKeyRow | undefined>;
548
- /** All keys, revoked ones included, ordered by `createdAt`, then id. */
549
- publishableKeys(): Promise<PublishableKeyRow[]>;
550
- /** Returns false when the key does not exist. */
551
- updatePublishableKey(id: string, patch: Partial<Pick<PublishableKeyRow, "originsJson" | "revokedAt">>): Promise<boolean>;
552
469
  /** Appends a row, setting `duplicate` when one with the same `effectKey` exists; returns it. */
553
- recordModelUsage(row: Omit<ModelUsageRow, "duplicate">): Promise<ModelUsageRow>;
470
+ recordModelUsage(row: ModelUsageWrite): Promise<ModelUsageRow>;
554
471
  modelUsageTotals(query: ModelUsageQuery): Promise<ModelUsageTotals>;
555
472
  /** Every budget, ordered by scope, then scope id. */
556
473
  listModelBudgets(): Promise<ModelBudgetRow[]>;
@@ -612,19 +529,27 @@ export interface Tx {
612
529
  artifactContentShas(scope: "sessions" | "all" | {
613
530
  artifactId: string;
614
531
  }): Promise<string[]>;
532
+ /** The definition file `sha256` (`sha256:<hex>`) names, once its bytes are stored. */
533
+ definitionFile(sha256: string): Promise<DefinitionFileRow | undefined>;
534
+ /** Records a stored definition file; false when the Tenant held it already. */
535
+ insertDefinitionFile(row: DefinitionFileRow): Promise<boolean>;
536
+ /** Those of `shas` the Tenant holds. */
537
+ heldDefinitionFiles(shas: readonly string[]): Promise<Set<string>>;
538
+ /** Records that version `manifestHash` of definition `agentId` names each of `shas`. */
539
+ insertDefinitionFileUses(agentId: string, manifestHash: string, shas: readonly string[]): Promise<void>;
615
540
  getSetting(key: string): Promise<string | undefined>;
616
541
  putSetting(key: string, value: string): Promise<void>;
617
542
  /**
618
543
  * Deletes Tenant state by scope, in this transaction:
619
- * - `sessions`: sessions, commands, effects, actions, links, subject turn
620
- * buckets, the artifacts of sessions (their blobs are the caller's to delete) and the
544
+ * - `sessions`: sessions, commands, effects, links, the artifacts of sessions (their blobs are the caller's to delete) and the
621
545
  * Tenant's record rows and log heads. The Tenant moves to the next basin
622
546
  * generation and the current one is retired, so session ids it frees start again in an
623
547
  * empty basin;
624
548
  * - `sandboxes`: sandbox records, sandbox resources and their lifecycle streams;
625
- * - `all`: both, plus definitions, Action endpoints, user vaults with their credentials,
626
- * the model usage ledger, the model budgets and Tenant-wide artifacts. The host vault, principals, signing keys, subject epochs,
627
- * publishable keys, settings, audit and vault idempotency rows stay.
549
+ * - `all`: both, plus definitions (and which definition files they use),
550
+ * user vaults with their credentials,
551
+ * the model usage ledger, the model budgets and Tenant-wide artifacts. The host vault, principals, signing keys,
552
+ * settings, audit and vault idempotency rows stay.
628
553
  */
629
554
  reset(scope: ResetScope): Promise<void>;
630
555
  }
@@ -3,7 +3,6 @@ export const DOC_TABLES = [
3
3
  "sessions",
4
4
  "commands",
5
5
  "effects",
6
- "actions",
7
6
  "sandboxes",
8
7
  "links",
9
8
  ];
@@ -6,15 +6,8 @@
6
6
  import { type DurableStreams } from "./types.js";
7
7
  /** Appends a `session.cancel` signal: the process running the session's advance aborts it. */
8
8
  export declare function signalCancel(streams: DurableStreams, basin: string, sessionId: string, turnId?: string): Promise<void>;
9
- /** Appends an `action.resolved` signal: a run held for the Action goes on with its outcome. */
10
- export declare function signalActionResolved(streams: DurableStreams, basin: string, sessionId: string, actionId: string): Promise<void>;
11
9
  /**
12
10
  * Appends a `sessions.reset` signal to the old generation's basin: every process with the
13
11
  * Tenant open moves its readers to `generation` and ends the streams of deleted sessions.
14
12
  */
15
13
  export declare function signalSessionsReset(streams: DurableStreams, basin: string, generation: number): Promise<void>;
16
- /**
17
- * Appends a `subject.revoked` signal: every process with the Tenant open ends the subject's
18
- * streams opened with a token older than `epoch`.
19
- */
20
- export declare function signalSubjectRevoked(streams: DurableStreams, basin: string, subject: string, epoch: number): Promise<void>;
@@ -15,11 +15,6 @@ export async function signalCancel(streams, basin, sessionId, turnId) {
15
15
  };
16
16
  await streams.append(basin, CONTROL_STREAM, [signal]);
17
17
  }
18
- /** Appends an `action.resolved` signal: a run held for the Action goes on with its outcome. */
19
- export async function signalActionResolved(streams, basin, sessionId, actionId) {
20
- const signal = { type: "action.resolved", sessionId, actionId };
21
- await streams.append(basin, CONTROL_STREAM, [signal]);
22
- }
23
18
  /**
24
19
  * Appends a `sessions.reset` signal to the old generation's basin: every process with the
25
20
  * Tenant open moves its readers to `generation` and ends the streams of deleted sessions.
@@ -28,11 +23,3 @@ export async function signalSessionsReset(streams, basin, generation) {
28
23
  const signal = { type: "sessions.reset", generation };
29
24
  await streams.append(basin, CONTROL_STREAM, [signal]);
30
25
  }
31
- /**
32
- * Appends a `subject.revoked` signal: every process with the Tenant open ends the subject's
33
- * streams opened with a token older than `epoch`.
34
- */
35
- export async function signalSubjectRevoked(streams, basin, subject, epoch) {
36
- const signal = { type: "subject.revoked", subject, epoch };
37
- await streams.append(basin, CONTROL_STREAM, [signal]);
38
- }
@@ -7,7 +7,7 @@
7
7
  * | Stream | Contents | Written by | Read by |
8
8
  * | --- | --- | --- | --- |
9
9
  * | `sessions/<sessionId>` | every event of the session, in sequence | the stream relay, from the record | history and session SSE |
10
- * | `tenant/control` | `session.cancel`, `sessions.reset` and `subject.revoked` signals | API nodes | every process with the Tenant open |
10
+ * | `tenant/control` | `session.cancel`, `sessions.reset` and `action.resolved` signals | API nodes | every process with the Tenant open |
11
11
  *
12
12
  * **Basin generations.** A session id is unique within its Tenant's basin generation. A
13
13
  * Tenant reset, the only path that frees ids, moves the Tenant to the next generation, so
@@ -138,22 +138,4 @@ export interface SessionsResetSignal {
138
138
  type: "sessions.reset";
139
139
  generation?: number;
140
140
  }
141
- /**
142
- * A subject's tokens older than `epoch` were revoked: each process ends that subject's
143
- * streams opened with them.
144
- */
145
- export interface SubjectRevokedSignal {
146
- type: "subject.revoked";
147
- subject: string;
148
- epoch: number;
149
- }
150
- /**
151
- * An Action of `sessionId` has its outcome (F6.2): the process whose harness holds the
152
- * session's run while the Action is pending passes it on (`effect.resolved`).
153
- */
154
- export interface ActionResolvedSignal {
155
- type: "action.resolved";
156
- sessionId: string;
157
- actionId: string;
158
- }
159
- export type ControlSignal = SessionCancelSignal | SessionsResetSignal | SubjectRevokedSignal | ActionResolvedSignal;
141
+ export type ControlSignal = SessionCancelSignal | SessionsResetSignal;
@@ -7,7 +7,7 @@
7
7
  * | Stream | Contents | Written by | Read by |
8
8
  * | --- | --- | --- | --- |
9
9
  * | `sessions/<sessionId>` | every event of the session, in sequence | the stream relay, from the record | history and session SSE |
10
- * | `tenant/control` | `session.cancel`, `sessions.reset` and `subject.revoked` signals | API nodes | every process with the Tenant open |
10
+ * | `tenant/control` | `session.cancel`, `sessions.reset` and `action.resolved` signals | API nodes | every process with the Tenant open |
11
11
  *
12
12
  * **Basin generations.** A session id is unique within its Tenant's basin generation. A
13
13
  * Tenant reset, the only path that frees ids, moves the Tenant to the next generation, so
@@ -9,12 +9,12 @@ export declare function advance(ctx: TenantContext, id: string, signal: AbortSig
9
9
  /**
10
10
  * Takeover (§10.5 step 2, §11.4), inside the transaction that took ownership: the dead
11
11
  * owner's `invoking` effects become `uncertain` and are never invoked again, except model
12
- * calls when the gate recovers them (P1.2) and remote MCP calls when the Tool Gate does (F4.1
13
- * G3): those stay `invoking`, and the replay re-sends them. When one belongs
12
+ * calls when the gate recovers them (P1.2) and remote MCP and HTTP tool calls when the Tool
13
+ * Gate does (F4.1 G3): those stay `invoking`, and the replay re-sends them. When one belongs
14
14
  * to the active turn, the session becomes `uncertain` too, with an `effect.uncertain` event.
15
15
  * Mutates and writes `s`. Returns the effect ids it marked.
16
16
  */
17
17
  export declare function takeOver(t: Tx, s: Session, options?: {
18
18
  recoversModelCalls?: boolean;
19
- recoversMcpCalls?: boolean;
19
+ recoversToolCalls?: boolean;
20
20
  }): Promise<string[]>;
@@ -42,8 +42,7 @@
42
42
  import { runDurable, runFlowDurable, } from "@nylorun/harness/run";
43
43
  import { aggregateWaits, cancelSiblingWork, isWorkflowManifest, wakeLinkedWorkflow, } from "../core/flow-host.js";
44
44
  import { isOwnershipLost, ownedTx } from "../store/ownership.js";
45
- import { linkedAgentOutput } from "./session.js";
46
- import { isRemoteMcpEffect, recoversMcpCalls, recoversModelCalls } from "./effects.js";
45
+ import { isGateToolEffect, recoversModelCalls, recoversToolCalls } from "./effects.js";
47
46
  import { slimModelEffects } from "./slim.js";
48
47
  import { applyUpdates, leanState, transcriptShadow, withTranscript, } from "./history.js";
49
48
  import { command } from "./commands.js";
@@ -232,7 +231,7 @@ async function takeOwnership(ctx, id) {
232
231
  if (taken.takeover)
233
232
  await takeOver(t, s, {
234
233
  recoversModelCalls: recoversModelCalls(ctx),
235
- recoversMcpCalls: recoversMcpCalls(ctx),
234
+ recoversToolCalls: recoversToolCalls(ctx),
236
235
  });
237
236
  if (!s.checkpoint || !["running", "runnable"].includes(s.status)) {
238
237
  await t.releaseOwnership(id, lease.owner, lease.epoch);
@@ -246,8 +245,8 @@ async function takeOwnership(ctx, id) {
246
245
  /**
247
246
  * Takeover (§10.5 step 2, §11.4), inside the transaction that took ownership: the dead
248
247
  * owner's `invoking` effects become `uncertain` and are never invoked again, except model
249
- * calls when the gate recovers them (P1.2) and remote MCP calls when the Tool Gate does (F4.1
250
- * G3): those stay `invoking`, and the replay re-sends them. When one belongs
248
+ * calls when the gate recovers them (P1.2) and remote MCP and HTTP tool calls when the Tool
249
+ * Gate does (F4.1 G3): those stay `invoking`, and the replay re-sends them. When one belongs
251
250
  * to the active turn, the session becomes `uncertain` too, with an `effect.uncertain` event.
252
251
  * Mutates and writes `s`. Returns the effect ids it marked.
253
252
  */
@@ -257,7 +256,7 @@ export async function takeOver(t, s, options = {}) {
257
256
  // Still running at the gate, or finished there: the replay re-sends it (P1.2).
258
257
  if (options.recoversModelCalls && effect.request.kind === "model")
259
258
  continue;
260
- if (options.recoversMcpCalls && isRemoteMcpEffect(s, effect.request))
259
+ if (options.recoversToolCalls && isGateToolEffect(s, effect.request))
261
260
  continue;
262
261
  effect.status = "uncertain";
263
262
  effect.error ??= "The Worker running this effect stopped before its outcome was recorded";
@@ -390,7 +389,7 @@ async function wakeWorkflowOf(ctx, t, agent, turnId, type, payload) {
390
389
  agentSessionId: agent.id,
391
390
  turnId,
392
391
  output: type === "turn.completed"
393
- ? linkedAgentOutput(agent, payload.output)
392
+ ? payload.output ?? null
394
393
  : undefined,
395
394
  failed: type === "turn.failed",
396
395
  error: type === "turn.failed"
@@ -526,9 +525,13 @@ async function settle(ctx, lease, s, result, updates = [], cursor) {
526
525
  ? {
527
526
  interactions: (result.result.pending ?? []).map((call) => ({
528
527
  invocationId: call.invocationId,
528
+ ...(typeof call.callId === "string" ? { callId: call.callId } : {}),
529
529
  interaction: call.interaction,
530
530
  wait: call.wait,
531
531
  status: call.status,
532
+ // A flow's tool node that asked.
533
+ ...(typeof call.path === "string" ? { path: call.path } : {}),
534
+ ...(typeof call.toolName === "string" ? { toolName: call.toolName } : {}),
532
535
  })),
533
536
  }
534
537
  : result.status === "failed"
@@ -1,15 +1,27 @@
1
1
  /**
2
2
  * Tenant request authentication and authorization: a bearer token resolves to an application
3
- * principal, a subject token or a delivery token; anything else is the opaque 404 (D5).
4
- * An application principal may act for a subject (`Nylorun-Subject`, `Nylorun-Scopes`); a
5
- * subject token names its subject itself. `authorize` limits both to the routes their scopes
6
- * allow, decided from the route alone.
3
+ * principal or a trusted issuer's token; anything else is the opaque 404
4
+ * (D5). An application principal may act for a subject (`Nylorun-Subject`, `Nylorun-Scopes`);
5
+ * an issuer token names its subject itself. `requireScopes` limits them to the routes their
6
+ * scopes allow, decided from the route alone.
7
+ *
8
+ * Browsers: a request with `Origin` may carry an issuer token (CORS is the operator's proxy's),
9
+ * never an application key, which is a server secret.
7
10
  */
8
11
  import type { IncomingMessage } from "node:http";
9
- import { type Action, type SubjectScope } from "@nylorun/core/contracts";
12
+ import { type SubjectScope } from "@nylorun/core/contracts";
10
13
  import type { AuthScope, SessionAccess, TenantContext } from "./context.js";
11
- import type { BrowserClient } from "./browser.js";
12
- export declare function authenticate(ctx: TenantContext, request: IncomingMessage, client?: BrowserClient): Promise<AuthScope>;
14
+ /**
15
+ * Which keys a route takes (protocol 8): an application key (alone or acting for a subject) on
16
+ * the Runtime API, a management key on the Management API. `/v1/me` takes both.
17
+ */
18
+ export interface KeyAccess {
19
+ readonly application: boolean;
20
+ readonly management: boolean;
21
+ }
22
+ /** Every route that does not say otherwise is a Runtime API route. */
23
+ export declare const RUNTIME_KEYS: KeyAccess;
24
+ export declare function authenticate(ctx: TenantContext, request: IncomingMessage, keys?: KeyAccess): Promise<AuthScope>;
13
25
  /**
14
26
  * What a subject needs for a route: any one of the scopes, nothing grants it (`never`), or
15
27
  * any caller may (`any`, public data such as the JWKS). Each route declares it
@@ -17,18 +29,15 @@ export declare function authenticate(ctx: TenantContext, request: IncomingMessag
17
29
  */
18
30
  export type SubjectAccess = readonly SubjectScope[] | "never" | "any";
19
31
  /**
20
- * A subject, subject token or publishable key reaches a route only with one of the scopes it
21
- * declares: `403 scope_required`, decided from the route alone before anything is read.
32
+ * A subject or a token caller reaches a route only with one of the scopes it declares:
33
+ * `403 scope_required`, decided from the route alone before anything is read.
22
34
  */
23
35
  export declare function requireScopes(scope: AuthScope, access: SubjectAccess): void;
24
36
  export declare function accessOf(scope: AuthScope): SessionAccess | undefined;
25
- /** The subject whose sessions and vaults the request is limited to, if it acts for one. */
37
+ /** The subject whose sessions the request is limited to, if it acts for one. */
26
38
  export declare function ownerOf(scope: AuthScope): string | undefined;
27
39
  /** The application principal behind the request, acting for a subject or not. */
28
40
  export declare function requirePrincipal(scope: AuthScope): string;
29
- /**
30
- * The caller may act on `action`: only the delivery token minted for it. Whether its generation
31
- * is still the Action's is checked by each callback.
32
- */
33
- export declare function scoped(scope: AuthScope, action: Action): void;
41
+ /** True when a token caller may reach `agentId` (its issuer's allowlist). Other callers always may. */
42
+ export declare function mayUseAgent(scope: AuthScope, agentId: string): boolean;
34
43
  export declare function requireApplication(scope: AuthScope): string;