fix(subagents): run bundled JS launcher via runtime on Windows (#975)

Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
Charles Packer
2026-02-16 01:11:41 -08:00
committed by GitHub
parent 1b8dab2040
commit 702e888300
4 changed files with 217 additions and 21 deletions

View File

@@ -1,5 +1,122 @@
import { describe, expect, test } from "bun:test";
import { resolveSubagentModel } from "../../agent/subagents/manager";
import {
resolveSubagentLauncher,
resolveSubagentModel,
} from "../../agent/subagents/manager";
describe("resolveSubagentLauncher", () => {
test("explicit launcher takes precedence over .ts script autodetection", () => {
const launcher = resolveSubagentLauncher(["-p", "hi"], {
env: {
LETTA_CODE_BIN: "custom-bun",
LETTA_CODE_BIN_ARGS_JSON: JSON.stringify(["run", "src/index.ts"]),
} as NodeJS.ProcessEnv,
argv: ["bun", "/tmp/dev-entry.ts"],
execPath: "/opt/homebrew/bin/bun",
platform: "darwin",
});
expect(launcher).toEqual({
command: "custom-bun",
args: ["run", "src/index.ts", "-p", "hi"],
});
});
test("explicit launcher takes precedence over .js script autodetection", () => {
const launcher = resolveSubagentLauncher(["-p", "hi"], {
env: {
LETTA_CODE_BIN: "custom-node",
} as NodeJS.ProcessEnv,
argv: ["node", "/tmp/letta.js"],
execPath: "/usr/local/bin/node",
platform: "win32",
});
expect(launcher).toEqual({
command: "custom-node",
args: ["-p", "hi"],
});
});
test("preserves existing .ts dev behavior for any ts entrypoint", () => {
const launcher = resolveSubagentLauncher(
["--output-format", "stream-json"],
{
env: {} as NodeJS.ProcessEnv,
argv: ["bun", "/tmp/custom-runner.ts"],
execPath: "/opt/homebrew/bin/bun",
platform: "darwin",
},
);
expect(launcher).toEqual({
command: "/opt/homebrew/bin/bun",
args: ["/tmp/custom-runner.ts", "--output-format", "stream-json"],
});
});
test("uses node runtime for bundled js on win32", () => {
const launcher = resolveSubagentLauncher(["-p", "prompt"], {
env: {} as NodeJS.ProcessEnv,
argv: ["node", "C:\\Program Files\\Letta\\letta.js"],
execPath: "C:\\Program Files\\nodejs\\node.exe",
platform: "win32",
});
expect(launcher).toEqual({
command: "C:\\Program Files\\nodejs\\node.exe",
args: ["C:\\Program Files\\Letta\\letta.js", "-p", "prompt"],
});
});
test("keeps direct js spawn behavior on non-win32", () => {
const launcher = resolveSubagentLauncher(["-p", "prompt"], {
env: {} as NodeJS.ProcessEnv,
argv: ["node", "/usr/local/lib/letta.js"],
execPath: "/usr/local/bin/node",
platform: "linux",
});
expect(launcher).toEqual({
command: "/usr/local/lib/letta.js",
args: ["-p", "prompt"],
});
});
test("falls back to global letta when no launcher hints available", () => {
const launcher = resolveSubagentLauncher(["-p", "prompt"], {
env: {} as NodeJS.ProcessEnv,
argv: ["node", ""],
execPath: "/usr/local/bin/node",
platform: "linux",
});
expect(launcher).toEqual({
command: "letta",
args: ["-p", "prompt"],
});
});
test("keeps explicit launcher with spaces as a single command token", () => {
const launcher = resolveSubagentLauncher(
["--output-format", "stream-json"],
{
env: {
LETTA_CODE_BIN:
'"C:\\Users\\Example User\\AppData\\Roaming\\npm\\letta.cmd"',
} as NodeJS.ProcessEnv,
argv: ["node", "C:\\Program Files\\Letta\\letta.js"],
execPath: "C:\\Program Files\\nodejs\\node.exe",
platform: "win32",
},
);
expect(launcher).toEqual({
command: "C:\\Users\\Example User\\AppData\\Roaming\\npm\\letta.cmd",
args: ["--output-format", "stream-json"],
});
});
});
describe("resolveSubagentModel", () => {
test("prefers BYOK-swapped handle when available", async () => {