@nylorun/runtime 0.24.0-beta → 0.26.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 (171) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/README.md +18 -4
  3. package/dist/api/a2a/card.d.ts +11 -1
  4. package/dist/api/a2a/card.js +26 -2
  5. package/dist/api/a2a/endpoint.js +4 -2
  6. package/dist/api/a2a/protocol.d.ts +25 -2
  7. package/dist/api/a2a/protocol.js +20 -3
  8. package/dist/api/a2a/routes.d.ts +4 -1
  9. package/dist/api/a2a/routes.js +65 -7
  10. package/dist/api/ag-ui/endpoint.js +5 -2
  11. package/dist/api/ag-ui/history.d.ts +6 -1
  12. package/dist/api/ag-ui/history.js +35 -2
  13. package/dist/api/ag-ui/routes.js +53 -11
  14. package/dist/api/components.d.ts +1165 -678
  15. package/dist/api/components.js +16 -1
  16. package/dist/api/gate/keys.d.ts +2 -1
  17. package/dist/api/gate/keys.js +7 -0
  18. package/dist/api/gate/routes.js +13 -0
  19. package/dist/api/http/app.d.ts +2 -2
  20. package/dist/api/http/app.js +15 -4
  21. package/dist/api/http/body.d.ts +3 -3
  22. package/dist/api/http/body.js +7 -7
  23. package/dist/api/http/define.d.ts +1 -1
  24. package/dist/api/http/respond.js +1 -1
  25. package/dist/api/http/routes/environment-manifests.d.ts +9 -0
  26. package/dist/api/http/routes/environment-manifests.js +118 -0
  27. package/dist/api/http/routes/environments.js +61 -12
  28. package/dist/api/http/routes/reads.d.ts +52 -3
  29. package/dist/api/http/routes/sessions.js +14 -4
  30. package/dist/api/http/routes/tenant.js +35 -7
  31. package/dist/api/inbound-files.d.ts +65 -0
  32. package/dist/api/inbound-files.js +115 -0
  33. package/dist/api/openapi.js +18 -3
  34. package/dist/artifacts/disk.js +20 -14
  35. package/dist/artifacts/media-types.d.ts +15 -0
  36. package/dist/artifacts/media-types.js +56 -4
  37. package/dist/artifacts/parts.d.ts +12 -3
  38. package/dist/artifacts/parts.js +15 -4
  39. package/dist/artifacts/workspace.d.ts +4 -4
  40. package/dist/artifacts/workspace.js +6 -18
  41. package/dist/core/flow-host.d.ts +1 -1
  42. package/dist/core/flow-host.js +2 -2
  43. package/dist/core/sandbox-routes.js +2 -2
  44. package/dist/core/turn-manifest.d.ts +3 -2
  45. package/dist/core/turn-manifest.js +29 -5
  46. package/dist/gates/egress-credentials.js +1 -1
  47. package/dist/gates/egress.d.ts +13 -19
  48. package/dist/gates/egress.js +32 -29
  49. package/dist/gates/http-tool.d.ts +3 -4
  50. package/dist/gates/http-tool.js +23 -19
  51. package/dist/gates/journal.js +0 -1
  52. package/dist/gates/mcp-handler.js +2 -3
  53. package/dist/gates/policy.js +1 -3
  54. package/dist/gates/tool-contract.d.ts +1 -1
  55. package/dist/harness/calls.d.ts +2 -2
  56. package/dist/harness/calls.js +9 -12
  57. package/dist/harness/main.js +7 -1
  58. package/dist/harness/pod.d.ts +6 -1
  59. package/dist/harness/pod.js +5 -0
  60. package/dist/harness/service.js +5 -5
  61. package/dist/harness/setup.d.ts +2 -0
  62. package/dist/harness/setup.js +25 -1
  63. package/dist/harness-api/record.d.ts +1 -1
  64. package/dist/harness-api/record.js +13 -13
  65. package/dist/harness-api/server.d.ts +27 -4
  66. package/dist/harness-api/server.js +41 -8
  67. package/dist/harness-api/tool-journal.d.ts +17 -8
  68. package/dist/harness-api/tool-journal.js +41 -11
  69. package/dist/harness-api/workspace.d.ts +7 -5
  70. package/dist/harness-api/workspace.js +25 -19
  71. package/dist/host/gates.js +2 -2
  72. package/dist/host/stack-config.js +1 -1
  73. package/dist/keys/contract.d.ts +1 -1
  74. package/dist/keys/contract.js +1 -1
  75. package/dist/keys/keys.d.ts +9 -2
  76. package/dist/keys/keys.js +4 -1
  77. package/dist/management-openapi.json +366 -61
  78. package/dist/mcp/connect.d.ts +1 -2
  79. package/dist/mcp/connect.js +1 -4
  80. package/dist/mcp/pool.d.ts +1 -4
  81. package/dist/mcp/pool.js +13 -27
  82. package/dist/mcp/preview.d.ts +1 -1
  83. package/dist/mcp/preview.js +1 -2
  84. package/dist/mcp/snapshot.d.ts +11 -13
  85. package/dist/mcp/snapshot.js +27 -38
  86. package/dist/model/capabilities.d.ts +26 -0
  87. package/dist/model/capabilities.js +44 -0
  88. package/dist/model/catalog.d.ts +34 -3
  89. package/dist/model/catalog.js +38 -2
  90. package/dist/model/models.d.ts +2 -0
  91. package/dist/model/models.js +1 -1
  92. package/dist/model/native-blocks.d.ts +35 -0
  93. package/dist/model/native-blocks.js +170 -0
  94. package/dist/model/pi-model.js +106 -94
  95. package/dist/openapi.json +9554 -5076
  96. package/dist/record/environment.js +1 -1
  97. package/dist/sandbox/join.js +4 -0
  98. package/dist/sandbox/manager.d.ts +32 -14
  99. package/dist/sandbox/manager.js +132 -93
  100. package/dist/sandbox/placement.d.ts +1 -1
  101. package/dist/sandbox/placement.js +2 -2
  102. package/dist/sandbox/pods/client.d.ts +3 -1
  103. package/dist/sandbox/pods/lifecycle.d.ts +8 -0
  104. package/dist/sandbox/pods/lifecycle.js +15 -0
  105. package/dist/sandbox/pods/spec.js +2 -1
  106. package/dist/sandbox/resolve.d.ts +5 -3
  107. package/dist/sandbox/resolve.js +9 -2
  108. package/dist/sandbox/runtime-tools.d.ts +9 -0
  109. package/dist/sandbox/runtime-tools.js +16 -0
  110. package/dist/sandbox/session-sandbox.d.ts +4 -6
  111. package/dist/sandbox/session-sandbox.js +47 -94
  112. package/dist/sandbox/setup.d.ts +4 -1
  113. package/dist/sandbox/setup.js +46 -9
  114. package/dist/sandbox/share.d.ts +12 -7
  115. package/dist/sandbox/share.js +27 -25
  116. package/dist/sandbox/skills.d.ts +8 -6
  117. package/dist/sandbox/skills.js +24 -23
  118. package/dist/store/postgres/drizzle/0024_flat_manifest.sql +7 -0
  119. package/dist/store/postgres/drizzle/0025_environment_manifests.sql +14 -0
  120. package/dist/store/postgres/drizzle/0026_environment_forks.sql +1 -0
  121. package/dist/store/postgres/drizzle/0027_environment_image_digest.sql +1 -0
  122. package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
  123. package/dist/store/postgres/migrate.js +1 -1
  124. package/dist/store/postgres/reads.js +8 -2
  125. package/dist/store/postgres/schema.d.ts +217 -0
  126. package/dist/store/postgres/schema.js +36 -2
  127. package/dist/store/postgres/store.js +79 -4
  128. package/dist/store/types.d.ts +68 -14
  129. package/dist/tenant/advance.js +3 -0
  130. package/dist/tenant/artifact-tool.d.ts +1 -1
  131. package/dist/tenant/artifact-tool.js +43 -22
  132. package/dist/tenant/commands.js +24 -4
  133. package/dist/tenant/context.d.ts +10 -4
  134. package/dist/tenant/effects.js +7 -9
  135. package/dist/tenant/environment-manifests.d.ts +57 -0
  136. package/dist/tenant/environment-manifests.js +200 -0
  137. package/dist/tenant/environments.d.ts +54 -47
  138. package/dist/tenant/environments.js +309 -85
  139. package/dist/tenant/ephemeral.d.ts +1 -1
  140. package/dist/tenant/host-token.js +1 -1
  141. package/dist/tenant/identity-file.d.ts +1 -1
  142. package/dist/tenant/identity-file.js +1 -1
  143. package/dist/tenant/model-setting.d.ts +14 -0
  144. package/dist/tenant/model-setting.js +51 -0
  145. package/dist/tenant/outbound.d.ts +6 -5
  146. package/dist/tenant/outbound.js +8 -6
  147. package/dist/tenant/sessions.d.ts +5 -1
  148. package/dist/tenant/sessions.js +45 -12
  149. package/dist/tenant/skill-tool.d.ts +3 -3
  150. package/dist/tenant/skill-tool.js +6 -11
  151. package/dist/tenant/sweep.js +1 -1
  152. package/dist/tenant/tool-results.js +1 -1
  153. package/dist/tenant/tool-search.d.ts +7 -11
  154. package/dist/tenant/tool-search.js +8 -5
  155. package/dist/tenant/transcript.d.ts +51 -32
  156. package/dist/tenant/transcript.js +2 -1
  157. package/dist/tenant/types.d.ts +2 -2
  158. package/dist/traces/ids.d.ts +0 -1
  159. package/dist/traces/ids.js +0 -4
  160. package/dist/traces/map.d.ts +2 -2
  161. package/dist/traces/map.js +1 -29
  162. package/dist/vault/coverage.js +11 -13
  163. package/dist/vault/host-model.d.ts +4 -1
  164. package/dist/vault/host-model.js +10 -2
  165. package/dist/vault/service.d.ts +49 -4
  166. package/dist/vault/service.js +153 -6
  167. package/dist/version.d.ts +1 -1
  168. package/dist/version.js +1 -1
  169. package/package.json +3 -3
  170. package/dist/sandbox/capability.d.ts +0 -3
  171. package/dist/sandbox/capability.js +0 -10
@@ -9,9 +9,15 @@
9
9
  * new VaultService({ store: SessionStore, kek: () => Buffer })
10
10
  *
11
11
  * // An Environment's vault, in the caller's transaction (`tenant/environments.ts`).
12
- * createEnvironmentVault(t: Tx, environmentId: string, actor: string): Promise<void>
12
+ * createEnvironmentVault(t: Tx, environmentId: string, actor: string, id?: string): Promise<string>
13
13
  * deleteEnvironmentVault(t: Tx, environmentId: string, actor: string): Promise<void>
14
14
  *
15
+ * // A fork's secrets (Q15): `Keys` seals the copies with the vault key in its own transaction,
16
+ * // before the fork's; the fork's transaction inserts them, so the process that forks never
17
+ * // holds the key.
18
+ * sealEnvironmentSecretCopies(from, vaultId, slots | null): Promise<SealedSecretCopies>
19
+ * insertEnvironmentSecretCopies(t: Tx, vaultId, from, actor, sealed): Promise<{ copied; dropped }>
20
+ *
15
21
  * // Its secrets (`/v1/environments/{id}/secrets`): each opens its own transaction and writes its
16
22
  * // audit rows in it. A put needs the vault key, so callers reach it through `Keys`.
17
23
  * putEnvironmentSecret(environmentId, name, body: PutEnvironmentSecretRequest, actor): Promise<EnvironmentSecretView>
@@ -78,7 +84,9 @@ import { decryptSecret, encryptSecret, VaultCryptoError } from "./crypto.js";
78
84
  import { VaultError } from "./error.js";
79
85
  import { credentialNeeds } from "./coverage.js";
80
86
  import { checkCredentialHeaders } from "./headers.js";
81
- import { hostModelCatalog } from "../model/catalog.js";
87
+ import { hostModelCatalog, inputsOfHostModel } from "../model/catalog.js";
88
+ import { inputsError } from "../model/capabilities.js";
89
+ import { readAddedInputs } from "../tenant/model-setting.js";
82
90
  import { normalizeVaultUrl } from "./url.js";
83
91
  export const HOST_VAULT_ID = "host";
84
92
  const HOST_MODEL_ID = "host-model";
@@ -90,10 +98,13 @@ export class VaultService {
90
98
  this.kek = options.kek;
91
99
  }
92
100
  // --- an Environment's vault (caller's transaction) ------------------------------
93
- /** Creates Environment `environmentId`'s vault (D56), in the transaction that creates it. */
94
- async createEnvironmentVault(t, environmentId, actor) {
101
+ /**
102
+ * Creates Environment `environmentId`'s vault (D56), in the transaction that creates it; answers
103
+ * its id, `id` when given (a fork's, whose secrets were sealed for it first).
104
+ */
105
+ async createEnvironmentVault(t, environmentId, actor, id = randomUUID()) {
95
106
  const row = {
96
- id: randomUUID(),
107
+ id,
97
108
  name: environmentId,
98
109
  metadataJson: null,
99
110
  createdAt: new Date().toISOString(),
@@ -101,6 +112,7 @@ export class VaultService {
101
112
  };
102
113
  await t.insertVault(row);
103
114
  await this.audit(t, { actor, action: "create", vaultId: row.id, target: environmentId, outcome: "created" });
115
+ return row.id;
104
116
  }
105
117
  /**
106
118
  * Deletes Environment `environmentId`'s vault and its credentials, with their audit rows, in
@@ -123,6 +135,100 @@ export class VaultService {
123
135
  await t.deleteVault(vault.id);
124
136
  await this.audit(t, { actor, action: "delete", vaultId: vault.id, target: environmentId, outcome: "deleted" });
125
137
  }
138
+ /**
139
+ * Seals Environment `from`'s secrets again for vault `vaultId`, a fork's new vault (Q15): each
140
+ * value is unsealed and sealed under the new vault's and credential's ids, which its AAD binds.
141
+ * Needs the vault key, so callers reach it through `Keys`; it reads `from` in its own
142
+ * transaction and writes nothing. With `slots` (what the fork runs declares secret slots, D64),
143
+ * only the names it declares are sealed, each with its slot's binding; a value the slot's type
144
+ * cannot take is left behind. The fork's transaction inserts the copies
145
+ * (`insertEnvironmentSecretCopies`).
146
+ */
147
+ async sealEnvironmentSecretCopies(from, vaultId, slots) {
148
+ const kek = this.kek();
149
+ const rows = await this.store.tx(async (t) => {
150
+ const source = await t.vaultOfEnvironment(from);
151
+ return source ? (await t.credentialsForVault(source.id)).filter(isUserCredential) : [];
152
+ });
153
+ const sealed = [];
154
+ const dropped = [];
155
+ const now = new Date().toISOString();
156
+ for (const row of rows) {
157
+ const payload = readPayload(kek, row);
158
+ let type = row.type;
159
+ let binding = credentialBinding(row);
160
+ let value = payload;
161
+ if (slots) {
162
+ const slot = slots[row.name];
163
+ const rebound = slot === undefined ? undefined : rebind(row.name, slot, row, payload, binding);
164
+ if (rebound === undefined) {
165
+ dropped.push(row.name);
166
+ continue;
167
+ }
168
+ ({ type, binding, payload: value } = rebound);
169
+ try {
170
+ conflictOf(type, binding, sealed);
171
+ }
172
+ catch (error) {
173
+ if (!(error instanceof VaultError))
174
+ throw error;
175
+ dropped.push(row.name);
176
+ continue;
177
+ }
178
+ }
179
+ const id = randomUUID();
180
+ sealed.push({
181
+ id,
182
+ vaultId,
183
+ name: row.name,
184
+ type,
185
+ bindingJson: JSON.stringify(binding),
186
+ expiresAt: row.expiresAt,
187
+ createdAt: now,
188
+ rotatedAt: null,
189
+ ...encryptSecret(kek, credentialAad(vaultId, id, type, binding), Buffer.from(JSON.stringify(value), "utf8")),
190
+ });
191
+ }
192
+ return {
193
+ copies: sealed.map((row) => ({
194
+ id: row.id,
195
+ name: row.name,
196
+ type: row.type,
197
+ bindingJson: row.bindingJson,
198
+ expiresAt: row.expiresAt,
199
+ kekId: row.kekId,
200
+ nonce: Buffer.from(row.nonce).toString("base64"),
201
+ ciphertext: Buffer.from(row.ciphertext).toString("base64"),
202
+ wrappedDek: Buffer.from(row.wrappedDek).toString("base64"),
203
+ })),
204
+ dropped: dropped.sort(),
205
+ };
206
+ }
207
+ /**
208
+ * Inserts a fork's sealed copies (`sealEnvironmentSecretCopies`) into vault `vaultId`, in the
209
+ * transaction that creates the fork, with an audit row each naming `from`. Reads no secret.
210
+ */
211
+ async insertEnvironmentSecretCopies(t, vaultId, from, actor, sealed) {
212
+ const now = new Date().toISOString();
213
+ for (const copy of sealed.copies) {
214
+ await t.insertCredential({
215
+ id: copy.id,
216
+ vaultId,
217
+ name: copy.name,
218
+ type: copy.type,
219
+ bindingJson: copy.bindingJson,
220
+ expiresAt: copy.expiresAt,
221
+ createdAt: now,
222
+ rotatedAt: null,
223
+ kekId: copy.kekId,
224
+ nonce: Buffer.from(copy.nonce, "base64"),
225
+ ciphertext: Buffer.from(copy.ciphertext, "base64"),
226
+ wrappedDek: Buffer.from(copy.wrappedDek, "base64"),
227
+ });
228
+ await this.audit(t, { actor, action: "create", vaultId, credentialId: copy.id, target: from, outcome: "copied" });
229
+ }
230
+ return { copied: sealed.copies.map((copy) => copy.name).sort(), dropped: [...sealed.dropped] };
231
+ }
126
232
  // --- an Environment's secrets ----------------------------------------------------
127
233
  /**
128
234
  * `PUT /v1/environments/{id}/secrets/{name}`: creates or replaces one credential. The same
@@ -402,9 +508,11 @@ export class VaultService {
402
508
  async listHostProviders() {
403
509
  return this.store.tx(async (t) => {
404
510
  const active = await activeProviderId(t);
511
+ const added = await readAddedInputs(t);
405
512
  const catalog = new Map(hostModelCatalog().providers.map((provider) => [provider.id, provider.name]));
406
513
  const providers = (await hostModelRows(t)).map((row) => {
407
514
  const binding = modelBinding(row);
515
+ const inputs = inputsOfHostModel({ configured: true, ...binding }, added);
408
516
  return {
409
517
  id: binding.provider,
410
518
  name: catalog.get(binding.provider) ??
@@ -415,6 +523,7 @@ export class VaultService {
415
523
  authType: binding.authType,
416
524
  ...(binding.baseUrl ? { baseUrl: binding.baseUrl } : {}),
417
525
  ...(binding.settings ? { settings: binding.settings } : {}),
526
+ ...(inputs ? { inputs } : {}),
418
527
  lastUpdated: row.rotatedAt ?? row.createdAt,
419
528
  active: binding.provider === active,
420
529
  };
@@ -541,8 +650,13 @@ export class VaultService {
541
650
  }
542
651
  validateHostModel(body) {
543
652
  if (body.settings && body.provider !== "custom")
544
- throw new VaultError(400, "Model settings (context window, output limit, reasoning, compat) apply only to a custom provider.");
653
+ throw new VaultError(400, "Model settings (context window, output limit, reasoning, inputs, compat) apply only to a custom provider.");
545
654
  if (body.provider === "custom") {
655
+ // A custom endpoint is OpenAI-compatible: it reads only what that API carries (protocol 12).
656
+ const inputsRefused = body.settings?.inputs &&
657
+ inputsError({ api: "openai-completions", input: ["text", "image"] }, body.settings.inputs);
658
+ if (inputsRefused)
659
+ throw new VaultError(400, inputsRefused);
546
660
  if (!body.baseUrl)
547
661
  throw new VaultError(400, "A base URL is required for a custom provider.");
548
662
  let url;
@@ -855,6 +969,39 @@ function credentialAad(vaultId, credentialId, type, binding) {
855
969
  }
856
970
  : { vaultId, credentialId, type, url: binding.url }), "utf8");
857
971
  }
972
+ /**
973
+ * A copied credential's type, binding and payload under a slot of the fork (D64): its value with
974
+ * the slot's binding, or undefined when the slot's type cannot take it.
975
+ */
976
+ function rebind(name, slot, row, payload, binding) {
977
+ const type = slot.type;
978
+ const value = row.type === "environment_variable" ? binding.variableValue : row.type === "bearer" ? payload.token : payload.value;
979
+ try {
980
+ if (type === "environment_secret" || type === "environment_variable") {
981
+ if (value === undefined)
982
+ return undefined;
983
+ const made = environmentCredential(name, { ...slot, type, value });
984
+ return { type, ...made };
985
+ }
986
+ const auth = type === "headers"
987
+ ? payload.headers === undefined
988
+ ? undefined
989
+ : { type, headers: payload.headers }
990
+ : value === undefined
991
+ ? undefined
992
+ : { type: "bearer", value };
993
+ if (auth === undefined)
994
+ return undefined;
995
+ const sealed = payloadOf(auth);
996
+ const routing = slot;
997
+ return { type, payload: sealed, binding: bindingOf(normalizeVaultUrl(routing.url), sealed, routing) };
998
+ }
999
+ catch (error) {
1000
+ if (error instanceof VaultError)
1001
+ return undefined;
1002
+ throw error;
1003
+ }
1004
+ }
858
1005
  /** The sealed payload and unsealed binding of a shell credential named `name` (R2c). */
859
1006
  function environmentCredential(name, body) {
860
1007
  if (body.type === "environment_variable")
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const RUNTIME_VERSION = "0.24.0-beta";
1
+ export declare const RUNTIME_VERSION = "0.26.0-beta";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Kept in step with package.json by runtime/server/scripts/check-package.mjs, which runs in npm run check.
2
2
  // release:prepare also rewrites this when it bumps @nylorun/runtime.
3
- export const RUNTIME_VERSION = "0.24.0-beta";
3
+ export const RUNTIME_VERSION = "0.26.0-beta";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nylorun/runtime",
3
- "version": "0.24.0-beta",
3
+ "version": "0.26.0-beta",
4
4
  "description": "Nylorun Runtime: the agent execution Host on Postgres, Restate and S2, and model providers.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -65,8 +65,8 @@
65
65
  "@hono/node-server": "^2.1.3",
66
66
  "@hono/zod-openapi": "^1.6.3",
67
67
  "@modelcontextprotocol/sdk": "^1.32.1",
68
- "@nylorun/core": "0.20.0-beta",
69
- "@nylorun/harness": "0.26.0-beta",
68
+ "@nylorun/core": "0.22.0-beta",
69
+ "@nylorun/harness": "0.27.1-beta",
70
70
  "@restatedev/restate-sdk": "1.17.2",
71
71
  "@restatedev/restate-sdk-clients": "1.17.2",
72
72
  "@s2-dev/streamstore": "0.28.0",
@@ -1,3 +0,0 @@
1
- import { type AgentManifest, type CapabilityManifest } from "@nylorun/core/define";
2
- /** The sandbox capability that owns this tool call, when the call is a built-in sandbox tool. */
3
- export declare function sandboxCapabilityOf(manifest: AgentManifest | undefined, capabilityId: string | undefined, toolName: string | undefined): CapabilityManifest | undefined;
@@ -1,10 +0,0 @@
1
- import { isSandboxToolName, } from "@nylorun/core/define";
2
- /** The sandbox capability that owns this tool call, when the call is a built-in sandbox tool. */
3
- export function sandboxCapabilityOf(manifest, capabilityId, toolName) {
4
- if (!manifest || !capabilityId || !toolName || !isSandboxToolName(toolName))
5
- return undefined;
6
- const capability = manifest.capabilities.find((item) => item.id === capabilityId);
7
- return capability?.sandbox && capability.tools?.some((tool) => tool.name === toolName)
8
- ? capability
9
- : undefined;
10
- }