Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion agents/langchain-deepagents-code/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ prepare_runtime_env
# phase, which breaks the Docker GPU-patch supervisor reconnect and leaves GPU
# posture unreliable (#5717). Idle forever instead so the sandbox stays Ready.
if [ "$#" -eq 0 ]; then
exec sleep infinity
printf '%s\n' 'Setting up NemoClaw Deep Agents Code runtime...'
exec tail -f /dev/null
fi

exec "$@"
2 changes: 1 addition & 1 deletion src/lib/onboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3064,10 +3064,10 @@ async function createSandbox(
dockerGpuCreatePatch.maybeApplyDuringCreate();
return false;
},
readyCheckOutputPatterns: agentDefs.isTerminalAgent(agent) ? [] : undefined,
failureCheck: dockerGpuCreatePatch.createFailureMessage,
traceEvent: onboardTracing.addTraceEvent,
});

if (initialSandboxPolicy.cleanup && initialSandboxPolicy.cleanup()) {
process.removeListener("exit", initialSandboxPolicy.cleanup);
}
Expand Down
1 change: 1 addition & 0 deletions test/dcode-start-keepalive.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ describe("Deep Agents Code sandbox entrypoint keep-alive (#5717)", () => {
// A self-exiting entrypoint would return status 0 with no signal.
expect(result.signal).toBe("SIGTERM");
expect(result.status).toBeNull();
expect(result.stdout).toContain("Setting up NemoClaw Deep Agents Code runtime...");
});

it("execs an explicitly supplied command instead of idling", () => {
Expand Down
8 changes: 8 additions & 0 deletions test/langchain-deepagents-code-image.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ describe("LangChain Deep Agents Code image contracts", () => {
);
});

it("prints NemoClaw setup output before idling as a terminal runtime", () => {
const startScript = readAgentFile("start.sh");

expect(startScript).toContain("Setting up NemoClaw Deep Agents Code runtime");
expect(startScript).toContain("exec tail -f /dev/null");
expect(startScript).not.toContain("exec sleep infinity");
});

it("does not serialize provider or optional service secrets into the shell env file", () => {
const startScript = readAgentFile("start.sh");

Expand Down
13 changes: 11 additions & 2 deletions test/onboard-terminal-dashboard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ function writeExecutable(target: string, contents: string) {
}

function parseStdoutJson<T>(stdout: string): T {
const line = stdout.trim().split("\n").pop();
const line = stdout
.trim()
.split("\n")
.reverse()
.find((candidate) => candidate.startsWith("{") && candidate.endsWith("}"));
assert.ok(line, `expected JSON payload in stdout:\n${stdout}`);
return JSON.parse(line);
}
Expand Down Expand Up @@ -55,6 +59,7 @@ const sandboxName = "deepagents-box";
const commands = [];
const registerCalls = [];
const updateCalls = [];
const keepAlive = setInterval(() => {}, 1000);
const _n = (c) => (Array.isArray(c) ? c.join(" ") : String(c)).replace(/'/g, "");

agentOnboard.createAgentSandbox = () => {
Expand Down Expand Up @@ -104,11 +109,11 @@ childProcess.spawn = (...args) => {
child.stdout = new EventEmitter();
child.stderr = new EventEmitter();
child.unref = () => {};
child.kill = () => true;
child.pid = 4242;
commands.push({ command: _n([args[0], ...(Array.isArray(args[1]) ? args[1] : [])]), env: args[2]?.env || null });
process.nextTick(() => {
child.stdout.emit("data", Buffer.from("Created sandbox: " + sandboxName + "\n"));
child.emit("close", 0);
});
return child;
};
Expand All @@ -122,7 +127,9 @@ const agent = agentDefs.loadAgent("langchain-deepagents-code");
process.env.NEMOCLAW_DASHBOARD_PORT = "19000";
const resultName = await createSandbox(null, "gpt-5.4", "nvidia-prod", null, sandboxName, null, null, null, agent);
console.log(JSON.stringify({ resultName, commands, registerCalls, updateCalls }));
clearInterval(keepAlive);
})().catch((error) => {
clearInterval(keepAlive);
console.error(error);
process.exit(1);
});
Expand All @@ -137,7 +144,9 @@ const agent = agentDefs.loadAgent("langchain-deepagents-code");
HOME: tmpDir,
PATH: `${fakeBin}:${process.env.PATH || ""}`,
NEMOCLAW_NON_INTERACTIVE: "1",
OPENSHELL_DRIVERS: scenario === "create" ? "vm" : "docker",
},
timeout: 15000,
});
assert.equal(result.status, 0, result.stderr);
return parseStdoutJson<{
Expand Down