@runuai/host 0.9.117 → 0.9.118
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 +7 -1
- package/lib/orchestrator.ts +20 -2
- package/package.json +1 -1
package/lib/browser-testing.ts
CHANGED
|
@@ -1048,8 +1048,14 @@ const DEFAULT_NODE_BIN =
|
|
|
1048
1048
|
`/opt/asdf-data/installs/nodejs/${STANDARD_DEFAULT_NODE_VERSION}/bin`;
|
|
1049
1049
|
const ROOT_RUNTIME_PATH =
|
|
1050
1050
|
`${DEFAULT_NODE_BIN}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`;
|
|
1051
|
+
// `npx` through ROOT_RUNTIME_PATH, not an absolute asdf path: the machine
|
|
1052
|
+
// image (ADR-121) carries no asdf — node is /usr/bin/node there — and the
|
|
1053
|
+
// absolute path made this worker exit 127 on every task machine, so its
|
|
1054
|
+
// done-marker was never written and each ensure re-ran it (live 2026-09-09).
|
|
1055
|
+
// The path lists the asdf bin first and never the shims, so a container
|
|
1056
|
+
// resolves exactly what it did before.
|
|
1051
1057
|
const APT_DEPS_CMD =
|
|
1052
|
-
`PATH=${ROOT_RUNTIME_PATH}
|
|
1058
|
+
`PATH=${ROOT_RUNTIME_PATH} npx ` +
|
|
1053
1059
|
"-y playwright@latest install-deps chromium";
|
|
1054
1060
|
const APT_VIEWER_CMD =
|
|
1055
1061
|
"/usr/bin/apt-get install -y --no-install-recommends xvfb x11vnc novnc websockify";
|
package/lib/orchestrator.ts
CHANGED
|
@@ -1595,6 +1595,15 @@ export class Orchestrator {
|
|
|
1595
1595
|
session: AgentSession,
|
|
1596
1596
|
): void {
|
|
1597
1597
|
channel.sessions.set(agentId, session);
|
|
1598
|
+
// The launch screen's `ready` rides the bind, not the tail of the start
|
|
1599
|
+
// loop: whichever path brings the last roster agent up — the initial
|
|
1600
|
+
// start, a reconcile that won the race with it, a respawn after Resume —
|
|
1601
|
+
// is the moment the task can take a message. Live 2026-09-09: `agents`
|
|
1602
|
+
// was stored, Jonah was up and idle, and no `ready` ever followed, so
|
|
1603
|
+
// the page stayed covered for minutes. Idempotent on the cloud side.
|
|
1604
|
+
if (channel.roster.every((agent) => channel.sessions.has(agent.id))) {
|
|
1605
|
+
this.emitTaskStage(channel.taskId, "ready");
|
|
1606
|
+
}
|
|
1598
1607
|
// Adapters may synchronously emit `error` followed by `turn_complete` (or
|
|
1599
1608
|
// `exit`). Terminal classification now awaits a daemon proof, so preserve
|
|
1600
1609
|
// transport emission order across that await; otherwise the later boundary
|
|
@@ -1966,7 +1975,15 @@ export class Orchestrator {
|
|
|
1966
1975
|
),
|
|
1967
1976
|
},
|
|
1968
1977
|
);
|
|
1969
|
-
if (!session)
|
|
1978
|
+
if (!session) {
|
|
1979
|
+
// The agents that did come up are usable; the reconcile pass keeps
|
|
1980
|
+
// retrying this one. Do not leave the page covered for a session
|
|
1981
|
+
// that may never bind — `ready` otherwise rides bindSession.
|
|
1982
|
+
if (channel.sessions.size > 0) {
|
|
1983
|
+
this.emitTaskStage(channel.taskId, "ready");
|
|
1984
|
+
}
|
|
1985
|
+
return false;
|
|
1986
|
+
}
|
|
1970
1987
|
this.startNextPendingPrompt(channel, agent.id);
|
|
1971
1988
|
} finally {
|
|
1972
1989
|
channel.spawning.delete(agent.id);
|
|
@@ -1980,7 +1997,8 @@ export class Orchestrator {
|
|
|
1980
1997
|
// so it both duplicated the opening turn AND re-injected it on a host
|
|
1981
1998
|
// restart, making agents redo the first turn mid-task. The persona/mission
|
|
1982
1999
|
// an agent needs live in the always-on system preamble, so nothing is lost.
|
|
1983
|
-
|
|
2000
|
+
// `ready` itself was emitted by bindSession as the last roster agent
|
|
2001
|
+
// bound (or above, when one could not).
|
|
1984
2002
|
return true;
|
|
1985
2003
|
}
|
|
1986
2004
|
|