@foldrun/core 7.0.2 → 8.0.0
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/dist/src/mail.js +1 -1
- package/dist/src/notify.js +1 -1
- package/dist/src/platform.d.ts +9 -0
- package/dist/src/platform.js +1 -0
- package/dist/src/run-container.js +7 -6
- package/dist/src/store.d.ts +13 -0
- package/package.json +1 -1
- package/src/mail.ts +1 -1
- package/src/notify.ts +1 -1
- package/src/platform.ts +10 -0
- package/src/run-container.ts +7 -6
- package/src/store.ts +14 -0
package/dist/src/mail.js
CHANGED
|
@@ -197,7 +197,7 @@ export async function mailWanted(tenant, email, category, workspace = null) {
|
|
|
197
197
|
// on dev let anyone send ~86k invites a day from hello@foldrun.io).
|
|
198
198
|
const UNCAPPED = new Set(["security", "billing", "account"]);
|
|
199
199
|
const PLATFORM_MAX_RECIPIENTS = 10;
|
|
200
|
-
const platformDayCap = (category) => Number(
|
|
200
|
+
const platformDayCap = (category) => Number(platform.setting(category === "invites" ? "FOLDRUN_PLATFORM_INVITES_PER_DAY" : "FOLDRUN_PLATFORM_MAIL_PER_DAY")) ||
|
|
201
201
|
(category === "invites" ? 25 : 200);
|
|
202
202
|
const platformSent = new Map();
|
|
203
203
|
/** Recipients this account may still send to today on the platform's key. */
|
package/dist/src/notify.js
CHANGED
|
@@ -58,7 +58,7 @@ export function platformMail(tenant) {
|
|
|
58
58
|
return own;
|
|
59
59
|
const key = process.env.FOLDRUN_RESEND_API_KEY;
|
|
60
60
|
if (key)
|
|
61
|
-
return { key, from:
|
|
61
|
+
return { key, from: platform.setting("FOLDRUN_EMAIL_FROM") || "foldrun <hello@foldrun.io>" };
|
|
62
62
|
return own;
|
|
63
63
|
}
|
|
64
64
|
/** The account's own Resend key and sender, or null when it has none. */
|
package/dist/src/platform.d.ts
CHANGED
|
@@ -142,6 +142,15 @@ export interface PlatformHooks {
|
|
|
142
142
|
* operator's accounts do so; every customer brings their own API key.
|
|
143
143
|
* Default: yes — a laptop or a self-hosted install is its own operator. */
|
|
144
144
|
platformKeyAllowed(tenant: string): boolean;
|
|
145
|
+
/**
|
|
146
|
+
* An operator setting, by the environment variable that used to hold it
|
|
147
|
+
* (30 Oct 2026): the platform answers with the operator's value where one
|
|
148
|
+
* is set (its settings store) and the variable otherwise, spelled as the
|
|
149
|
+
* variable would be. Read where core reads FOLDRUN_EMAIL_FROM, the
|
|
150
|
+
* platform mail caps and the step sizes. Default: the variable itself —
|
|
151
|
+
* a laptop or the CLI reads its environment as before.
|
|
152
|
+
*/
|
|
153
|
+
setting(env: string): string | undefined;
|
|
145
154
|
/**
|
|
146
155
|
* Where the platform's built-in tools sit on disk, materialised at boot —
|
|
147
156
|
* a shelf every account reads, beneath its own library. A name found in
|
package/dist/src/platform.js
CHANGED
|
@@ -42,6 +42,7 @@ const local = {
|
|
|
42
42
|
workspaceChanged() { },
|
|
43
43
|
sandboxResumable: () => false,
|
|
44
44
|
platformKeyAllowed: () => true,
|
|
45
|
+
setting: (env) => process.env[env],
|
|
45
46
|
galleryDir: () => null,
|
|
46
47
|
noteOAuthRefresh: async () => undefined,
|
|
47
48
|
fetchUntrusted: Object.assign((url, init) => fetch(url, init), { [LAPTOP_FETCH]: true }),
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
// The runner image bundles @foldrun/core itself, so the driver runs the same
|
|
19
19
|
// executeStep the server would — one implementation, two homes.
|
|
20
20
|
import { isHookRecord } from "./hooks.js";
|
|
21
|
+
import { platform } from "./platform.js";
|
|
21
22
|
import fs from "node:fs";
|
|
22
23
|
import os from "node:os";
|
|
23
24
|
import path from "node:path";
|
|
@@ -1451,8 +1452,8 @@ export function k8sMemory(value) {
|
|
|
1451
1452
|
export function sizeLimits(size) {
|
|
1452
1453
|
if (size === "small") {
|
|
1453
1454
|
return {
|
|
1454
|
-
cpus:
|
|
1455
|
-
memory:
|
|
1455
|
+
cpus: platform.setting("FOLDRUN_RUNNER_CPUS_SMALL") ?? "1",
|
|
1456
|
+
memory: platform.setting("FOLDRUN_RUNNER_MEMORY_SMALL") ?? "1Gi",
|
|
1456
1457
|
};
|
|
1457
1458
|
}
|
|
1458
1459
|
if (size === "heavy") {
|
|
@@ -1462,13 +1463,13 @@ export function sizeLimits(size) {
|
|
|
1462
1463
|
// cpus figure is both the rate its seconds are priced at and, since
|
|
1463
1464
|
// 26 Oct 2026, the cores the sandbox is capped at.
|
|
1464
1465
|
return {
|
|
1465
|
-
cpus:
|
|
1466
|
-
memory:
|
|
1466
|
+
cpus: platform.setting("FOLDRUN_RUNNER_CPUS_HEAVY") ?? "4",
|
|
1467
|
+
memory: platform.setting("FOLDRUN_RUNNER_MEMORY_HEAVY") ?? "8Gi",
|
|
1467
1468
|
};
|
|
1468
1469
|
}
|
|
1469
1470
|
return {
|
|
1470
|
-
cpus:
|
|
1471
|
-
memory:
|
|
1471
|
+
cpus: platform.setting("FOLDRUN_RUNNER_CPUS") ?? "2",
|
|
1472
|
+
memory: platform.setting("FOLDRUN_RUNNER_MEMORY") ?? "2g",
|
|
1472
1473
|
};
|
|
1473
1474
|
}
|
|
1474
1475
|
/**
|
package/dist/src/store.d.ts
CHANGED
|
@@ -1397,6 +1397,13 @@ export interface StepRecord {
|
|
|
1397
1397
|
txBytes: number | null;
|
|
1398
1398
|
} | null;
|
|
1399
1399
|
}
|
|
1400
|
+
/** A run's prices as they stood when it was admitted: the operator
|
|
1401
|
+
* settings' version and the figures themselves, by name. */
|
|
1402
|
+
export interface PriceSnapshot {
|
|
1403
|
+
version: number;
|
|
1404
|
+
at: string;
|
|
1405
|
+
values: Record<string, number>;
|
|
1406
|
+
}
|
|
1400
1407
|
export interface RunRecord {
|
|
1401
1408
|
id: string;
|
|
1402
1409
|
flow: string;
|
|
@@ -1405,6 +1412,12 @@ export interface RunRecord {
|
|
|
1405
1412
|
status: "queued" | "running" | "awaiting-approval" | "completed" | "failed";
|
|
1406
1413
|
startedAt: string;
|
|
1407
1414
|
finishedAt: string | null;
|
|
1415
|
+
/** The prices the run was admitted under — the platform's run-start
|
|
1416
|
+
* snapshot of its operator settings (30 Oct 2026). Its settlement and
|
|
1417
|
+
* its `budget:` read these, never a price changed while it ran. Opaque
|
|
1418
|
+
* to core; absent on a laptop, and on runs from before snapshots (those
|
|
1419
|
+
* price at the live figures). */
|
|
1420
|
+
pricing?: PriceSnapshot | null;
|
|
1408
1421
|
/** Set when a worker parked this run at an approval gate and returned its
|
|
1409
1422
|
* slot to the queue. The approval API re-enqueues exactly when this is
|
|
1410
1423
|
* set — without the marker it would also re-enqueue runs whose starting
|
package/package.json
CHANGED
package/src/mail.ts
CHANGED
|
@@ -268,7 +268,7 @@ export async function mailWanted(tenant: string, email: string, category: MailCa
|
|
|
268
268
|
const UNCAPPED = new Set<string>(["security", "billing", "account"]);
|
|
269
269
|
const PLATFORM_MAX_RECIPIENTS = 10;
|
|
270
270
|
const platformDayCap = (category: string) =>
|
|
271
|
-
Number(
|
|
271
|
+
Number(platform.setting(category === "invites" ? "FOLDRUN_PLATFORM_INVITES_PER_DAY" : "FOLDRUN_PLATFORM_MAIL_PER_DAY")) ||
|
|
272
272
|
(category === "invites" ? 25 : 200);
|
|
273
273
|
const platformSent = new Map<string, number>();
|
|
274
274
|
|
package/src/notify.ts
CHANGED
|
@@ -58,7 +58,7 @@ export function platformMail(tenant: string): { key: string; from: string } | nu
|
|
|
58
58
|
const own = accountMail(tenant);
|
|
59
59
|
if (own && getSecret(tenant, "EMAIL_FROM")?.value?.trim()) return own;
|
|
60
60
|
const key = process.env.FOLDRUN_RESEND_API_KEY;
|
|
61
|
-
if (key) return { key, from:
|
|
61
|
+
if (key) return { key, from: platform.setting("FOLDRUN_EMAIL_FROM") || "foldrun <hello@foldrun.io>" };
|
|
62
62
|
return own;
|
|
63
63
|
}
|
|
64
64
|
|
package/src/platform.ts
CHANGED
|
@@ -149,6 +149,15 @@ export interface PlatformHooks {
|
|
|
149
149
|
* operator's accounts do so; every customer brings their own API key.
|
|
150
150
|
* Default: yes — a laptop or a self-hosted install is its own operator. */
|
|
151
151
|
platformKeyAllowed(tenant: string): boolean;
|
|
152
|
+
/**
|
|
153
|
+
* An operator setting, by the environment variable that used to hold it
|
|
154
|
+
* (30 Oct 2026): the platform answers with the operator's value where one
|
|
155
|
+
* is set (its settings store) and the variable otherwise, spelled as the
|
|
156
|
+
* variable would be. Read where core reads FOLDRUN_EMAIL_FROM, the
|
|
157
|
+
* platform mail caps and the step sizes. Default: the variable itself —
|
|
158
|
+
* a laptop or the CLI reads its environment as before.
|
|
159
|
+
*/
|
|
160
|
+
setting(env: string): string | undefined;
|
|
152
161
|
/**
|
|
153
162
|
* Where the platform's built-in tools sit on disk, materialised at boot —
|
|
154
163
|
* a shelf every account reads, beneath its own library. A name found in
|
|
@@ -250,6 +259,7 @@ const local: PlatformHooks = {
|
|
|
250
259
|
workspaceChanged() {},
|
|
251
260
|
sandboxResumable: () => false,
|
|
252
261
|
platformKeyAllowed: () => true,
|
|
262
|
+
setting: (env) => process.env[env],
|
|
253
263
|
galleryDir: () => null,
|
|
254
264
|
noteOAuthRefresh: async () => undefined,
|
|
255
265
|
fetchUntrusted: Object.assign((url: string, init?: RequestInit) => fetch(url, init), { [LAPTOP_FETCH]: true }),
|
package/src/run-container.ts
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
import type { RoomLevel } from "./store.ts";
|
|
22
22
|
import type { PeerInfo } from "./operator.ts";
|
|
23
23
|
import { isHookRecord, type HookRecord } from "./hooks.ts";
|
|
24
|
+
import { platform } from "./platform.ts";
|
|
24
25
|
import fs from "node:fs";
|
|
25
26
|
import os from "node:os";
|
|
26
27
|
import path from "node:path";
|
|
@@ -1730,8 +1731,8 @@ export function k8sMemory(value: string): string {
|
|
|
1730
1731
|
export function sizeLimits(size?: "small" | "large" | "heavy"): { cpus: string; memory: string } {
|
|
1731
1732
|
if (size === "small") {
|
|
1732
1733
|
return {
|
|
1733
|
-
cpus:
|
|
1734
|
-
memory:
|
|
1734
|
+
cpus: platform.setting("FOLDRUN_RUNNER_CPUS_SMALL") ?? "1",
|
|
1735
|
+
memory: platform.setting("FOLDRUN_RUNNER_MEMORY_SMALL") ?? "1Gi",
|
|
1735
1736
|
};
|
|
1736
1737
|
}
|
|
1737
1738
|
if (size === "heavy") {
|
|
@@ -1741,13 +1742,13 @@ export function sizeLimits(size?: "small" | "large" | "heavy"): { cpus: string;
|
|
|
1741
1742
|
// cpus figure is both the rate its seconds are priced at and, since
|
|
1742
1743
|
// 26 Oct 2026, the cores the sandbox is capped at.
|
|
1743
1744
|
return {
|
|
1744
|
-
cpus:
|
|
1745
|
-
memory:
|
|
1745
|
+
cpus: platform.setting("FOLDRUN_RUNNER_CPUS_HEAVY") ?? "4",
|
|
1746
|
+
memory: platform.setting("FOLDRUN_RUNNER_MEMORY_HEAVY") ?? "8Gi",
|
|
1746
1747
|
};
|
|
1747
1748
|
}
|
|
1748
1749
|
return {
|
|
1749
|
-
cpus:
|
|
1750
|
-
memory:
|
|
1750
|
+
cpus: platform.setting("FOLDRUN_RUNNER_CPUS") ?? "2",
|
|
1751
|
+
memory: platform.setting("FOLDRUN_RUNNER_MEMORY") ?? "2g",
|
|
1751
1752
|
};
|
|
1752
1753
|
}
|
|
1753
1754
|
|
package/src/store.ts
CHANGED
|
@@ -3674,6 +3674,14 @@ export interface StepRecord {
|
|
|
3674
3674
|
} | null;
|
|
3675
3675
|
}
|
|
3676
3676
|
|
|
3677
|
+
/** A run's prices as they stood when it was admitted: the operator
|
|
3678
|
+
* settings' version and the figures themselves, by name. */
|
|
3679
|
+
export interface PriceSnapshot {
|
|
3680
|
+
version: number;
|
|
3681
|
+
at: string;
|
|
3682
|
+
values: Record<string, number>;
|
|
3683
|
+
}
|
|
3684
|
+
|
|
3677
3685
|
export interface RunRecord {
|
|
3678
3686
|
id: string;
|
|
3679
3687
|
flow: string; // flow name, or "adhoc:<agent>" for direct agent runs
|
|
@@ -3682,6 +3690,12 @@ export interface RunRecord {
|
|
|
3682
3690
|
status: "queued" | "running" | "awaiting-approval" | "completed" | "failed";
|
|
3683
3691
|
startedAt: string;
|
|
3684
3692
|
finishedAt: string | null;
|
|
3693
|
+
/** The prices the run was admitted under — the platform's run-start
|
|
3694
|
+
* snapshot of its operator settings (30 Oct 2026). Its settlement and
|
|
3695
|
+
* its `budget:` read these, never a price changed while it ran. Opaque
|
|
3696
|
+
* to core; absent on a laptop, and on runs from before snapshots (those
|
|
3697
|
+
* price at the live figures). */
|
|
3698
|
+
pricing?: PriceSnapshot | null;
|
|
3685
3699
|
/** Set when a worker parked this run at an approval gate and returned its
|
|
3686
3700
|
* slot to the queue. The approval API re-enqueues exactly when this is
|
|
3687
3701
|
* set — without the marker it would also re-enqueue runs whose starting
|