@nylorun/runtime 0.24.0-beta → 0.25.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +10 -2
  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.js +13 -2
  20. package/dist/api/http/body.d.ts +3 -3
  21. package/dist/api/http/body.js +7 -7
  22. package/dist/api/http/routes/environment-manifests.d.ts +9 -0
  23. package/dist/api/http/routes/environment-manifests.js +118 -0
  24. package/dist/api/http/routes/environments.js +61 -12
  25. package/dist/api/http/routes/reads.d.ts +52 -3
  26. package/dist/api/http/routes/sessions.js +13 -3
  27. package/dist/api/http/routes/tenant.js +35 -7
  28. package/dist/api/inbound-files.d.ts +65 -0
  29. package/dist/api/inbound-files.js +115 -0
  30. package/dist/api/openapi.js +18 -3
  31. package/dist/artifacts/disk.js +20 -14
  32. package/dist/artifacts/media-types.d.ts +15 -0
  33. package/dist/artifacts/media-types.js +56 -4
  34. package/dist/artifacts/parts.d.ts +12 -3
  35. package/dist/artifacts/parts.js +15 -4
  36. package/dist/artifacts/workspace.d.ts +4 -4
  37. package/dist/artifacts/workspace.js +6 -18
  38. package/dist/core/flow-host.d.ts +1 -1
  39. package/dist/core/flow-host.js +2 -2
  40. package/dist/core/sandbox-routes.js +2 -2
  41. package/dist/core/turn-manifest.d.ts +3 -2
  42. package/dist/core/turn-manifest.js +29 -5
  43. package/dist/gates/egress-credentials.js +1 -1
  44. package/dist/gates/egress.d.ts +13 -19
  45. package/dist/gates/egress.js +30 -29
  46. package/dist/gates/http-tool.d.ts +3 -4
  47. package/dist/gates/http-tool.js +8 -12
  48. package/dist/gates/journal.js +0 -1
  49. package/dist/gates/mcp-handler.js +2 -3
  50. package/dist/gates/policy.js +1 -3
  51. package/dist/gates/tool-contract.d.ts +1 -1
  52. package/dist/harness/calls.d.ts +2 -2
  53. package/dist/harness/calls.js +9 -12
  54. package/dist/harness/main.js +7 -1
  55. package/dist/harness/pod.d.ts +6 -1
  56. package/dist/harness/pod.js +5 -0
  57. package/dist/harness/service.js +5 -5
  58. package/dist/harness/setup.d.ts +2 -0
  59. package/dist/harness/setup.js +25 -1
  60. package/dist/harness-api/record.d.ts +1 -1
  61. package/dist/harness-api/record.js +13 -13
  62. package/dist/harness-api/server.d.ts +27 -4
  63. package/dist/harness-api/server.js +41 -8
  64. package/dist/harness-api/tool-journal.d.ts +17 -8
  65. package/dist/harness-api/tool-journal.js +41 -11
  66. package/dist/harness-api/workspace.d.ts +7 -5
  67. package/dist/harness-api/workspace.js +25 -19
  68. package/dist/host/gates.js +2 -2
  69. package/dist/host/stack-config.js +1 -1
  70. package/dist/keys/keys.d.ts +9 -2
  71. package/dist/keys/keys.js +4 -1
  72. package/dist/management-openapi.json +366 -61
  73. package/dist/mcp/connect.d.ts +1 -2
  74. package/dist/mcp/connect.js +1 -4
  75. package/dist/mcp/pool.d.ts +1 -4
  76. package/dist/mcp/pool.js +13 -27
  77. package/dist/mcp/preview.js +0 -1
  78. package/dist/mcp/snapshot.d.ts +11 -13
  79. package/dist/mcp/snapshot.js +27 -38
  80. package/dist/model/capabilities.d.ts +26 -0
  81. package/dist/model/capabilities.js +44 -0
  82. package/dist/model/catalog.d.ts +34 -3
  83. package/dist/model/catalog.js +38 -2
  84. package/dist/model/models.d.ts +2 -0
  85. package/dist/model/models.js +1 -1
  86. package/dist/model/native-blocks.d.ts +35 -0
  87. package/dist/model/native-blocks.js +170 -0
  88. package/dist/model/pi-model.js +106 -94
  89. package/dist/openapi.json +9554 -5104
  90. package/dist/record/environment.js +1 -1
  91. package/dist/sandbox/join.js +4 -0
  92. package/dist/sandbox/manager.d.ts +32 -14
  93. package/dist/sandbox/manager.js +132 -93
  94. package/dist/sandbox/placement.d.ts +1 -1
  95. package/dist/sandbox/placement.js +2 -2
  96. package/dist/sandbox/pods/client.d.ts +3 -1
  97. package/dist/sandbox/pods/lifecycle.d.ts +8 -0
  98. package/dist/sandbox/pods/lifecycle.js +15 -0
  99. package/dist/sandbox/pods/spec.js +2 -1
  100. package/dist/sandbox/resolve.d.ts +5 -3
  101. package/dist/sandbox/resolve.js +9 -2
  102. package/dist/sandbox/runtime-tools.d.ts +9 -0
  103. package/dist/sandbox/runtime-tools.js +16 -0
  104. package/dist/sandbox/session-sandbox.d.ts +4 -6
  105. package/dist/sandbox/session-sandbox.js +47 -94
  106. package/dist/sandbox/setup.d.ts +4 -1
  107. package/dist/sandbox/setup.js +46 -9
  108. package/dist/sandbox/share.d.ts +12 -7
  109. package/dist/sandbox/share.js +27 -25
  110. package/dist/sandbox/skills.d.ts +8 -6
  111. package/dist/sandbox/skills.js +24 -23
  112. package/dist/store/postgres/drizzle/0024_flat_manifest.sql +7 -0
  113. package/dist/store/postgres/drizzle/0025_environment_manifests.sql +14 -0
  114. package/dist/store/postgres/drizzle/0026_environment_forks.sql +1 -0
  115. package/dist/store/postgres/drizzle/0027_environment_image_digest.sql +1 -0
  116. package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
  117. package/dist/store/postgres/reads.js +8 -2
  118. package/dist/store/postgres/schema.d.ts +217 -0
  119. package/dist/store/postgres/schema.js +36 -2
  120. package/dist/store/postgres/store.js +79 -4
  121. package/dist/store/types.d.ts +68 -14
  122. package/dist/tenant/advance.js +3 -0
  123. package/dist/tenant/artifact-tool.d.ts +1 -1
  124. package/dist/tenant/artifact-tool.js +43 -22
  125. package/dist/tenant/commands.js +24 -4
  126. package/dist/tenant/context.d.ts +10 -4
  127. package/dist/tenant/effects.js +7 -9
  128. package/dist/tenant/environment-manifests.d.ts +57 -0
  129. package/dist/tenant/environment-manifests.js +200 -0
  130. package/dist/tenant/environments.d.ts +54 -47
  131. package/dist/tenant/environments.js +304 -83
  132. package/dist/tenant/model-setting.d.ts +14 -0
  133. package/dist/tenant/model-setting.js +51 -0
  134. package/dist/tenant/sessions.d.ts +5 -1
  135. package/dist/tenant/sessions.js +45 -12
  136. package/dist/tenant/skill-tool.d.ts +3 -3
  137. package/dist/tenant/skill-tool.js +6 -11
  138. package/dist/tenant/sweep.js +1 -1
  139. package/dist/tenant/tool-results.js +1 -1
  140. package/dist/tenant/tool-search.d.ts +7 -11
  141. package/dist/tenant/tool-search.js +8 -5
  142. package/dist/tenant/transcript.d.ts +51 -32
  143. package/dist/tenant/transcript.js +2 -1
  144. package/dist/traces/ids.d.ts +0 -1
  145. package/dist/traces/ids.js +0 -4
  146. package/dist/traces/map.d.ts +2 -2
  147. package/dist/traces/map.js +1 -29
  148. package/dist/vault/coverage.js +11 -13
  149. package/dist/vault/host-model.d.ts +4 -1
  150. package/dist/vault/host-model.js +10 -2
  151. package/dist/vault/service.d.ts +49 -4
  152. package/dist/vault/service.js +153 -6
  153. package/dist/version.d.ts +1 -1
  154. package/dist/version.js +1 -1
  155. package/package.json +3 -3
  156. package/dist/sandbox/capability.d.ts +0 -3
  157. package/dist/sandbox/capability.js +0 -10
@@ -17,7 +17,10 @@ export declare class HostModelVault {
17
17
  private readonly store;
18
18
  private readonly kek;
19
19
  constructor(options: HostModelVaultOptions);
20
- /** Reads the active host model secret. Decrypts after the read commits. */
20
+ /**
21
+ * Reads the active host model secret, with the inputs the operator added to catalog models
22
+ * (protocol 12). Decrypts after the read commits.
23
+ */
21
24
  readHostModel(): Promise<HostModelSecret | undefined>;
22
25
  /** Replaces the active host model's secret, keeping its binding. */
23
26
  updateHostCredential(credential: {
@@ -1,3 +1,4 @@
1
+ import { readAddedInputs } from "../tenant/model-setting.js";
1
2
  import { encryptSecret } from "./crypto.js";
2
3
  import { VaultError } from "./error.js";
3
4
  import { activeHostCredentialRow, HOST_VAULT_ID, hostModelAad, modelBinding, readHostPayload, } from "./service.js";
@@ -8,9 +9,15 @@ export class HostModelVault {
8
9
  this.store = options.store;
9
10
  this.kek = options.kek;
10
11
  }
11
- /** Reads the active host model secret. Decrypts after the read commits. */
12
+ /**
13
+ * Reads the active host model secret, with the inputs the operator added to catalog models
14
+ * (protocol 12). Decrypts after the read commits.
15
+ */
12
16
  async readHostModel() {
13
- const row = await this.store.tx((t) => activeHostCredentialRow(t));
17
+ const { row, addedInputs } = await this.store.tx(async (t) => ({
18
+ row: await activeHostCredentialRow(t),
19
+ addedInputs: await readAddedInputs(t),
20
+ }));
14
21
  if (!row)
15
22
  return undefined;
16
23
  const binding = modelBinding(row);
@@ -27,6 +34,7 @@ export class HostModelVault {
27
34
  model: binding.model,
28
35
  ...(binding.baseUrl ? { baseUrl: binding.baseUrl } : {}),
29
36
  ...(binding.settings ? { settings: binding.settings } : {}),
37
+ addedInputs,
30
38
  authType: binding.authType,
31
39
  credential,
32
40
  };
@@ -1,4 +1,4 @@
1
- import type { CredentialCoverage, CredentialCoverageRequest, CredentialIdentity, EnvironmentSecretView, HostModelProviderInfo, HostModelView, PutEnvironmentSecretRequest, PutHostModelRequest, CustomModelSettings, SelectHostModelRequest } from "@nylorun/core/contracts";
1
+ import type { CredentialCoverage, CredentialCoverageRequest, CredentialIdentity, EnvironmentSecretView, HostModelProviderInfo, HostModelView, PutEnvironmentSecretRequest, PutHostModelRequest, CustomModelSettings, ModelInput, SelectHostModelRequest } from "@nylorun/core/contracts";
2
2
  import type { AgentManifest, WorkflowManifest } from "@nylorun/core/define";
3
3
  import type { SessionStore, Tx, VaultCredentialRow } from "../store/types.js";
4
4
  export declare const HOST_VAULT_ID = "host";
@@ -6,8 +6,10 @@ export type HostModelSecret = {
6
6
  provider: string;
7
7
  model: string;
8
8
  baseUrl?: string;
9
- /** A custom endpoint's window, output limit, reasoning and pi-ai compat (Model Calls §7). */
9
+ /** A custom endpoint's window, output limit, reasoning, inputs and pi-ai compat (Model Calls §7). */
10
10
  settings?: CustomModelSettings;
11
+ /** The inputs the operator added to catalog models, by `<provider>/<model>` (protocol 12). */
12
+ addedInputs?: Readonly<Record<string, readonly ModelInput[]>>;
11
13
  authType: "api_key" | "oauth";
12
14
  credential: {
13
15
  type: "api_key" | "oauth";
@@ -19,6 +21,28 @@ export type HostModelSecret = {
19
21
  [key: string]: unknown;
20
22
  };
21
23
  };
24
+ type UserCredentialRow = VaultCredentialRow & {
25
+ type: "bearer" | "headers" | "environment_secret" | "environment_variable";
26
+ };
27
+ /**
28
+ * A fork's secrets sealed for its new vault (`sealEnvironmentSecretCopies`): each copy's
29
+ * ciphertext, base64 so it crosses the keys service's JSON, and what about it is not secret.
30
+ */
31
+ export interface SealedSecretCopies {
32
+ readonly copies: readonly {
33
+ readonly id: string;
34
+ readonly name: string;
35
+ readonly type: UserCredentialRow["type"];
36
+ readonly bindingJson: string;
37
+ readonly expiresAt: string | null;
38
+ readonly kekId: string;
39
+ readonly nonce: string;
40
+ readonly ciphertext: string;
41
+ readonly wrappedDek: string;
42
+ }[];
43
+ /** Names left behind: no slot of the fork declares them, or their slot cannot take the value. */
44
+ readonly dropped: readonly string[];
45
+ }
22
46
  export type AuthorizeResult = {
23
47
  status: "unauthenticated";
24
48
  url: string;
@@ -47,14 +71,35 @@ export declare class VaultService {
47
71
  private readonly store;
48
72
  private readonly kek;
49
73
  constructor(options: VaultServiceOptions);
50
- /** Creates Environment `environmentId`'s vault (D56), in the transaction that creates it. */
51
- createEnvironmentVault(t: Tx, environmentId: string, actor: string): Promise<void>;
74
+ /**
75
+ * Creates Environment `environmentId`'s vault (D56), in the transaction that creates it; answers
76
+ * its id, `id` when given (a fork's, whose secrets were sealed for it first).
77
+ */
78
+ createEnvironmentVault(t: Tx, environmentId: string, actor: string, id?: string): Promise<string>;
52
79
  /**
53
80
  * Deletes Environment `environmentId`'s vault and its credentials, with their audit rows, in
54
81
  * the transaction that deletes the Environment: no release or tool call finds them after it
55
82
  * commits.
56
83
  */
57
84
  deleteEnvironmentVault(t: Tx, environmentId: string, actor: string): Promise<void>;
85
+ /**
86
+ * Seals Environment `from`'s secrets again for vault `vaultId`, a fork's new vault (Q15): each
87
+ * value is unsealed and sealed under the new vault's and credential's ids, which its AAD binds.
88
+ * Needs the vault key, so callers reach it through `Keys`; it reads `from` in its own
89
+ * transaction and writes nothing. With `slots` (what the fork runs declares secret slots, D64),
90
+ * only the names it declares are sealed, each with its slot's binding; a value the slot's type
91
+ * cannot take is left behind. The fork's transaction inserts the copies
92
+ * (`insertEnvironmentSecretCopies`).
93
+ */
94
+ sealEnvironmentSecretCopies(from: string, vaultId: string, slots?: Readonly<Record<string, Record<string, unknown>>> | null): Promise<SealedSecretCopies>;
95
+ /**
96
+ * Inserts a fork's sealed copies (`sealEnvironmentSecretCopies`) into vault `vaultId`, in the
97
+ * transaction that creates the fork, with an audit row each naming `from`. Reads no secret.
98
+ */
99
+ insertEnvironmentSecretCopies(t: Tx, vaultId: string, from: string, actor: string, sealed: SealedSecretCopies): Promise<{
100
+ copied: string[];
101
+ dropped: string[];
102
+ }>;
58
103
  /**
59
104
  * `PUT /v1/environments/{id}/secrets/{name}`: creates or replaces one credential. The same
60
105
  * name and type keeps the credential's id and re-seals its value and binding; another type
@@ -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.25.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.25.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.25.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.21.0-beta",
69
+ "@nylorun/harness": "0.27.0-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
- }