@nylorun/runtime 0.27.0-beta → 0.29.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.
- package/CHANGELOG.md +67 -0
- package/README.md +1 -1
- package/dist/api/a2a/card.d.ts +4 -3
- package/dist/api/a2a/card.js +3 -3
- package/dist/api/a2a/routes.js +18 -7
- package/dist/api/ag-ui/routes.js +4 -7
- package/dist/api/components.d.ts +5854 -2718
- package/dist/api/components.js +39 -30
- package/dist/api/http/app.js +9 -4
- package/dist/api/http/body.d.ts +2 -0
- package/dist/api/http/body.js +20 -0
- package/dist/api/http/define.d.ts +4 -0
- package/dist/api/http/define.js +20 -9
- package/dist/api/http/routes/agent-manifests.d.ts +10 -0
- package/dist/api/http/routes/agent-manifests.js +135 -0
- package/dist/api/http/routes/agents.d.ts +11 -0
- package/dist/api/http/routes/agents.js +418 -0
- package/dist/api/http/routes/artifacts.js +2 -2
- package/dist/api/http/routes/coverage.d.ts +4 -4
- package/dist/api/http/routes/coverage.js +12 -6
- package/dist/api/http/routes/files.js +1 -1
- package/dist/api/http/routes/mcp.js +2 -2
- package/dist/api/http/routes/me.d.ts +1 -1
- package/dist/api/http/routes/me.js +1 -2
- package/dist/api/http/routes/memories.d.ts +9 -0
- package/dist/api/http/routes/memories.js +152 -0
- package/dist/api/http/routes/reads.d.ts +1 -137
- package/dist/api/http/routes/reads.js +31 -12
- package/dist/api/http/routes/sessions.js +21 -50
- package/dist/api/http/routes/tenant.js +13 -10
- package/dist/api/http/routes/triggers.d.ts +10 -0
- package/dist/api/http/routes/triggers.js +183 -0
- package/dist/api/openapi.js +69 -47
- package/dist/artifacts/disk.d.ts +10 -10
- package/dist/artifacts/disk.js +27 -27
- package/dist/artifacts/quota.d.ts +1 -1
- package/dist/artifacts/quota.js +2 -2
- package/dist/artifacts/service.js +2 -2
- package/dist/core/flow-host.d.ts +0 -1
- package/dist/gates/egress-credentials.js +1 -1
- package/dist/gates/egress.d.ts +5 -5
- package/dist/gates/egress.js +6 -6
- package/dist/gates/http-tool.js +2 -2
- package/dist/gates/meter.js +22 -5
- package/dist/gates/policy.d.ts +8 -3
- package/dist/gates/policy.js +7 -2
- package/dist/gates/tenant-vaults.d.ts +1 -1
- package/dist/harness/pod.d.ts +2 -0
- package/dist/harness/setup.js +17 -6
- package/dist/harness-api/record.js +11 -0
- package/dist/harness-api/server.js +4 -0
- package/dist/harness-api/start.d.ts +11 -7
- package/dist/harness-api/start.js +49 -5
- package/dist/harness-api/workspace.js +2 -2
- package/dist/host/config-for.d.ts +2 -0
- package/dist/host/config-for.js +1 -0
- package/dist/host/http.d.ts +2 -2
- package/dist/host/http.js +5 -2
- package/dist/host/main.js +1 -0
- package/dist/keys/keys.d.ts +15 -4
- package/dist/keys/keys.js +16 -0
- package/dist/keys/webhooks.d.ts +25 -0
- package/dist/keys/webhooks.js +62 -0
- package/dist/management-openapi.json +313 -133
- package/dist/mcp/connect.d.ts +2 -2
- package/dist/mcp/connect.js +3 -3
- package/dist/mcp/preview.js +7 -7
- package/dist/memory/service.d.ts +97 -0
- package/dist/memory/service.js +335 -0
- package/dist/memory/tool.d.ts +36 -0
- package/dist/memory/tool.js +84 -0
- package/dist/model/pi-model.js +7 -0
- package/dist/openapi.json +13120 -9034
- package/dist/reads/types.d.ts +3 -3
- package/dist/record/agent.d.ts +27 -0
- package/dist/record/agent.js +46 -0
- package/dist/record/index.d.ts +1 -1
- package/dist/record/index.js +1 -1
- package/dist/sandbox/join.js +5 -5
- package/dist/sandbox/placement.d.ts +1 -1
- package/dist/sandbox/placement.js +3 -3
- package/dist/sandbox/pods/lifecycle.d.ts +6 -6
- package/dist/sandbox/pods/lifecycle.js +6 -6
- package/dist/sandbox/pods/reconcile.js +10 -2
- package/dist/sandbox/resolve.d.ts +3 -3
- package/dist/sandbox/resolve.js +7 -7
- package/dist/sandbox/setup.d.ts +3 -1
- package/dist/sandbox/setup.js +14 -4
- package/dist/store/postgres/drizzle/0032_agents.sql +54 -0
- package/dist/store/postgres/drizzle/0033_agent_versions.sql +7 -0
- package/dist/store/postgres/drizzle/0034_protocol_17_session_queue.sql +13 -0
- package/dist/store/postgres/drizzle/0035_t4_triggers.sql +41 -0
- package/dist/store/postgres/drizzle/0036_t5_memories.sql +30 -0
- package/dist/store/postgres/drizzle/0037_model_usage_cost_split.sql +4 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +42 -0
- package/dist/store/postgres/reads.js +44 -87
- package/dist/store/postgres/record-writer.d.ts +4 -4
- package/dist/store/postgres/record-writer.js +9 -9
- package/dist/store/postgres/schema.d.ts +1408 -123
- package/dist/store/postgres/schema.js +194 -38
- package/dist/store/postgres/store.js +329 -79
- package/dist/store/postgres/tenant.js +1 -2
- package/dist/store/types.d.ts +155 -50
- package/dist/store/types.js +0 -1
- package/dist/tenant/advance.js +20 -8
- package/dist/tenant/agent-manifests.d.ts +72 -0
- package/dist/tenant/agent-manifests.js +359 -0
- package/dist/tenant/agent-versions.d.ts +126 -0
- package/dist/tenant/agent-versions.js +389 -0
- package/dist/tenant/agents.d.ts +230 -0
- package/dist/tenant/{environments.js → agents.js} +464 -320
- package/dist/tenant/auth.d.ts +1 -1
- package/dist/tenant/auth.js +3 -3
- package/dist/tenant/commands.d.ts +63 -2
- package/dist/tenant/commands.js +240 -83
- package/dist/tenant/context.d.ts +46 -19
- package/dist/tenant/context.js +6 -2
- package/dist/tenant/effects.js +7 -16
- package/dist/tenant/identity-file.d.ts +6 -6
- package/dist/tenant/identity-file.js +12 -10
- package/dist/tenant/issuers.js +3 -3
- package/dist/tenant/limits.d.ts +0 -3
- package/dist/tenant/limits.js +0 -3
- package/dist/tenant/memories.d.ts +38 -0
- package/dist/tenant/memories.js +119 -0
- package/dist/tenant/reset.js +2 -2
- package/dist/tenant/run-grants.d.ts +6 -0
- package/dist/tenant/run-grants.js +4 -0
- package/dist/tenant/runtime.d.ts +1 -1
- package/dist/tenant/runtime.js +8 -0
- package/dist/tenant/sessions.d.ts +28 -45
- package/dist/tenant/sessions.js +85 -208
- package/dist/tenant/status.js +6 -7
- package/dist/tenant/sweep.js +12 -3
- package/dist/tenant/transcript.d.ts +16 -16
- package/dist/tenant/triggers.d.ts +143 -0
- package/dist/tenant/triggers.js +715 -0
- package/dist/tenant/turn-timing.d.ts +11 -1
- package/dist/tenant/turn-timing.js +3 -1
- package/dist/tenant/types.d.ts +5 -0
- package/dist/tenant/worker.d.ts +2 -0
- package/dist/tenant/worker.js +5 -0
- package/dist/traces/map.d.ts +1 -1
- package/dist/traces/map.js +7 -1
- package/dist/tuning.d.ts +7 -0
- package/dist/tuning.js +19 -0
- package/dist/vault/service.d.ts +13 -8
- package/dist/vault/service.js +61 -17
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +13 -12
- package/dist/api/http/routes/environment-manifests.d.ts +0 -9
- package/dist/api/http/routes/environment-manifests.js +0 -118
- package/dist/api/http/routes/environments.d.ts +0 -11
- package/dist/api/http/routes/environments.js +0 -332
- package/dist/record/environment.d.ts +0 -27
- package/dist/record/environment.js +0 -46
- package/dist/tenant/environment-manifests.d.ts +0 -57
- package/dist/tenant/environment-manifests.js +0 -208
- package/dist/tenant/environments.d.ts +0 -172
package/dist/keys/keys.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AgentSecretView, HostModelView, McpPreview, McpPreviewRequest, PutAgentSecretRequest, PutHostModelRequest, SelectHostModelRequest, SigningKeyView } from "@nylorun/core/contracts";
|
|
2
2
|
import type { SessionStore } from "../store/types.js";
|
|
3
3
|
import type { OutboundPolicy } from "../tenant/outbound.js";
|
|
4
4
|
import { type SigningKeys } from "../tenant/signing-keys.js";
|
|
@@ -13,9 +13,10 @@ export interface Signed {
|
|
|
13
13
|
/** The signing key's id, the token's `kid`. */
|
|
14
14
|
readonly keyId: string;
|
|
15
15
|
}
|
|
16
|
+
import { type SealedWebhookSecret, type WebhookDelivery } from "./webhooks.js";
|
|
16
17
|
export interface Keys {
|
|
17
|
-
/** `PUT /v1/
|
|
18
|
-
putEnvironmentSecret(environmentId: string, name: string, body:
|
|
18
|
+
/** `PUT /v1/agents/{id}/secrets/{name}` (`VaultService.putEnvironmentSecret`). */
|
|
19
|
+
putEnvironmentSecret(environmentId: string, name: string, body: PutAgentSecretRequest, actor: string): Promise<AgentSecretView>;
|
|
19
20
|
putHostModel(body: PutHostModelRequest): Promise<HostModelView>;
|
|
20
21
|
selectHostModel(body: SelectHostModelRequest): Promise<HostModelView>;
|
|
21
22
|
/**
|
|
@@ -46,9 +47,19 @@ export interface Keys {
|
|
|
46
47
|
* egress CA (R2c). The leaf's private key never reaches keys; the CA's never leaves it.
|
|
47
48
|
*/
|
|
48
49
|
signEgressLeaf(host: string, publicKey: string): Promise<string>;
|
|
50
|
+
/**
|
|
51
|
+
* A new Standard Webhooks secret for Agent `agentId`'s trigger `triggerId` (track T4, D75), and
|
|
52
|
+
* the same sealed with the vault key for the trigger's row. The secret leaves keys this once.
|
|
53
|
+
*/
|
|
54
|
+
makeWebhookSecret(agentId: string, triggerId: string): Promise<{
|
|
55
|
+
secret: string;
|
|
56
|
+
sealed: SealedWebhookSecret;
|
|
57
|
+
}>;
|
|
58
|
+
/** Whether a delivery to that trigger carries a signature its sealed secret made. */
|
|
59
|
+
verifyWebhook(agentId: string, triggerId: string, sealed: SealedWebhookSecret, delivery: WebhookDelivery): Promise<boolean>;
|
|
49
60
|
}
|
|
50
61
|
/** The operations, by the name the HTTP route carries. */
|
|
51
|
-
export declare const KEYS_OPERATIONS: readonly ["putEnvironmentSecret", "putHostModel", "selectHostModel", "sealEnvironmentSecretCopies", "sign", "rotateSigningKeys", "ensureSigningKeys", "previewMcp", "egressCa", "signEgressLeaf"];
|
|
62
|
+
export declare const KEYS_OPERATIONS: readonly ["putEnvironmentSecret", "putHostModel", "selectHostModel", "sealEnvironmentSecretCopies", "sign", "rotateSigningKeys", "ensureSigningKeys", "previewMcp", "egressCa", "signEgressLeaf", "makeWebhookSecret", "verifyWebhook"];
|
|
52
63
|
export type KeysOperation = (typeof KEYS_OPERATIONS)[number];
|
|
53
64
|
export interface InProcessKeysOptions {
|
|
54
65
|
readonly store: SessionStore;
|
package/dist/keys/keys.js
CHANGED
|
@@ -18,6 +18,8 @@ import { SignJWT } from "jose";
|
|
|
18
18
|
import { previewMcpServer } from "../mcp/preview.js";
|
|
19
19
|
import { readRuntimeLimits } from "../tenant/runtime-limits.js";
|
|
20
20
|
import { signingKeyView } from "../tenant/signing-keys.js";
|
|
21
|
+
import { makeWebhookSecret, verifyWebhook } from "./webhooks.js";
|
|
22
|
+
import { VaultCryptoError } from "../vault/crypto.js";
|
|
21
23
|
/** The operations, by the name the HTTP route carries. */
|
|
22
24
|
export const KEYS_OPERATIONS = [
|
|
23
25
|
"putEnvironmentSecret",
|
|
@@ -30,6 +32,8 @@ export const KEYS_OPERATIONS = [
|
|
|
30
32
|
"previewMcp",
|
|
31
33
|
"egressCa",
|
|
32
34
|
"signEgressLeaf",
|
|
35
|
+
"makeWebhookSecret",
|
|
36
|
+
"verifyWebhook",
|
|
33
37
|
];
|
|
34
38
|
export function inProcessKeys(options) {
|
|
35
39
|
const { store, vault, signingKeys, kek } = options;
|
|
@@ -64,5 +68,17 @@ export function inProcessKeys(options) {
|
|
|
64
68
|
}),
|
|
65
69
|
egressCa: () => egress.certificate(),
|
|
66
70
|
signEgressLeaf: (host, publicKey) => egress.signLeaf(host, publicKey),
|
|
71
|
+
makeWebhookSecret: async (agentId, triggerId) => makeWebhookSecret(kek(), agentId, triggerId),
|
|
72
|
+
verifyWebhook: async (agentId, triggerId, sealed, delivery) => {
|
|
73
|
+
try {
|
|
74
|
+
return verifyWebhook(kek(), agentId, triggerId, sealed, delivery);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
// A secret sealed with another vault key, or not one: it verifies nothing.
|
|
78
|
+
if (error instanceof VaultCryptoError)
|
|
79
|
+
return false;
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
},
|
|
67
83
|
};
|
|
68
84
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** A secret sealed with the vault key, as the trigger's row keeps it. */
|
|
2
|
+
export interface SealedWebhookSecret {
|
|
3
|
+
readonly nonce: string;
|
|
4
|
+
readonly ciphertext: string;
|
|
5
|
+
readonly wrappedDek: string;
|
|
6
|
+
readonly kekId: string;
|
|
7
|
+
}
|
|
8
|
+
/** What a delivery says, as it arrived: its headers, and its body in base64. */
|
|
9
|
+
export interface WebhookDelivery {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly timestamp: string;
|
|
12
|
+
readonly signature: string;
|
|
13
|
+
readonly body: string;
|
|
14
|
+
}
|
|
15
|
+
/** A new secret for Agent `agentId`'s trigger `triggerId`, and the same sealed for its row. */
|
|
16
|
+
export declare function makeWebhookSecret(kek: Buffer, agentId: string, triggerId: string): {
|
|
17
|
+
secret: string;
|
|
18
|
+
sealed: SealedWebhookSecret;
|
|
19
|
+
};
|
|
20
|
+
/** The signature of `delivery`'s id, timestamp and body with `key` (base64). */
|
|
21
|
+
export declare function signWebhook(key: Buffer, id: string, timestamp: string, body: Buffer): string;
|
|
22
|
+
/** The key bytes of a `whsec_` secret. */
|
|
23
|
+
export declare function webhookKeyOf(secret: string): Buffer;
|
|
24
|
+
/** Whether `delivery` carries a signature the sealed secret made. */
|
|
25
|
+
export declare function verifyWebhook(kek: Buffer, agentId: string, triggerId: string, sealed: SealedWebhookSecret, delivery: WebhookDelivery): boolean;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook signing secrets (track T4, D75): the keys service makes a trigger's Standard Webhooks
|
|
3
|
+
* secret, seals it with the Tenant's vault key for the trigger's row, and is the only place that
|
|
4
|
+
* opens it, to verify a delivery. The secret leaves keys once, when it is made, for its owner.
|
|
5
|
+
*
|
|
6
|
+
* Standard Webhooks (https://www.standardwebhooks.com): the secret is `whsec_` and the base64 of
|
|
7
|
+
* its key bytes; a delivery's `webhook-signature` is space-separated `v1,<base64>` entries, each an
|
|
8
|
+
* HMAC-SHA256 with the key over `<webhook-id>.<webhook-timestamp>.<body>`. One that matches, in
|
|
9
|
+
* constant time, verifies it. The timestamp's tolerance is the route's to check.
|
|
10
|
+
*/
|
|
11
|
+
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
12
|
+
import { decryptSecret, encryptSecret } from "../vault/crypto.js";
|
|
13
|
+
/** The Standard Webhooks secret format: the prefix, and 32 random bytes of key. */
|
|
14
|
+
const SECRET_PREFIX = "whsec_";
|
|
15
|
+
const SECRET_BYTES = 32;
|
|
16
|
+
const aadOf = (agentId, triggerId) => Buffer.from(`nylorun-webhook:${agentId}:${triggerId}`, "utf8");
|
|
17
|
+
/** A new secret for Agent `agentId`'s trigger `triggerId`, and the same sealed for its row. */
|
|
18
|
+
export function makeWebhookSecret(kek, agentId, triggerId) {
|
|
19
|
+
const key = randomBytes(SECRET_BYTES);
|
|
20
|
+
try {
|
|
21
|
+
const sealed = encryptSecret(kek, aadOf(agentId, triggerId), key);
|
|
22
|
+
return {
|
|
23
|
+
secret: `${SECRET_PREFIX}${key.toString("base64")}`,
|
|
24
|
+
sealed: {
|
|
25
|
+
nonce: sealed.nonce.toString("base64"),
|
|
26
|
+
ciphertext: sealed.ciphertext.toString("base64"),
|
|
27
|
+
wrappedDek: sealed.wrappedDek.toString("base64"),
|
|
28
|
+
kekId: sealed.kekId,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
key.fill(0);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** The signature of `delivery`'s id, timestamp and body with `key` (base64). */
|
|
37
|
+
export function signWebhook(key, id, timestamp, body) {
|
|
38
|
+
return createHmac("sha256", key).update(`${id}.${timestamp}.`).update(body).digest("base64");
|
|
39
|
+
}
|
|
40
|
+
/** The key bytes of a `whsec_` secret. */
|
|
41
|
+
export function webhookKeyOf(secret) {
|
|
42
|
+
return Buffer.from(secret.startsWith(SECRET_PREFIX) ? secret.slice(SECRET_PREFIX.length) : secret, "base64");
|
|
43
|
+
}
|
|
44
|
+
/** Whether `delivery` carries a signature the sealed secret made. */
|
|
45
|
+
export function verifyWebhook(kek, agentId, triggerId, sealed, delivery) {
|
|
46
|
+
const key = decryptSecret(kek, aadOf(agentId, triggerId), Buffer.from(sealed.nonce, "base64"), Buffer.from(sealed.ciphertext, "base64"), Buffer.from(sealed.wrappedDek, "base64"), sealed.kekId);
|
|
47
|
+
try {
|
|
48
|
+
const expected = Buffer.from(signWebhook(key, delivery.id, delivery.timestamp, Buffer.from(delivery.body, "base64")), "base64");
|
|
49
|
+
for (const entry of delivery.signature.split(" ")) {
|
|
50
|
+
const [version, value] = entry.split(",", 2);
|
|
51
|
+
if (version !== "v1" || !value)
|
|
52
|
+
continue;
|
|
53
|
+
const given = Buffer.from(value, "base64");
|
|
54
|
+
if (given.length === expected.length && timingSafeEqual(given, expected))
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
key.fill(0);
|
|
61
|
+
}
|
|
62
|
+
}
|