@runuai/host 0.9.92 → 0.9.94
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/lib/browser-testing.ts +11 -2
- package/lib/machine-provider-aws.ts +14 -4
- package/package.json +1 -1
package/lib/browser-testing.ts
CHANGED
|
@@ -941,6 +941,15 @@ console.log(
|
|
|
941
941
|
* lockfile and PIDFILES — never pgrep: a pgrep -f guard sharing a cmdline
|
|
942
942
|
* with its own payload self-matches and skips the start (this exact bug
|
|
943
943
|
* kept the stack down in every container until 2026-07-08).
|
|
944
|
+
*
|
|
945
|
+
* The pidfile tracks the LOOP SHELL, not the port. When a loop is orphaned
|
|
946
|
+
* — the display owner changes, or two ensures race, and the single pidfile
|
|
947
|
+
* only remembers the latest — the previous loop's websockify keeps holding
|
|
948
|
+
* 6080, and SO_REUSEADDR lets the new one bind alongside it. The kernel
|
|
949
|
+
* then round-robins connections across both, so the viewer lands on a live
|
|
950
|
+
* proxy only SOMETIMES and reconnects the rest (live 2026-09-02). So the
|
|
951
|
+
* start branch — reached only when the tracked loop is already dead — first
|
|
952
|
+
* reaps anything still holding the port, guaranteeing exactly one listener.
|
|
944
953
|
*/
|
|
945
954
|
const VIEWER_STEPS: string[] = [
|
|
946
955
|
// Xvfb — one-shot; the X lockfile is the truth (also set when an agent
|
|
@@ -949,9 +958,9 @@ const VIEWER_STEPS: string[] = [
|
|
|
949
958
|
`[ -x /usr/bin/Xvfb ] || exit 0; [ -e ${X_LOCK} ] || /usr/bin/nohup /usr/bin/${XVFB_CMD} >>/tmp/uai-xvfb.log 2>&1 &`,
|
|
950
959
|
// x11vnc under a restart loop (it exits whenever the X server isn't up
|
|
951
960
|
// yet). Pidfile-guarded.
|
|
952
|
-
`[ -x /usr/bin/x11vnc ] || exit 0; [ -f /tmp/uai-x11vnc.pid ] && /usr/bin/kill -0 "$(/usr/bin/cat /tmp/uai-x11vnc.pid)" 2>/dev/null && exit 0; /usr/bin/nohup /bin/sh -c 'echo $$ > /tmp/uai-x11vnc.pid; while true; do /usr/bin/x11vnc -display ${SERVER_DISPLAY} -forever -shared -nopw -quiet >>/tmp/uai-x11vnc.log 2>&1; /bin/sleep 2; done' >/dev/null 2>&1 &`,
|
|
961
|
+
`[ -x /usr/bin/x11vnc ] || exit 0; [ -f /tmp/uai-x11vnc.pid ] && /usr/bin/kill -0 "$(/usr/bin/cat /tmp/uai-x11vnc.pid)" 2>/dev/null && exit 0; /usr/bin/pkill -f 'x11vnc -display' 2>/dev/null; /usr/bin/nohup /bin/sh -c 'echo $$ > /tmp/uai-x11vnc.pid; while true; do /usr/bin/x11vnc -display ${SERVER_DISPLAY} -forever -shared -nopw -quiet >>/tmp/uai-x11vnc.log 2>&1; /bin/sleep 2; done' >/dev/null 2>&1 &`,
|
|
953
962
|
// websockify/noVNC under the same pattern.
|
|
954
|
-
`[ -x /usr/bin/websockify ] || exit 0; [ -f /tmp/uai-novnc.pid ] && /usr/bin/kill -0 "$(/usr/bin/cat /tmp/uai-novnc.pid)" 2>/dev/null && exit 0; /usr/bin/nohup /bin/sh -c 'echo $$ > /tmp/uai-novnc.pid; while true; do /usr/bin/websockify --web=/usr/share/novnc 0.0.0.0:6080 localhost:5900 >>/tmp/uai-websockify.log 2>&1; /bin/sleep 2; done' >/dev/null 2>&1 &`,
|
|
963
|
+
`[ -x /usr/bin/websockify ] || exit 0; [ -f /tmp/uai-novnc.pid ] && /usr/bin/kill -0 "$(/usr/bin/cat /tmp/uai-novnc.pid)" 2>/dev/null && exit 0; /usr/bin/pkill -f 'websockify.*6080' 2>/dev/null; /usr/bin/nohup /bin/sh -c 'echo $$ > /tmp/uai-novnc.pid; while true; do /usr/bin/websockify --web=/usr/share/novnc 0.0.0.0:6080 localhost:5900 >>/tmp/uai-websockify.log 2>&1; /bin/sleep 2; done' >/dev/null 2>&1 &`,
|
|
955
964
|
];
|
|
956
965
|
|
|
957
966
|
const DEFAULT_NODE_BIN =
|
|
@@ -101,11 +101,18 @@ export function awsMachineName(taskId: string): string {
|
|
|
101
101
|
return `uai-machine-${taskId.toLowerCase()}`;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
/** Smallest Graviton type satisfying both dimensions.
|
|
104
|
+
/** Smallest Graviton type satisfying both dimensions.
|
|
105
|
+
*
|
|
106
|
+
* FLOORS AT 16GiB (owner decision 2026-08-31, priced at $0.25/machine-up
|
|
107
|
+
* hour): an 8GiB machine thrashed to death twice in one day under the
|
|
108
|
+
* ordinary heavy shape — a 5-agent crew + Turbopack dev server + editor +
|
|
109
|
+
* VNC browser — and a memory wall reads as "the product is broken", which
|
|
110
|
+
* costs more than the larger instance. m7g (sustained) over t4g (burstable)
|
|
111
|
+
* deliberately: compile bursts on a drained CPU-credit balance are the same
|
|
112
|
+
* wall wearing a different mask. The floor is AWS-only — local VM sizing
|
|
113
|
+
* has its own constraints and keeps the spec-driven path. */
|
|
105
114
|
export function defaultInstanceType(spec: MachineSpec): string {
|
|
106
115
|
const ladder: Array<[string, number, number]> = [
|
|
107
|
-
["m7g.medium", 1, 4096],
|
|
108
|
-
["m7g.large", 2, 8192],
|
|
109
116
|
["m7g.xlarge", 4, 16384],
|
|
110
117
|
["m7g.2xlarge", 8, 32768],
|
|
111
118
|
["m7g.4xlarge", 16, 65536],
|
|
@@ -142,7 +149,10 @@ export function awsUserData(authorizedPublicKey: string): string {
|
|
|
142
149
|
// real machine task; the HOSTS got their swapfile in 0.9.85, the
|
|
143
150
|
// machines never did). Best-effort: a machine without fallocate still
|
|
144
151
|
// boots.
|
|
145
|
-
|
|
152
|
+
// 16G (owner decision 2026-08-31): the graceful-degradation floor has to
|
|
153
|
+
// absorb the whole heavy shape, not soften its first half — 4G filled
|
|
154
|
+
// and the wall moved instead of vanishing. Disk is already paid for.
|
|
155
|
+
"(fallocate -l 16G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile && echo '/swapfile none swap sw 0 0' >> /etc/fstab) || true",
|
|
146
156
|
// The task OWNS its machine (ADR-121 — per-customer kernel isolation is
|
|
147
157
|
// the whole point); denying sudo just breaks project setups that
|
|
148
158
|
// container tasks handle fine (live 2026-08-31: a Hightop machine task
|