@nylorun/runtime 0.9.0-beta → 0.11.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 +81 -0
- package/README.md +110 -37
- package/dist/adapters/execution/restate.d.ts +130 -0
- package/dist/adapters/execution/restate.js +442 -0
- package/dist/adapters/media.d.ts +2 -2
- package/dist/adapters/media.js +2 -2
- package/dist/adapters/observe.d.ts +2 -1
- package/dist/adapters/observe.js +2 -3
- package/dist/adapters/sandbox/virtual.js +1 -1
- package/dist/adapters/streams/s2.d.ts +18 -0
- package/dist/adapters/streams/s2.js +361 -0
- package/dist/assets.d.ts +2 -2
- package/dist/assets.js +5 -3
- package/dist/core/executors.d.ts +15 -3
- package/dist/core/executors.js +40 -5
- package/dist/core/flow-host.d.ts +225 -0
- package/dist/core/flow-host.js +518 -0
- package/dist/core/limits.d.ts +40 -0
- package/dist/core/limits.js +76 -0
- package/dist/core/runtime.d.ts +5 -90
- package/dist/core/runtime.js +3 -1447
- package/dist/core/sandbox-routes.d.ts +40 -0
- package/dist/core/sandbox-routes.js +106 -0
- package/dist/core/turn-manifest.d.ts +50 -0
- package/dist/core/turn-manifest.js +66 -0
- package/dist/execution/memory.d.ts +54 -0
- package/dist/execution/memory.js +217 -0
- package/dist/execution/types.d.ts +125 -0
- package/dist/execution/types.js +52 -0
- package/dist/host/config-for.d.ts +17 -0
- package/dist/host/config-for.js +27 -0
- package/dist/host/config.d.ts +16 -0
- package/dist/host/create-host.d.ts +56 -0
- package/dist/host/create-host.js +420 -0
- package/dist/host/environment.d.ts +13 -0
- package/dist/host/environment.js +53 -0
- package/dist/host/execution.d.ts +61 -0
- package/dist/host/execution.js +69 -0
- package/dist/host/http.d.ts +39 -0
- package/dist/host/http.js +142 -0
- package/dist/host/index.d.ts +8 -0
- package/dist/host/index.js +7 -0
- package/dist/host/logger.d.ts +3 -0
- package/dist/host/logger.js +18 -0
- package/dist/host/main.d.ts +3 -0
- package/dist/host/main.js +201 -0
- package/dist/host/stack-config.d.ts +72 -0
- package/dist/host/stack-config.js +193 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +4 -2
- package/dist/infra/database.d.ts +16 -0
- package/dist/infra/database.js +31 -0
- package/dist/infra/execution.d.ts +39 -0
- package/dist/infra/execution.js +68 -0
- package/dist/infra/index.d.ts +42 -0
- package/dist/infra/index.js +56 -0
- package/dist/infra/readiness.d.ts +33 -0
- package/dist/infra/readiness.js +53 -0
- package/dist/infra/streams.d.ts +17 -0
- package/dist/infra/streams.js +33 -0
- package/dist/infra/workers.d.ts +39 -0
- package/dist/infra/workers.js +31 -0
- package/dist/mcp/connect.d.ts +1 -0
- package/dist/mcp/connect.js +2 -0
- package/dist/mcp/pool.d.ts +3 -1
- package/dist/mcp/pool.js +2 -1
- package/dist/mcp/stdio.d.ts +2 -0
- package/dist/mcp/stdio.js +3 -1
- package/dist/model/auth-store.d.ts +1 -1
- package/dist/model/auth-store.js +2 -2
- package/dist/model/models.d.ts +4 -0
- package/dist/model/models.js +22 -26
- package/dist/model/pi-model.d.ts +2 -2
- package/dist/model/pi-model.js +6 -6
- package/dist/model/settings.d.ts +5 -1
- package/dist/model/settings.js +6 -2
- package/dist/sandbox/manager.d.ts +26 -8
- package/dist/sandbox/manager.js +95 -47
- package/dist/sandbox/select.d.ts +5 -4
- package/dist/sandbox/select.js +18 -13
- package/dist/sandbox/share.d.ts +23 -0
- package/dist/sandbox/share.js +58 -0
- package/dist/sandbox/types.d.ts +2 -2
- package/dist/store/canonical.d.ts +5 -0
- package/dist/store/canonical.js +17 -0
- package/dist/store/cursor.d.ts +9 -0
- package/dist/store/cursor.js +18 -0
- package/dist/store/memory.d.ts +57 -0
- package/dist/store/memory.js +643 -0
- package/dist/store/ownership.d.ts +19 -0
- package/dist/store/ownership.js +33 -0
- package/dist/store/postgres/connect.d.ts +25 -0
- package/dist/store/postgres/connect.js +25 -0
- package/dist/store/postgres/locking.d.ts +16 -0
- package/dist/store/postgres/locking.js +22 -0
- package/dist/store/postgres/migrations/001_initial.d.ts +27 -0
- package/dist/store/postgres/migrations/001_initial.js +196 -0
- package/dist/store/postgres/migrations/index.d.ts +49 -0
- package/dist/store/postgres/migrations/index.js +75 -0
- package/dist/store/postgres/names.d.ts +11 -0
- package/dist/store/postgres/names.js +42 -0
- package/dist/store/postgres/store.d.ts +11 -0
- package/dist/store/postgres/store.js +790 -0
- package/dist/store/postgres/tenants.d.ts +90 -0
- package/dist/store/postgres/tenants.js +207 -0
- package/dist/store/types.d.ts +440 -0
- package/dist/store/types.js +10 -0
- package/dist/streams/basin.d.ts +23 -0
- package/dist/streams/basin.js +51 -0
- package/dist/streams/memory.d.ts +25 -0
- package/dist/streams/memory.js +124 -0
- package/dist/streams/relay.d.ts +37 -0
- package/dist/streams/relay.js +254 -0
- package/dist/streams/types.d.ts +115 -0
- package/dist/streams/types.js +86 -0
- package/dist/tenant/actions.d.ts +153 -0
- package/dist/tenant/actions.js +191 -0
- package/dist/tenant/advance.d.ts +15 -0
- package/dist/tenant/advance.js +439 -0
- package/dist/tenant/auth.d.ts +11 -0
- package/dist/tenant/auth.js +34 -0
- package/dist/tenant/commands.d.ts +3 -0
- package/dist/tenant/commands.js +384 -0
- package/dist/tenant/context.d.ts +140 -0
- package/dist/tenant/context.js +40 -0
- package/dist/tenant/effects.d.ts +20 -0
- package/dist/tenant/effects.js +539 -0
- package/dist/tenant/envelope.d.ts +7 -0
- package/dist/tenant/envelope.js +22 -0
- package/dist/tenant/ephemeral.d.ts +42 -0
- package/dist/tenant/ephemeral.js +224 -0
- package/dist/tenant/http.d.ts +32 -0
- package/dist/tenant/http.js +51 -0
- package/dist/tenant/live.d.ts +92 -0
- package/dist/tenant/live.js +290 -0
- package/dist/tenant/logger.d.ts +9 -0
- package/dist/tenant/logger.js +25 -0
- package/dist/tenant/model-setting.d.ts +16 -0
- package/dist/tenant/model-setting.js +12 -0
- package/dist/tenant/module.d.ts +38 -0
- package/dist/tenant/module.js +319 -0
- package/dist/tenant/paths.d.ts +28 -0
- package/dist/tenant/paths.js +91 -0
- package/dist/tenant/pool.d.ts +10 -0
- package/dist/tenant/pool.js +54 -0
- package/dist/tenant/principals.d.ts +13 -0
- package/dist/tenant/principals.js +37 -0
- package/dist/tenant/quarantine-error.d.ts +6 -0
- package/dist/tenant/quarantine-error.js +9 -0
- package/dist/tenant/quarantine.d.ts +27 -0
- package/dist/tenant/quarantine.js +72 -0
- package/dist/tenant/reset.d.ts +22 -0
- package/dist/tenant/reset.js +81 -0
- package/dist/tenant/routes-tenant.d.ts +12 -0
- package/dist/tenant/routes-tenant.js +126 -0
- package/dist/tenant/routes.d.ts +9 -0
- package/dist/tenant/routes.js +142 -0
- package/dist/tenant/runtime.d.ts +81 -0
- package/dist/tenant/runtime.js +298 -0
- package/dist/tenant/scheduler.d.ts +25 -0
- package/dist/tenant/scheduler.js +84 -0
- package/dist/tenant/session.d.ts +60 -0
- package/dist/tenant/session.js +94 -0
- package/dist/tenant/sessions.d.ts +34 -0
- package/dist/tenant/sessions.js +149 -0
- package/dist/tenant/status.d.ts +37 -0
- package/dist/tenant/status.js +130 -0
- package/dist/tenant/store-memory.d.ts +16 -0
- package/dist/tenant/store-memory.js +111 -0
- package/dist/tenant/store-pg.d.ts +15 -0
- package/dist/tenant/store-pg.js +140 -0
- package/dist/tenant/streams.d.ts +126 -0
- package/dist/tenant/streams.js +419 -0
- package/dist/tenant/sweep.d.ts +15 -0
- package/dist/tenant/sweep.js +122 -0
- package/dist/tenant/types.d.ts +205 -0
- package/dist/tenant/types.js +23 -0
- package/dist/tenant/worker.d.ts +84 -0
- package/dist/tenant/worker.js +189 -0
- package/dist/vault/kek.d.ts +5 -2
- package/dist/vault/kek.js +7 -10
- package/dist/vault/service.d.ts +37 -31
- package/dist/vault/service.js +439 -359
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +14 -11
- package/dist/adapters/sandbox/microsandbox.d.ts +0 -2
- package/dist/adapters/sandbox/microsandbox.js +0 -238
- package/dist/core/main.js +0 -35
- package/dist/core/store.d.ts +0 -30
- package/dist/core/store.js +0 -202
- /package/dist/{core/main.d.ts → host/config.js} +0 -0
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const RUNTIME_VERSION = "0.
|
|
1
|
+
export declare const RUNTIME_VERSION = "0.11.0-beta";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nylorun/runtime",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.11.0-beta",
|
|
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",
|
|
7
7
|
"repository": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"types": "./dist/core/runtime.d.ts",
|
|
26
26
|
"import": "./dist/core/runtime.js"
|
|
27
27
|
},
|
|
28
|
-
"./server": "./dist/
|
|
28
|
+
"./server": "./dist/host/main.js",
|
|
29
29
|
"./configuration": {
|
|
30
30
|
"types": "./dist/configuration.d.ts",
|
|
31
31
|
"import": "./dist/configuration.js"
|
|
@@ -47,20 +47,23 @@
|
|
|
47
47
|
"check": "npm run build && npm test && node scripts/check-package.mjs",
|
|
48
48
|
"typecheck": "node ../scripts/check-typescript-version.mjs && tsc -p tsconfig.json --noEmit",
|
|
49
49
|
"test": "vitest run",
|
|
50
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
51
|
+
"test:stack:up": "node test/stack/up.mjs up",
|
|
52
|
+
"test:stack:down": "node test/stack/up.mjs down",
|
|
50
53
|
"prepack": "npm run build",
|
|
51
54
|
"clean": "node -e \"import('node:fs').then(({rmSync})=>rmSync('dist',{recursive:true,force:true}))\"",
|
|
52
|
-
"start": "node dist/
|
|
55
|
+
"start": "node dist/host/main.js"
|
|
53
56
|
},
|
|
54
57
|
"dependencies": {
|
|
55
58
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
56
|
-
"@earendil-works/pi-ai": "0.
|
|
59
|
+
"@earendil-works/pi-ai": "0.87.0",
|
|
57
60
|
"@hono/node-server": "^2.1.1",
|
|
58
|
-
"@nylorun/harness": "0.
|
|
59
|
-
"@nylorun/core": "0.
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"
|
|
61
|
+
"@nylorun/harness": "0.19.1-beta",
|
|
62
|
+
"@nylorun/core": "0.6.0-beta",
|
|
63
|
+
"@restatedev/restate-sdk": "1.16.9",
|
|
64
|
+
"@s2-dev/streamstore": "0.27.0",
|
|
65
|
+
"just-bash": "3.4.2",
|
|
66
|
+
"postgres": "^3.4.9"
|
|
64
67
|
},
|
|
65
68
|
"devDependencies": {
|
|
66
69
|
"@types/node": "^26.5.0",
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
/** microsandbox backend: a hardware-isolated microVM per sandbox (libkrun). */
|
|
2
|
-
import { accessSync, constants, readFileSync } from "node:fs";
|
|
3
|
-
import { createRequire } from "node:module";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import { SANDBOX_WORKSPACE } from "@nylorun/core/define";
|
|
6
|
-
/** Releases that are known not to work; the probe refuses them and selection falls back. */
|
|
7
|
-
const KNOWN_BAD_VERSIONS = new Set(["0.7.0"]);
|
|
8
|
-
/** Keep at most this much of each output stream in memory while a command runs. */
|
|
9
|
-
const CAPTURE_LIMIT = 4 * 1024 * 1024;
|
|
10
|
-
const require = createRequire(import.meta.url);
|
|
11
|
-
/** The package's exports map hides package.json, so walk up from its entry point. */
|
|
12
|
-
function installedVersion() {
|
|
13
|
-
try {
|
|
14
|
-
let directory = dirname(require.resolve("microsandbox"));
|
|
15
|
-
for (let depth = 0; depth < 4; depth += 1, directory = dirname(directory)) {
|
|
16
|
-
try {
|
|
17
|
-
const manifest = JSON.parse(readFileSync(join(directory, "package.json"), "utf8"));
|
|
18
|
-
if (manifest.name === "microsandbox")
|
|
19
|
-
return manifest.version;
|
|
20
|
-
}
|
|
21
|
-
catch { }
|
|
22
|
-
}
|
|
23
|
-
return undefined;
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return undefined;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function platformReason() {
|
|
30
|
-
if (process.platform === "darwin")
|
|
31
|
-
return process.arch === "arm64" ? undefined : "requires Apple Silicon on macOS";
|
|
32
|
-
if (process.platform === "linux") {
|
|
33
|
-
try {
|
|
34
|
-
accessSync("/dev/kvm", constants.R_OK | constants.W_OK);
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return "no usable /dev/kvm (enable KVM or nested virtualisation)";
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
if (process.platform === "win32")
|
|
42
|
-
return "not yet enabled on Windows";
|
|
43
|
-
return `unsupported platform ${process.platform}`;
|
|
44
|
-
}
|
|
45
|
-
export function microsandboxBackend() {
|
|
46
|
-
let sdk;
|
|
47
|
-
const load = () => (sdk ??= import("microsandbox"));
|
|
48
|
-
const handleFor = (sandbox) => ({
|
|
49
|
-
async exec(request, signal) {
|
|
50
|
-
const execution = await sandbox.execStreamWith("bash", (options) => options
|
|
51
|
-
.args(["-c", request.command])
|
|
52
|
-
.cwd(request.cwd)
|
|
53
|
-
.envs({ LANG: "C.UTF-8", TERM: "dumb" })
|
|
54
|
-
.stdinNull());
|
|
55
|
-
const stdout = new Capture();
|
|
56
|
-
const stderr = new Capture();
|
|
57
|
-
let killed = false;
|
|
58
|
-
let timedOut = false;
|
|
59
|
-
const kill = () => {
|
|
60
|
-
if (killed)
|
|
61
|
-
return;
|
|
62
|
-
killed = true;
|
|
63
|
-
void execution.kill().catch(() => undefined);
|
|
64
|
-
};
|
|
65
|
-
const timer = setTimeout(() => {
|
|
66
|
-
timedOut = true;
|
|
67
|
-
kill();
|
|
68
|
-
}, request.timeoutMs);
|
|
69
|
-
const onAbort = () => kill();
|
|
70
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
71
|
-
if (signal.aborted)
|
|
72
|
-
kill();
|
|
73
|
-
let exitCode = -1;
|
|
74
|
-
try {
|
|
75
|
-
for await (const event of execution) {
|
|
76
|
-
if (event.kind === "stdout")
|
|
77
|
-
stdout.push(event.data);
|
|
78
|
-
else if (event.kind === "stderr")
|
|
79
|
-
stderr.push(event.data);
|
|
80
|
-
else if (event.kind === "exited") {
|
|
81
|
-
exitCode = event.code;
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
finally {
|
|
87
|
-
clearTimeout(timer);
|
|
88
|
-
signal.removeEventListener("abort", onAbort);
|
|
89
|
-
}
|
|
90
|
-
return {
|
|
91
|
-
exitCode: killed && exitCode < 0 ? (timedOut ? 124 : 130) : exitCode,
|
|
92
|
-
stdout: stdout.text(),
|
|
93
|
-
stderr: stderr.text(),
|
|
94
|
-
killed,
|
|
95
|
-
timedOut,
|
|
96
|
-
};
|
|
97
|
-
},
|
|
98
|
-
async readFile(path) {
|
|
99
|
-
const fs = sandbox.fs();
|
|
100
|
-
if (!(await fs.exists(path)))
|
|
101
|
-
return undefined;
|
|
102
|
-
return fs.readToString(path);
|
|
103
|
-
},
|
|
104
|
-
async writeFile(path, content) {
|
|
105
|
-
await sandbox.fs().write(path, content);
|
|
106
|
-
},
|
|
107
|
-
async stop() {
|
|
108
|
-
await sandbox.stop();
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
return {
|
|
112
|
-
name: "microsandbox",
|
|
113
|
-
isolation: "vm",
|
|
114
|
-
async probe() {
|
|
115
|
-
const base = { name: "microsandbox", isolation: "vm" };
|
|
116
|
-
const version = installedVersion();
|
|
117
|
-
const platform = platformReason();
|
|
118
|
-
if (platform)
|
|
119
|
-
return { ...base, available: false, reason: platform, ...(version ? { version } : {}) };
|
|
120
|
-
if (!version)
|
|
121
|
-
return {
|
|
122
|
-
...base,
|
|
123
|
-
available: false,
|
|
124
|
-
reason: "the optional microsandbox package is not installed (reinstall with optional dependencies enabled)",
|
|
125
|
-
};
|
|
126
|
-
if (KNOWN_BAD_VERSIONS.has(version))
|
|
127
|
-
return { ...base, available: false, version, reason: `microsandbox ${version} is a known-bad release` };
|
|
128
|
-
try {
|
|
129
|
-
const msb = await load();
|
|
130
|
-
if (!(await msb.isRuntimeInstalled()))
|
|
131
|
-
return { ...base, available: false, version, reason: "the microsandbox runtime (msb, libkrunfw) is not installed" };
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
return {
|
|
135
|
-
...base,
|
|
136
|
-
available: false,
|
|
137
|
-
version,
|
|
138
|
-
reason: `could not load microsandbox: ${error instanceof Error ? error.message : String(error)}`,
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
return { ...base, available: true, version, reason: "hardware-isolated microVM" };
|
|
142
|
-
},
|
|
143
|
-
unmet() {
|
|
144
|
-
return undefined;
|
|
145
|
-
},
|
|
146
|
-
async open(spec) {
|
|
147
|
-
const msb = await load();
|
|
148
|
-
const { Sandbox, SandboxNotFoundError } = msb;
|
|
149
|
-
try {
|
|
150
|
-
const existing = await Sandbox.get(spec.key);
|
|
151
|
-
return handleFor(await existing.connectOrStart());
|
|
152
|
-
}
|
|
153
|
-
catch (error) {
|
|
154
|
-
if (!(error instanceof SandboxNotFoundError))
|
|
155
|
-
throw error;
|
|
156
|
-
}
|
|
157
|
-
const sandbox = await Sandbox.builder(spec.key)
|
|
158
|
-
.image(spec.image)
|
|
159
|
-
.cpus(spec.cpus)
|
|
160
|
-
.memory(spec.memoryMiB)
|
|
161
|
-
.patch((patch) => patch.mkdir(SANDBOX_WORKSPACE, { mode: 0o755 }))
|
|
162
|
-
.workdir(SANDBOX_WORKSPACE)
|
|
163
|
-
.label("nylorun", "sandbox")
|
|
164
|
-
.network((network) => network.policy(policyFor(msb, spec)))
|
|
165
|
-
.create();
|
|
166
|
-
return handleFor(sandbox);
|
|
167
|
-
},
|
|
168
|
-
async remove(key) {
|
|
169
|
-
const { Sandbox, SandboxNotFoundError } = await load();
|
|
170
|
-
try {
|
|
171
|
-
const handle = await Sandbox.get(key);
|
|
172
|
-
await handle.destroy({ force: true });
|
|
173
|
-
}
|
|
174
|
-
catch (error) {
|
|
175
|
-
if (!(error instanceof SandboxNotFoundError))
|
|
176
|
-
throw error;
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
async list(prefix) {
|
|
180
|
-
const { Sandbox } = await load();
|
|
181
|
-
const keys = [];
|
|
182
|
-
let page = await Sandbox.list();
|
|
183
|
-
for (;;) {
|
|
184
|
-
for (const handle of page.sandboxes)
|
|
185
|
-
if (handle.name.startsWith(prefix))
|
|
186
|
-
keys.push(handle.name);
|
|
187
|
-
if (!page.nextCursor)
|
|
188
|
-
break;
|
|
189
|
-
const cursor = page.nextCursor;
|
|
190
|
-
page = await Sandbox.listWith((list) => list.cursor(cursor));
|
|
191
|
-
}
|
|
192
|
-
return keys;
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
/** Deny by default. Private, loopback, link-local, metadata and host ranges are always denied. */
|
|
197
|
-
function policyFor(msb, spec) {
|
|
198
|
-
const { Destination, Rule } = msb;
|
|
199
|
-
const always = ["private", "loopback", "link-local", "metadata", "multicast"];
|
|
200
|
-
// The host is denied for TCP only: its resolver answers DNS for the sandbox and filters
|
|
201
|
-
// names by this same policy, so a UDP deny would break every allowed host.
|
|
202
|
-
const host = {
|
|
203
|
-
direction: "egress",
|
|
204
|
-
destination: Destination.group("host"),
|
|
205
|
-
protocols: ["tcp"],
|
|
206
|
-
ports: [],
|
|
207
|
-
action: "deny",
|
|
208
|
-
};
|
|
209
|
-
return {
|
|
210
|
-
defaultEgress: "deny",
|
|
211
|
-
defaultIngress: "deny",
|
|
212
|
-
rules: [
|
|
213
|
-
...always.map((group) => Rule.denyEgress(Destination.group(group))),
|
|
214
|
-
host,
|
|
215
|
-
...(spec.network.preset === "open" ? [Rule.allowEgress(Destination.group("public"))] : []),
|
|
216
|
-
...spec.network.hosts.map((host) => Rule.allowEgress(Destination.domain(host))),
|
|
217
|
-
...spec.network.suffixes.map((suffix) => Rule.allowEgress(Destination.domainSuffix(suffix))),
|
|
218
|
-
],
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
class Capture {
|
|
222
|
-
chunks = [];
|
|
223
|
-
size = 0;
|
|
224
|
-
dropped = 0;
|
|
225
|
-
push(data) {
|
|
226
|
-
const chunk = typeof data === "string" ? Buffer.from(data) : Buffer.from(data);
|
|
227
|
-
if (this.size >= CAPTURE_LIMIT) {
|
|
228
|
-
this.dropped += chunk.length;
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
this.chunks.push(chunk);
|
|
232
|
-
this.size += chunk.length;
|
|
233
|
-
}
|
|
234
|
-
text() {
|
|
235
|
-
const text = Buffer.concat(this.chunks).toString("utf8");
|
|
236
|
-
return this.dropped > 0 ? `${text}\n… [${this.dropped} bytes not captured]` : text;
|
|
237
|
-
}
|
|
238
|
-
}
|
package/dist/core/main.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { startRuntime } from "./runtime.js";
|
|
2
|
-
import { gatewayModel, scriptedModel, toolFixtureModel } from "./provider.js";
|
|
3
|
-
const serverToken = process.env.NYLORUN_SERVER_KEY;
|
|
4
|
-
if (!serverToken)
|
|
5
|
-
throw new Error("Set NYLORUN_SERVER_KEY (at least 16 characters)");
|
|
6
|
-
const executors = JSON.parse(process.env.NYLORUN_EXECUTORS_JSON ?? "[]");
|
|
7
|
-
const useHostModel = process.env.NYLORUN_DEV_MODEL !== "fixture" &&
|
|
8
|
-
process.env.NYLORUN_PROJECT_PROVIDER === "1";
|
|
9
|
-
const model = useHostModel
|
|
10
|
-
? undefined
|
|
11
|
-
: process.env.NYLORUN_DEV_MODEL === "fixture"
|
|
12
|
-
? toolFixtureModel()
|
|
13
|
-
: process.env.NYLORUN_MODEL_GATEWAY_URL
|
|
14
|
-
? gatewayModel({
|
|
15
|
-
url: process.env.NYLORUN_MODEL_GATEWAY_URL,
|
|
16
|
-
token: process.env.NYLORUN_MODEL_GATEWAY_KEY ?? "",
|
|
17
|
-
model: process.env.NYLORUN_MODEL ?? "",
|
|
18
|
-
})
|
|
19
|
-
: scriptedModel(process.env.NYLORUN_SCRIPTED_OUTPUT);
|
|
20
|
-
const runtime = await startRuntime({
|
|
21
|
-
sqlitePath: process.env.NYLORUN_SQLITE_PATH ?? "./nylorun.sqlite",
|
|
22
|
-
serverToken,
|
|
23
|
-
executors,
|
|
24
|
-
model,
|
|
25
|
-
useHostModel,
|
|
26
|
-
port: Number(process.env.PORT ?? 8787),
|
|
27
|
-
hostname: process.env.HOST ?? "127.0.0.1",
|
|
28
|
-
});
|
|
29
|
-
console.log(`Nylorun Runtime listening at ${runtime.url}`);
|
|
30
|
-
process.send?.({ type: "ready", url: runtime.url });
|
|
31
|
-
let closing;
|
|
32
|
-
for (const signal of ["SIGINT", "SIGTERM"])
|
|
33
|
-
process.on(signal, () => {
|
|
34
|
-
closing ??= runtime.close().then(() => { process.exit(0); });
|
|
35
|
-
});
|
package/dist/core/store.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { DatabaseSync } from "node:sqlite";
|
|
2
|
-
import type { LiveEvent } from "@nylorun/core/contracts";
|
|
3
|
-
export declare function canonical(value: unknown): string;
|
|
4
|
-
export interface ExecutorRow {
|
|
5
|
-
agentId: string;
|
|
6
|
-
tokenHash: string;
|
|
7
|
-
implementationVersion: string;
|
|
8
|
-
manifestHash?: string;
|
|
9
|
-
createdAt: string;
|
|
10
|
-
updatedAt: string;
|
|
11
|
-
}
|
|
12
|
-
export declare class Store {
|
|
13
|
-
readonly db: DatabaseSync;
|
|
14
|
-
constructor(path: string);
|
|
15
|
-
tx<T>(fn: () => T): T;
|
|
16
|
-
get<T = any>(table: string, id: string): T | undefined;
|
|
17
|
-
all<T = any>(table: string): T[];
|
|
18
|
-
put(table: string, id: string, body: unknown): void;
|
|
19
|
-
delete(table: string, id: string): void;
|
|
20
|
-
allExecutors(): ExecutorRow[];
|
|
21
|
-
putExecutor(row: Omit<ExecutorRow, "createdAt">): void;
|
|
22
|
-
deleteExecutor(agentId: string): void;
|
|
23
|
-
event(sessionId: string, turnId: string | null, type: string, payload: unknown): LiveEvent;
|
|
24
|
-
credentialCount(): number;
|
|
25
|
-
/** `agent` keeps only events of one agent used as a tool, by delegationId or path. */
|
|
26
|
-
history(sessionId: string, cursor?: string, agent?: string): {
|
|
27
|
-
items: LiveEvent[];
|
|
28
|
-
cursor: string | null;
|
|
29
|
-
};
|
|
30
|
-
}
|
package/dist/core/store.js
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { DatabaseSync } from "node:sqlite";
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
3
|
-
export function canonical(value) {
|
|
4
|
-
if (Array.isArray(value))
|
|
5
|
-
return "[" + value.map(canonical).join(",") + "]";
|
|
6
|
-
if (value && typeof value === "object")
|
|
7
|
-
return ("{" +
|
|
8
|
-
Object.keys(value)
|
|
9
|
-
.sort()
|
|
10
|
-
.filter((k) => value[k] !== undefined)
|
|
11
|
-
.map((k) => JSON.stringify(k) + ":" + canonical(value[k]))
|
|
12
|
-
.join(",") +
|
|
13
|
-
"}");
|
|
14
|
-
return JSON.stringify(value) ?? "null";
|
|
15
|
-
}
|
|
16
|
-
export class Store {
|
|
17
|
-
db;
|
|
18
|
-
constructor(path) {
|
|
19
|
-
this.db = new DatabaseSync(path);
|
|
20
|
-
this.db
|
|
21
|
-
.exec(`PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON; PRAGMA busy_timeout=5000;
|
|
22
|
-
CREATE TABLE IF NOT EXISTS definitions(id TEXT PRIMARY KEY, body TEXT NOT NULL);
|
|
23
|
-
CREATE TABLE IF NOT EXISTS sessions(id TEXT PRIMARY KEY, body TEXT NOT NULL);
|
|
24
|
-
CREATE TABLE IF NOT EXISTS commands(id TEXT PRIMARY KEY, body TEXT NOT NULL);
|
|
25
|
-
CREATE TABLE IF NOT EXISTS checkpoints(id TEXT PRIMARY KEY, body TEXT NOT NULL);
|
|
26
|
-
CREATE TABLE IF NOT EXISTS effects(id TEXT PRIMARY KEY, body TEXT NOT NULL);
|
|
27
|
-
CREATE TABLE IF NOT EXISTS actions(id TEXT PRIMARY KEY, body TEXT NOT NULL);
|
|
28
|
-
CREATE TABLE IF NOT EXISTS sandboxes(id TEXT PRIMARY KEY, body TEXT NOT NULL);
|
|
29
|
-
CREATE TABLE IF NOT EXISTS events(sequence INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL, body TEXT NOT NULL);
|
|
30
|
-
CREATE INDEX IF NOT EXISTS events_session ON events(session_id, sequence);
|
|
31
|
-
CREATE TABLE IF NOT EXISTS vaults(
|
|
32
|
-
id TEXT PRIMARY KEY,
|
|
33
|
-
name TEXT NOT NULL,
|
|
34
|
-
owner_user_id TEXT NOT NULL,
|
|
35
|
-
metadata_json TEXT,
|
|
36
|
-
created_at TEXT NOT NULL,
|
|
37
|
-
scope TEXT NOT NULL DEFAULT 'user'
|
|
38
|
-
);
|
|
39
|
-
CREATE INDEX IF NOT EXISTS vaults_owner ON vaults(owner_user_id);
|
|
40
|
-
CREATE TABLE IF NOT EXISTS vault_credentials(
|
|
41
|
-
id TEXT PRIMARY KEY,
|
|
42
|
-
vault_id TEXT NOT NULL REFERENCES vaults(id) ON DELETE CASCADE,
|
|
43
|
-
name TEXT NOT NULL,
|
|
44
|
-
type TEXT NOT NULL,
|
|
45
|
-
binding_json TEXT NOT NULL,
|
|
46
|
-
expires_at TEXT,
|
|
47
|
-
created_at TEXT NOT NULL,
|
|
48
|
-
rotated_at TEXT,
|
|
49
|
-
kek_id TEXT NOT NULL,
|
|
50
|
-
nonce BLOB NOT NULL,
|
|
51
|
-
ciphertext BLOB NOT NULL,
|
|
52
|
-
wrapped_dek BLOB NOT NULL
|
|
53
|
-
);
|
|
54
|
-
CREATE INDEX IF NOT EXISTS vault_credentials_vault ON vault_credentials(vault_id);
|
|
55
|
-
CREATE TABLE IF NOT EXISTS vault_audit(
|
|
56
|
-
id TEXT PRIMARY KEY,
|
|
57
|
-
at TEXT NOT NULL,
|
|
58
|
-
actor TEXT NOT NULL,
|
|
59
|
-
action TEXT NOT NULL,
|
|
60
|
-
vault_id TEXT,
|
|
61
|
-
credential_id TEXT,
|
|
62
|
-
session_id TEXT,
|
|
63
|
-
target TEXT,
|
|
64
|
-
outcome TEXT NOT NULL
|
|
65
|
-
);
|
|
66
|
-
CREATE TABLE IF NOT EXISTS vault_idempotency(
|
|
67
|
-
id TEXT PRIMARY KEY,
|
|
68
|
-
body_hash TEXT NOT NULL,
|
|
69
|
-
response TEXT NOT NULL
|
|
70
|
-
);
|
|
71
|
-
CREATE TABLE IF NOT EXISTS executors(
|
|
72
|
-
agent_id TEXT PRIMARY KEY,
|
|
73
|
-
token_hash TEXT NOT NULL UNIQUE,
|
|
74
|
-
implementation_version TEXT NOT NULL,
|
|
75
|
-
manifest_hash TEXT,
|
|
76
|
-
created_at TEXT NOT NULL,
|
|
77
|
-
updated_at TEXT NOT NULL
|
|
78
|
-
);`);
|
|
79
|
-
migrateVaultScope(this.db);
|
|
80
|
-
}
|
|
81
|
-
tx(fn) {
|
|
82
|
-
this.db.exec("BEGIN IMMEDIATE");
|
|
83
|
-
try {
|
|
84
|
-
const result = fn();
|
|
85
|
-
this.db.exec("COMMIT");
|
|
86
|
-
return result;
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
this.db.exec("ROLLBACK");
|
|
90
|
-
throw e;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
get(table, id) {
|
|
94
|
-
const row = this.db.prepare(`SELECT body FROM ${table} WHERE id=?`).get(id);
|
|
95
|
-
return row ? JSON.parse(String(row.body)) : undefined;
|
|
96
|
-
}
|
|
97
|
-
all(table) {
|
|
98
|
-
return this.db
|
|
99
|
-
.prepare(`SELECT body FROM ${table}`)
|
|
100
|
-
.all()
|
|
101
|
-
.map((r) => JSON.parse(String(r.body)));
|
|
102
|
-
}
|
|
103
|
-
put(table, id, body) {
|
|
104
|
-
this.db
|
|
105
|
-
.prepare(`INSERT INTO ${table}(id,body) VALUES(?,?) ON CONFLICT(id) DO UPDATE SET body=excluded.body`)
|
|
106
|
-
.run(id, JSON.stringify(body));
|
|
107
|
-
}
|
|
108
|
-
delete(table, id) {
|
|
109
|
-
this.db.prepare(`DELETE FROM ${table} WHERE id=?`).run(id);
|
|
110
|
-
}
|
|
111
|
-
// Executors carry a bearer secret, so they use typed columns with a database-enforced unique
|
|
112
|
-
// token hash instead of flowing through the generic JSON document helpers above.
|
|
113
|
-
allExecutors() {
|
|
114
|
-
return this.db
|
|
115
|
-
.prepare("SELECT agent_id,token_hash,implementation_version,manifest_hash,created_at,updated_at FROM executors")
|
|
116
|
-
.all()
|
|
117
|
-
.map((r) => ({
|
|
118
|
-
agentId: String(r.agent_id),
|
|
119
|
-
tokenHash: String(r.token_hash),
|
|
120
|
-
implementationVersion: String(r.implementation_version),
|
|
121
|
-
manifestHash: r.manifest_hash == null ? undefined : String(r.manifest_hash),
|
|
122
|
-
createdAt: String(r.created_at),
|
|
123
|
-
updatedAt: String(r.updated_at),
|
|
124
|
-
}));
|
|
125
|
-
}
|
|
126
|
-
putExecutor(row) {
|
|
127
|
-
this.db
|
|
128
|
-
.prepare(`INSERT INTO executors(agent_id,token_hash,implementation_version,manifest_hash,created_at,updated_at)
|
|
129
|
-
VALUES(?,?,?,?,?,?)
|
|
130
|
-
ON CONFLICT(agent_id) DO UPDATE SET
|
|
131
|
-
token_hash=excluded.token_hash,
|
|
132
|
-
implementation_version=excluded.implementation_version,
|
|
133
|
-
manifest_hash=excluded.manifest_hash,
|
|
134
|
-
updated_at=excluded.updated_at`)
|
|
135
|
-
.run(row.agentId, row.tokenHash, row.implementationVersion, row.manifestHash ?? null, row.updatedAt, row.updatedAt);
|
|
136
|
-
}
|
|
137
|
-
deleteExecutor(agentId) {
|
|
138
|
-
this.db.prepare("DELETE FROM executors WHERE agent_id=?").run(agentId);
|
|
139
|
-
}
|
|
140
|
-
event(sessionId, turnId, type, payload) {
|
|
141
|
-
const base = {
|
|
142
|
-
eventId: randomUUID(),
|
|
143
|
-
sessionId,
|
|
144
|
-
turnId,
|
|
145
|
-
createdAt: new Date().toISOString(),
|
|
146
|
-
type,
|
|
147
|
-
payload,
|
|
148
|
-
};
|
|
149
|
-
const result = this.db
|
|
150
|
-
.prepare("INSERT INTO events(session_id,body) VALUES(?,?)")
|
|
151
|
-
.run(sessionId, "{}");
|
|
152
|
-
const event = {
|
|
153
|
-
...base,
|
|
154
|
-
cursor: Buffer.from(`${sessionId}:${result.lastInsertRowid}`).toString("base64url"),
|
|
155
|
-
};
|
|
156
|
-
this.db
|
|
157
|
-
.prepare("UPDATE events SET body=? WHERE sequence=?")
|
|
158
|
-
.run(JSON.stringify(event), result.lastInsertRowid);
|
|
159
|
-
return event;
|
|
160
|
-
}
|
|
161
|
-
credentialCount() {
|
|
162
|
-
const row = this.db
|
|
163
|
-
.prepare("SELECT COUNT(*) AS n FROM vault_credentials")
|
|
164
|
-
.get();
|
|
165
|
-
return Number(row.n);
|
|
166
|
-
}
|
|
167
|
-
/** `agent` keeps only events of one agent used as a tool, by delegationId or path. */
|
|
168
|
-
history(sessionId, cursor, agent) {
|
|
169
|
-
let sequence = 0;
|
|
170
|
-
if (cursor) {
|
|
171
|
-
const decoded = Buffer.from(cursor, "base64url").toString();
|
|
172
|
-
const prefix = `${sessionId}:`;
|
|
173
|
-
if (!decoded.startsWith(prefix) ||
|
|
174
|
-
!/^\d+$/.test(decoded.slice(prefix.length)))
|
|
175
|
-
throw new Error("Invalid cursor");
|
|
176
|
-
sequence = Number(decoded.slice(prefix.length));
|
|
177
|
-
}
|
|
178
|
-
const items = this.db
|
|
179
|
-
.prepare("SELECT body FROM events WHERE session_id=? AND sequence>? ORDER BY sequence")
|
|
180
|
-
.all(sessionId, sequence)
|
|
181
|
-
.map((r) => JSON.parse(String(r.body)))
|
|
182
|
-
.filter((event) => agent === undefined || belongsTo(event, agent));
|
|
183
|
-
const last = this.db
|
|
184
|
-
.prepare("SELECT body FROM events WHERE session_id=? ORDER BY sequence DESC LIMIT 1")
|
|
185
|
-
.get(sessionId);
|
|
186
|
-
return {
|
|
187
|
-
items,
|
|
188
|
-
cursor: last ? JSON.parse(String(last.body)).cursor : null,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
function belongsTo(event, agent) {
|
|
193
|
-
const ref = event.payload
|
|
194
|
-
?.agent;
|
|
195
|
-
return ref?.delegationId === agent || ref?.path === agent;
|
|
196
|
-
}
|
|
197
|
-
function migrateVaultScope(db) {
|
|
198
|
-
const columns = db.prepare("PRAGMA table_info(vaults)").all();
|
|
199
|
-
if (!columns.some((column) => column.name === "scope"))
|
|
200
|
-
db.exec("ALTER TABLE vaults ADD COLUMN scope TEXT NOT NULL DEFAULT 'user'");
|
|
201
|
-
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS vaults_one_host ON vaults(scope) WHERE scope = 'host'");
|
|
202
|
-
}
|
|
File without changes
|