@nylorun/runtime 0.10.0-beta → 0.12.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 (194) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +53 -51
  3. package/dist/adapters/execution/restate.d.ts +130 -0
  4. package/dist/adapters/execution/restate.js +442 -0
  5. package/dist/adapters/sandbox/virtual.js +1 -1
  6. package/dist/adapters/streams/s2.d.ts +18 -0
  7. package/dist/adapters/streams/s2.js +361 -0
  8. package/dist/core/executors.d.ts +4 -1
  9. package/dist/core/executors.js +20 -1
  10. package/dist/core/flow-host.d.ts +93 -132
  11. package/dist/core/flow-host.js +282 -547
  12. package/dist/core/sandbox-routes.d.ts +13 -4
  13. package/dist/core/sandbox-routes.js +14 -12
  14. package/dist/execution/memory.d.ts +54 -0
  15. package/dist/execution/memory.js +217 -0
  16. package/dist/execution/types.d.ts +125 -0
  17. package/dist/execution/types.js +52 -0
  18. package/dist/host/config-for.d.ts +2 -1
  19. package/dist/host/config-for.js +3 -21
  20. package/dist/host/config.d.ts +0 -8
  21. package/dist/host/create-host.d.ts +36 -1
  22. package/dist/host/create-host.js +51 -24
  23. package/dist/host/execution.d.ts +61 -0
  24. package/dist/host/execution.js +69 -0
  25. package/dist/host/http.d.ts +4 -0
  26. package/dist/host/http.js +6 -0
  27. package/dist/host/index.d.ts +3 -1
  28. package/dist/host/index.js +2 -0
  29. package/dist/host/main.js +106 -47
  30. package/dist/host/stack-config.d.ts +72 -0
  31. package/dist/host/stack-config.js +193 -0
  32. package/dist/index.d.ts +1 -1
  33. package/dist/infra/database.d.ts +16 -0
  34. package/dist/infra/database.js +31 -0
  35. package/dist/infra/execution.d.ts +39 -0
  36. package/dist/infra/execution.js +68 -0
  37. package/dist/infra/index.d.ts +42 -0
  38. package/dist/infra/index.js +56 -0
  39. package/dist/infra/readiness.d.ts +33 -0
  40. package/dist/infra/readiness.js +53 -0
  41. package/dist/infra/streams.d.ts +17 -0
  42. package/dist/infra/streams.js +33 -0
  43. package/dist/infra/workers.d.ts +39 -0
  44. package/dist/infra/workers.js +31 -0
  45. package/dist/model/pi-model.d.ts +2 -2
  46. package/dist/model/pi-model.js +5 -5
  47. package/dist/sandbox/manager.d.ts +26 -8
  48. package/dist/sandbox/manager.js +95 -47
  49. package/dist/sandbox/select.d.ts +1 -1
  50. package/dist/sandbox/select.js +4 -5
  51. package/dist/sandbox/types.d.ts +2 -2
  52. package/dist/store/canonical.d.ts +5 -0
  53. package/dist/store/canonical.js +17 -0
  54. package/dist/store/cursor.d.ts +9 -0
  55. package/dist/store/cursor.js +18 -0
  56. package/dist/store/memory.d.ts +57 -0
  57. package/dist/store/memory.js +645 -0
  58. package/dist/store/ownership.d.ts +19 -0
  59. package/dist/store/ownership.js +33 -0
  60. package/dist/store/postgres/connect.d.ts +25 -0
  61. package/dist/store/postgres/connect.js +25 -0
  62. package/dist/store/postgres/locking.d.ts +16 -0
  63. package/dist/store/postgres/locking.js +22 -0
  64. package/dist/store/postgres/migrations/001_initial.d.ts +27 -0
  65. package/dist/store/postgres/migrations/001_initial.js +196 -0
  66. package/dist/store/postgres/migrations/002_session_owner.d.ts +6 -0
  67. package/dist/store/postgres/migrations/002_session_owner.js +13 -0
  68. package/dist/store/postgres/migrations/index.d.ts +49 -0
  69. package/dist/store/postgres/migrations/index.js +76 -0
  70. package/dist/store/postgres/names.d.ts +11 -0
  71. package/dist/store/postgres/names.js +42 -0
  72. package/dist/store/postgres/store.d.ts +11 -0
  73. package/dist/store/postgres/store.js +797 -0
  74. package/dist/store/postgres/tenants.d.ts +90 -0
  75. package/dist/store/postgres/tenants.js +214 -0
  76. package/dist/store/types.d.ts +442 -0
  77. package/dist/store/types.js +10 -0
  78. package/dist/streams/basin.d.ts +23 -0
  79. package/dist/streams/basin.js +51 -0
  80. package/dist/streams/memory.d.ts +25 -0
  81. package/dist/streams/memory.js +124 -0
  82. package/dist/streams/relay.d.ts +37 -0
  83. package/dist/streams/relay.js +254 -0
  84. package/dist/streams/types.d.ts +115 -0
  85. package/dist/streams/types.js +86 -0
  86. package/dist/tenant/actions.d.ts +153 -0
  87. package/dist/tenant/actions.js +191 -0
  88. package/dist/tenant/advance.d.ts +15 -0
  89. package/dist/tenant/advance.js +439 -0
  90. package/dist/tenant/auth.d.ts +32 -0
  91. package/dist/tenant/auth.js +169 -0
  92. package/dist/tenant/commands.d.ts +3 -0
  93. package/dist/tenant/commands.js +393 -0
  94. package/dist/tenant/context.d.ts +147 -0
  95. package/dist/tenant/context.js +48 -0
  96. package/dist/tenant/effects.d.ts +20 -0
  97. package/dist/tenant/effects.js +564 -0
  98. package/dist/tenant/envelope.d.ts +0 -3
  99. package/dist/tenant/envelope.js +2 -34
  100. package/dist/tenant/ephemeral.d.ts +15 -4
  101. package/dist/tenant/ephemeral.js +106 -38
  102. package/dist/tenant/http.d.ts +38 -0
  103. package/dist/tenant/http.js +53 -0
  104. package/dist/tenant/live.d.ts +92 -0
  105. package/dist/tenant/live.js +290 -0
  106. package/dist/tenant/model-setting.d.ts +16 -0
  107. package/dist/tenant/model-setting.js +12 -0
  108. package/dist/tenant/module.d.ts +29 -8
  109. package/dist/tenant/module.js +165 -158
  110. package/dist/tenant/paths.d.ts +12 -8
  111. package/dist/tenant/paths.js +38 -12
  112. package/dist/tenant/principals.d.ts +12 -13
  113. package/dist/tenant/principals.js +50 -38
  114. package/dist/tenant/quarantine-error.d.ts +1 -1
  115. package/dist/tenant/quarantine-error.js +2 -8
  116. package/dist/tenant/quarantine.d.ts +0 -8
  117. package/dist/tenant/quarantine.js +8 -30
  118. package/dist/tenant/reset.d.ts +7 -6
  119. package/dist/tenant/reset.js +7 -51
  120. package/dist/tenant/routes-tenant.d.ts +12 -0
  121. package/dist/tenant/routes-tenant.js +137 -0
  122. package/dist/tenant/routes.d.ts +9 -0
  123. package/dist/tenant/routes.js +151 -0
  124. package/dist/tenant/runtime.d.ts +59 -58
  125. package/dist/tenant/runtime.js +243 -2201
  126. package/dist/tenant/scheduler.d.ts +25 -0
  127. package/dist/tenant/scheduler.js +84 -0
  128. package/dist/tenant/session.d.ts +60 -0
  129. package/dist/tenant/session.js +94 -0
  130. package/dist/tenant/sessions.d.ts +40 -0
  131. package/dist/tenant/sessions.js +163 -0
  132. package/dist/tenant/status.d.ts +13 -4
  133. package/dist/tenant/status.js +76 -41
  134. package/dist/tenant/store-memory.d.ts +9 -12
  135. package/dist/tenant/store-memory.js +79 -68
  136. package/dist/tenant/store-pg.d.ts +15 -0
  137. package/dist/tenant/store-pg.js +140 -0
  138. package/dist/tenant/streams.d.ts +126 -0
  139. package/dist/tenant/streams.js +419 -0
  140. package/dist/tenant/sweep.d.ts +15 -0
  141. package/dist/tenant/sweep.js +122 -0
  142. package/dist/tenant/transcript.d.ts +104 -0
  143. package/dist/tenant/transcript.js +58 -0
  144. package/dist/tenant/types.d.ts +101 -15
  145. package/dist/tenant/types.js +23 -1
  146. package/dist/tenant/worker.d.ts +84 -0
  147. package/dist/tenant/worker.js +189 -0
  148. package/dist/vault/service.d.ts +44 -31
  149. package/dist/vault/service.js +454 -360
  150. package/dist/version.d.ts +1 -1
  151. package/dist/version.js +1 -1
  152. package/package.json +15 -14
  153. package/dist/adapters/sandbox/microsandbox.d.ts +0 -2
  154. package/dist/adapters/sandbox/microsandbox.js +0 -238
  155. package/dist/core/store.d.ts +0 -32
  156. package/dist/core/store.js +0 -143
  157. package/dist/launcher/commands.d.ts +0 -24
  158. package/dist/launcher/commands.js +0 -260
  159. package/dist/launcher/ensure-config.d.ts +0 -16
  160. package/dist/launcher/ensure-config.js +0 -79
  161. package/dist/launcher/errors.d.ts +0 -12
  162. package/dist/launcher/errors.js +0 -22
  163. package/dist/launcher/host-config.d.ts +0 -17
  164. package/dist/launcher/host-config.js +0 -64
  165. package/dist/launcher/host-state.d.ts +0 -17
  166. package/dist/launcher/host-state.js +0 -61
  167. package/dist/launcher/lifecycle.d.ts +0 -66
  168. package/dist/launcher/lifecycle.js +0 -407
  169. package/dist/launcher/locks.d.ts +0 -26
  170. package/dist/launcher/locks.js +0 -117
  171. package/dist/launcher/logs.d.ts +0 -18
  172. package/dist/launcher/logs.js +0 -117
  173. package/dist/launcher/main.d.ts +0 -2
  174. package/dist/launcher/main.js +0 -66
  175. package/dist/launcher/output.d.ts +0 -11
  176. package/dist/launcher/output.js +0 -68
  177. package/dist/launcher/paths.d.ts +0 -20
  178. package/dist/launcher/paths.js +0 -36
  179. package/dist/launcher/probe.d.ts +0 -23
  180. package/dist/launcher/probe.js +0 -72
  181. package/dist/launcher/protocol.d.ts +0 -62
  182. package/dist/launcher/protocol.js +0 -1
  183. package/dist/launcher/schema-guard.d.ts +0 -6
  184. package/dist/launcher/schema-guard.js +0 -36
  185. package/dist/launcher/spawn.d.ts +0 -22
  186. package/dist/launcher/spawn.js +0 -85
  187. package/dist/launcher/status.d.ts +0 -6
  188. package/dist/launcher/status.js +0 -65
  189. package/dist/tenant/migration.d.ts +0 -16
  190. package/dist/tenant/migration.js +0 -116
  191. package/dist/tenant/schema.d.ts +0 -23
  192. package/dist/tenant/schema.js +0 -151
  193. package/dist/tenant/store-fs.d.ts +0 -16
  194. package/dist/tenant/store-fs.js +0 -205
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const RUNTIME_VERSION = "0.10.0-beta";
1
+ export declare const RUNTIME_VERSION = "0.12.0-beta";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Kept in step with package.json by runtime/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.10.0-beta";
3
+ export const RUNTIME_VERSION = "0.12.0-beta";
package/package.json CHANGED
@@ -1,20 +1,17 @@
1
1
  {
2
2
  "name": "@nylorun/runtime",
3
- "version": "0.10.0-beta",
4
- "description": "SQLite agent execution host and model providers.",
3
+ "version": "0.12.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": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/nylorun/harness.git",
9
+ "url": "git+https://github.com/nylorun/agents.git",
10
10
  "directory": "runtime"
11
11
  },
12
12
  "engines": {
13
13
  "node": ">=24.0.0"
14
14
  },
15
- "bin": {
16
- "nylorun-runtime": "dist/launcher/main.js"
17
- },
18
15
  "exports": {
19
16
  ".": {
20
17
  "types": "./dist/index.d.ts",
@@ -46,26 +43,30 @@
46
43
  "provenance": true
47
44
  },
48
45
  "scripts": {
49
- "build": "npm run clean && node ../scripts/check-typescript-version.mjs && tsc -p tsconfig.json && node -e \"require('node:fs').chmodSync('dist/launcher/main.js', 0o755)\"",
46
+ "build": "npm run clean && node ../scripts/check-typescript-version.mjs && tsc -p tsconfig.json",
50
47
  "check": "npm run build && npm test && node scripts/check-package.mjs",
51
48
  "typecheck": "node ../scripts/check-typescript-version.mjs && tsc -p tsconfig.json --noEmit",
52
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",
53
53
  "prepack": "npm run build",
54
54
  "clean": "node -e \"import('node:fs').then(({rmSync})=>rmSync('dist',{recursive:true,force:true}))\"",
55
55
  "start": "node dist/host/main.js"
56
56
  },
57
57
  "dependencies": {
58
58
  "@modelcontextprotocol/sdk": "^1.30.0",
59
- "@earendil-works/pi-ai": "0.85.1",
59
+ "@earendil-works/pi-ai": "0.87.0",
60
60
  "@hono/node-server": "^2.1.1",
61
- "@nylorun/harness": "0.19.0-beta",
62
- "@nylorun/core": "0.5.0-beta",
63
- "just-bash": "3.4.2"
64
- },
65
- "optionalDependencies": {
66
- "microsandbox": "0.7.2"
61
+ "@nylorun/harness": "0.19.2-beta",
62
+ "@nylorun/core": "0.7.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"
67
67
  },
68
68
  "devDependencies": {
69
+ "@ag-ui/client": "1.0.0",
69
70
  "@types/node": "^26.5.0",
70
71
  "@typescript/native": "npm:typescript@^7.0.2",
71
72
  "hono": "^4.13.8",
@@ -1,2 +0,0 @@
1
- import type { SandboxBackend } from "../../sandbox/types.js";
2
- export declare function microsandboxBackend(): SandboxBackend;
@@ -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
- }
@@ -1,32 +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
- principalId?: string;
10
- createdAt: string;
11
- updatedAt: string;
12
- }
13
- export declare class Store {
14
- private readonly tenantId;
15
- readonly db: DatabaseSync;
16
- constructor(path: string, tenantId: string);
17
- tx<T>(fn: () => T): T;
18
- get<T = any>(table: string, id: string): T | undefined;
19
- all<T = any>(table: string): T[];
20
- put(table: string, id: string, body: unknown): void;
21
- delete(table: string, id: string): void;
22
- allExecutors(): ExecutorRow[];
23
- putExecutor(row: Omit<ExecutorRow, "createdAt">): void;
24
- deleteExecutor(agentId: string): void;
25
- event(sessionId: string, turnId: string | null, type: string, payload: unknown): LiveEvent;
26
- credentialCount(): number;
27
- /** `agent` keeps only events of one agent used as a tool, by delegationId or path. */
28
- history(sessionId: string, cursor?: string, agent?: string): {
29
- items: LiveEvent[];
30
- cursor: string | null;
31
- };
32
- }
@@ -1,143 +0,0 @@
1
- import { DatabaseSync } from "node:sqlite";
2
- import { randomUUID } from "node:crypto";
3
- import { migrateTenantDatabase } from "../tenant/schema.js";
4
- export function canonical(value) {
5
- if (Array.isArray(value))
6
- return "[" + value.map(canonical).join(",") + "]";
7
- if (value && typeof value === "object")
8
- return ("{" +
9
- Object.keys(value)
10
- .sort()
11
- .filter((k) => value[k] !== undefined)
12
- .map((k) => JSON.stringify(k) + ":" + canonical(value[k]))
13
- .join(",") +
14
- "}");
15
- return JSON.stringify(value) ?? "null";
16
- }
17
- export class Store {
18
- tenantId;
19
- db;
20
- constructor(path, tenantId) {
21
- this.tenantId = tenantId;
22
- this.db = new DatabaseSync(path);
23
- this.db.exec(`PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON; PRAGMA busy_timeout=5000;`);
24
- migrateTenantDatabase(this.db);
25
- }
26
- tx(fn) {
27
- this.db.exec("BEGIN IMMEDIATE");
28
- try {
29
- const result = fn();
30
- this.db.exec("COMMIT");
31
- return result;
32
- }
33
- catch (e) {
34
- this.db.exec("ROLLBACK");
35
- throw e;
36
- }
37
- }
38
- get(table, id) {
39
- const row = this.db.prepare(`SELECT body FROM ${table} WHERE id=?`).get(id);
40
- return row ? JSON.parse(String(row.body)) : undefined;
41
- }
42
- all(table) {
43
- return this.db
44
- .prepare(`SELECT body FROM ${table}`)
45
- .all()
46
- .map((r) => JSON.parse(String(r.body)));
47
- }
48
- put(table, id, body) {
49
- this.db
50
- .prepare(`INSERT INTO ${table}(id,body) VALUES(?,?) ON CONFLICT(id) DO UPDATE SET body=excluded.body`)
51
- .run(id, JSON.stringify(body));
52
- }
53
- delete(table, id) {
54
- this.db.prepare(`DELETE FROM ${table} WHERE id=?`).run(id);
55
- }
56
- // Executors carry a bearer secret, so they use typed columns with a database-enforced unique
57
- // token hash instead of flowing through the generic JSON document helpers above.
58
- allExecutors() {
59
- return this.db
60
- .prepare("SELECT agent_id,token_hash,implementation_version,manifest_hash,principal_id,created_at,updated_at FROM executors")
61
- .all()
62
- .map((r) => ({
63
- agentId: String(r.agent_id),
64
- tokenHash: String(r.token_hash),
65
- implementationVersion: String(r.implementation_version),
66
- manifestHash: r.manifest_hash == null ? undefined : String(r.manifest_hash),
67
- principalId: r.principal_id == null ? undefined : String(r.principal_id),
68
- createdAt: String(r.created_at),
69
- updatedAt: String(r.updated_at),
70
- }));
71
- }
72
- putExecutor(row) {
73
- this.db
74
- .prepare(`INSERT INTO executors(agent_id,token_hash,implementation_version,manifest_hash,principal_id,created_at,updated_at)
75
- VALUES(?,?,?,?,?,?,?)
76
- ON CONFLICT(agent_id) DO UPDATE SET
77
- token_hash=excluded.token_hash,
78
- implementation_version=excluded.implementation_version,
79
- manifest_hash=excluded.manifest_hash,
80
- principal_id=excluded.principal_id,
81
- updated_at=excluded.updated_at`)
82
- .run(row.agentId, row.tokenHash, row.implementationVersion, row.manifestHash ?? null, row.principalId ?? null, row.updatedAt, row.updatedAt);
83
- }
84
- deleteExecutor(agentId) {
85
- this.db.prepare("DELETE FROM executors WHERE agent_id=?").run(agentId);
86
- }
87
- event(sessionId, turnId, type, payload) {
88
- const base = {
89
- eventId: randomUUID(),
90
- sessionId,
91
- turnId,
92
- createdAt: new Date().toISOString(),
93
- type,
94
- payload,
95
- };
96
- const result = this.db
97
- .prepare("INSERT INTO events(session_id,body) VALUES(?,?)")
98
- .run(sessionId, "{}");
99
- const event = {
100
- ...base,
101
- tenantId: this.tenantId,
102
- cursor: Buffer.from(`${sessionId}:${result.lastInsertRowid}`).toString("base64url"),
103
- };
104
- this.db
105
- .prepare("UPDATE events SET body=? WHERE sequence=?")
106
- .run(JSON.stringify(event), result.lastInsertRowid);
107
- return event;
108
- }
109
- credentialCount() {
110
- const row = this.db
111
- .prepare("SELECT COUNT(*) AS n FROM vault_credentials")
112
- .get();
113
- return Number(row.n);
114
- }
115
- /** `agent` keeps only events of one agent used as a tool, by delegationId or path. */
116
- history(sessionId, cursor, agent) {
117
- let sequence = 0;
118
- if (cursor) {
119
- const decoded = Buffer.from(cursor, "base64url").toString();
120
- const prefix = `${sessionId}:`;
121
- if (!decoded.startsWith(prefix) ||
122
- !/^\d+$/.test(decoded.slice(prefix.length)))
123
- throw new Error("Invalid cursor");
124
- sequence = Number(decoded.slice(prefix.length));
125
- }
126
- const items = this.db
127
- .prepare("SELECT body FROM events WHERE session_id=? AND sequence>? ORDER BY sequence")
128
- .all(sessionId, sequence)
129
- .map((r) => JSON.parse(String(r.body)))
130
- .filter((event) => agent === undefined || belongsTo(event, agent));
131
- const last = this.db
132
- .prepare("SELECT body FROM events WHERE session_id=? ORDER BY sequence DESC LIMIT 1")
133
- .get(sessionId);
134
- return {
135
- items,
136
- cursor: last ? JSON.parse(String(last.body)).cursor : null,
137
- };
138
- }
139
- }
140
- function belongsTo(event, agent) {
141
- const ref = event.payload?.agent;
142
- return ref?.delegationId === agent || ref?.path === agent;
143
- }
@@ -1,24 +0,0 @@
1
- import { type LifecycleContext } from "./lifecycle.js";
2
- import { type OutputSink } from "./output.js";
3
- export declare const launcherUsage = "Usage: nylorun-runtime [--home <dir>] [--json] <command>\n\nCommands:\n version also --version\n up [--port <n>] [--allow-downgrade]\n down [--wait [--timeout <s>]] [--force]\n restart [--port <n>] [--allow-downgrade] [--wait | --force]\n run [--port <n>] [--allow-downgrade]\n status\n logs [--lines <n>] [--follow] [--tenant <id> | --all]";
4
- export interface LauncherRuntimeOptions {
5
- home: string;
6
- platform: NodeJS.Platform;
7
- /** Node running this launcher (`process.execPath`); the Host runs on it. */
8
- nodeBinary: string;
9
- /** `process.versions.node`; the launcher refuses Node older than 24. */
10
- nodeVersion: string;
11
- sink: OutputSink;
12
- /** Allowlisted ambient baseline from main.ts. */
13
- baselineEnv: Readonly<Record<string, string | undefined>>;
14
- fetchImpl?: typeof fetch;
15
- /** Abort signal for logs --follow (tests). */
16
- signal?: AbortSignal;
17
- /** Optional lifecycle overrides for tests. */
18
- lifecycle?: Partial<Pick<LifecycleContext, "spawnHost" | "onSignal" | "lock" | "fetchImpl" | "hostEntry" | "runtimeVersion" | "tenantSchemaMax">>;
19
- }
20
- /**
21
- * Run launcher commands. Returns a process exit code (0, 1, or 2).
22
- * Ambient values must already be resolved into `options`.
23
- */
24
- export declare function runLauncher(argv: readonly string[], options: LauncherRuntimeOptions): Promise<number>;