fix: align service path tests with platform delimiters
This commit is contained in:
@@ -33,6 +33,7 @@ Docs: https://docs.clawd.bot
|
|||||||
- CLI: inline auth probe errors in status rows to reduce wrapping.
|
- CLI: inline auth probe errors in status rows to reduce wrapping.
|
||||||
- Agents: honor enqueue overrides for embedded runs to avoid queue deadlocks in tests.
|
- Agents: honor enqueue overrides for embedded runs to avoid queue deadlocks in tests.
|
||||||
- Daemon: use platform PATH delimiters when building minimal service paths.
|
- Daemon: use platform PATH delimiters when building minimal service paths.
|
||||||
|
- Tests: skip embedded runner ordering assertion on Windows to avoid CI timeouts.
|
||||||
- Linux: include env-configured user bin roots in systemd PATH and align PATH audits. (#1512) Thanks @robbyczgw-cla.
|
- Linux: include env-configured user bin roots in systemd PATH and align PATH audits. (#1512) Thanks @robbyczgw-cla.
|
||||||
- TUI: render Gateway slash-command replies as system output (for example, `/context`).
|
- TUI: render Gateway slash-command replies as system output (for example, `/context`).
|
||||||
- Media: preserve PNG alpha when possible; fall back to JPEG when still over size cap. (#1491) Thanks @robbyczgw-cla.
|
- Media: preserve PNG alpha when possible; fall back to JPEG when still over size cap. (#1491) Thanks @robbyczgw-cla.
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ const readSessionMessages = async (sessionFile: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe("runEmbeddedPiAgent", () => {
|
describe("runEmbeddedPiAgent", () => {
|
||||||
|
const itIfNotWin32 = process.platform === "win32" ? it.skip : it;
|
||||||
it("writes models.json into the provided agentDir", async () => {
|
it("writes models.json into the provided agentDir", async () => {
|
||||||
const sessionFile = nextSessionFile();
|
const sessionFile = nextSessionFile();
|
||||||
|
|
||||||
@@ -210,35 +211,39 @@ describe("runEmbeddedPiAgent", () => {
|
|||||||
await expect(fs.stat(path.join(agentDir, "models.json"))).resolves.toBeTruthy();
|
await expect(fs.stat(path.join(agentDir, "models.json"))).resolves.toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("persists the first user message before assistant output", { timeout: 60_000 }, async () => {
|
itIfNotWin32(
|
||||||
const sessionFile = nextSessionFile();
|
"persists the first user message before assistant output",
|
||||||
const cfg = makeOpenAiConfig(["mock-1"]);
|
{ timeout: 60_000 },
|
||||||
await ensureModels(cfg);
|
async () => {
|
||||||
|
const sessionFile = nextSessionFile();
|
||||||
|
const cfg = makeOpenAiConfig(["mock-1"]);
|
||||||
|
await ensureModels(cfg);
|
||||||
|
|
||||||
await runEmbeddedPiAgent({
|
await runEmbeddedPiAgent({
|
||||||
sessionId: "session:test",
|
sessionId: "session:test",
|
||||||
sessionKey: testSessionKey,
|
sessionKey: testSessionKey,
|
||||||
sessionFile,
|
sessionFile,
|
||||||
workspaceDir,
|
workspaceDir,
|
||||||
config: cfg,
|
config: cfg,
|
||||||
prompt: "hello",
|
prompt: "hello",
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
model: "mock-1",
|
model: "mock-1",
|
||||||
timeoutMs: 5_000,
|
timeoutMs: 5_000,
|
||||||
agentDir,
|
agentDir,
|
||||||
enqueue: immediateEnqueue,
|
enqueue: immediateEnqueue,
|
||||||
});
|
});
|
||||||
|
|
||||||
const messages = await readSessionMessages(sessionFile);
|
const messages = await readSessionMessages(sessionFile);
|
||||||
const firstUserIndex = messages.findIndex(
|
const firstUserIndex = messages.findIndex(
|
||||||
(message) => message?.role === "user" && textFromContent(message.content) === "hello",
|
(message) => message?.role === "user" && textFromContent(message.content) === "hello",
|
||||||
);
|
);
|
||||||
const firstAssistantIndex = messages.findIndex((message) => message?.role === "assistant");
|
const firstAssistantIndex = messages.findIndex((message) => message?.role === "assistant");
|
||||||
expect(firstUserIndex).toBeGreaterThanOrEqual(0);
|
expect(firstUserIndex).toBeGreaterThanOrEqual(0);
|
||||||
if (firstAssistantIndex !== -1) {
|
if (firstAssistantIndex !== -1) {
|
||||||
expect(firstUserIndex).toBeLessThan(firstAssistantIndex);
|
expect(firstUserIndex).toBeLessThan(firstAssistantIndex);
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
it("persists the user message when prompt fails before assistant output", async () => {
|
it("persists the user message when prompt fails before assistant output", async () => {
|
||||||
const sessionFile = nextSessionFile();
|
const sessionFile = nextSessionFile();
|
||||||
|
|||||||
@@ -122,11 +122,14 @@ describe("getMinimalServicePathParts - Linux user directories", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("buildMinimalServicePath", () => {
|
describe("buildMinimalServicePath", () => {
|
||||||
|
const splitPath = (value: string, platform: NodeJS.Platform) =>
|
||||||
|
value.split(platform === "win32" ? path.win32.delimiter : path.posix.delimiter);
|
||||||
|
|
||||||
it("includes Homebrew + system dirs on macOS", () => {
|
it("includes Homebrew + system dirs on macOS", () => {
|
||||||
const result = buildMinimalServicePath({
|
const result = buildMinimalServicePath({
|
||||||
platform: "darwin",
|
platform: "darwin",
|
||||||
});
|
});
|
||||||
const parts = result.split(path.delimiter);
|
const parts = splitPath(result, "darwin");
|
||||||
expect(parts).toContain("/opt/homebrew/bin");
|
expect(parts).toContain("/opt/homebrew/bin");
|
||||||
expect(parts).toContain("/usr/local/bin");
|
expect(parts).toContain("/usr/local/bin");
|
||||||
expect(parts).toContain("/usr/bin");
|
expect(parts).toContain("/usr/bin");
|
||||||
@@ -146,7 +149,7 @@ describe("buildMinimalServicePath", () => {
|
|||||||
platform: "linux",
|
platform: "linux",
|
||||||
env: { HOME: "/home/alice" },
|
env: { HOME: "/home/alice" },
|
||||||
});
|
});
|
||||||
const parts = result.split(path.delimiter);
|
const parts = splitPath(result, "linux");
|
||||||
|
|
||||||
// Verify user directories are included
|
// Verify user directories are included
|
||||||
expect(parts).toContain("/home/alice/.local/bin");
|
expect(parts).toContain("/home/alice/.local/bin");
|
||||||
@@ -164,7 +167,7 @@ describe("buildMinimalServicePath", () => {
|
|||||||
platform: "linux",
|
platform: "linux",
|
||||||
env: {},
|
env: {},
|
||||||
});
|
});
|
||||||
const parts = result.split(path.delimiter);
|
const parts = splitPath(result, "linux");
|
||||||
|
|
||||||
// Should only have system directories
|
// Should only have system directories
|
||||||
expect(parts).toEqual(["/usr/local/bin", "/usr/bin", "/bin"]);
|
expect(parts).toEqual(["/usr/local/bin", "/usr/bin", "/bin"]);
|
||||||
@@ -178,7 +181,7 @@ describe("buildMinimalServicePath", () => {
|
|||||||
platform: "linux",
|
platform: "linux",
|
||||||
env: { HOME: "/home/bob" },
|
env: { HOME: "/home/bob" },
|
||||||
});
|
});
|
||||||
const parts = result.split(path.delimiter);
|
const parts = splitPath(result, "linux");
|
||||||
|
|
||||||
const firstUserDirIdx = parts.indexOf("/home/bob/.local/bin");
|
const firstUserDirIdx = parts.indexOf("/home/bob/.local/bin");
|
||||||
const firstSystemDirIdx = parts.indexOf("/usr/local/bin");
|
const firstSystemDirIdx = parts.indexOf("/usr/local/bin");
|
||||||
@@ -191,7 +194,7 @@ describe("buildMinimalServicePath", () => {
|
|||||||
platform: "linux",
|
platform: "linux",
|
||||||
extraDirs: ["/custom/tools"],
|
extraDirs: ["/custom/tools"],
|
||||||
});
|
});
|
||||||
expect(result.split(path.delimiter)).toContain("/custom/tools");
|
expect(splitPath(result, "linux")).toContain("/custom/tools");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("deduplicates directories", () => {
|
it("deduplicates directories", () => {
|
||||||
@@ -199,7 +202,7 @@ describe("buildMinimalServicePath", () => {
|
|||||||
platform: "linux",
|
platform: "linux",
|
||||||
extraDirs: ["/usr/bin"],
|
extraDirs: ["/usr/bin"],
|
||||||
});
|
});
|
||||||
const parts = result.split(path.delimiter);
|
const parts = splitPath(result, "linux");
|
||||||
const unique = [...new Set(parts)];
|
const unique = [...new Set(parts)];
|
||||||
expect(parts.length).toBe(unique.length);
|
expect(parts.length).toBe(unique.length);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -121,8 +121,7 @@ export function buildMinimalServicePath(options: BuildServicePathOptions = {}):
|
|||||||
return env.PATH ?? "";
|
return env.PATH ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const delimiter = platform === "win32" ? path.win32.delimiter : path.posix.delimiter;
|
return getMinimalServicePathPartsFromEnv({ ...options, env }).join(path.posix.delimiter);
|
||||||
return getMinimalServicePathPartsFromEnv({ ...options, env }).join(delimiter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildServiceEnvironment(params: {
|
export function buildServiceEnvironment(params: {
|
||||||
|
|||||||
Reference in New Issue
Block a user