mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-10-07 16:08:23 +08:00
Improve missing agent-server setup guidance (#42)
Add actionable dev-safe output when agent-server is missing, including README and uv installation guidance, and update tests plus quickstart docs. Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
committed by
GitHub
co-authored by
openhands
parent
fbfd3015ab
commit
3b754b5703
@@ -31,6 +31,8 @@ If you do not already have the backend installed, install `uv` first (OpenHands
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
```
|
||||
|
||||
Need Windows or another install method? See the official uv installation guide: <https://docs.astral.sh/uv/getting-started/installation/>
|
||||
|
||||
Then install or upgrade the agent server package together with the tool/workspace dependencies it needs:
|
||||
|
||||
```sh
|
||||
|
||||
@@ -5,13 +5,38 @@ import process from "node:process";
|
||||
import { setTimeout as delay } from "node:timers/promises";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildSafeDevConfig } from "../../scripts/dev-safe.mjs";
|
||||
import {
|
||||
buildSafeDevConfig,
|
||||
formatMissingAgentServerGuidance,
|
||||
} from "../../scripts/dev-safe.mjs";
|
||||
|
||||
const repoRoot = path.resolve(
|
||||
path.dirname(fileURLToPath(import.meta.url)),
|
||||
"../..",
|
||||
);
|
||||
|
||||
|
||||
describe("formatMissingAgentServerGuidance", () => {
|
||||
it("includes install, PATH, README, and fallback workflow hints", () => {
|
||||
const guidance = formatMissingAgentServerGuidance(
|
||||
"/workspace/project/agent-server-gui",
|
||||
);
|
||||
|
||||
expect(guidance).toContain(
|
||||
"uv tool install -U --with openhands-tools --with openhands-workspace openhands-agent-server",
|
||||
);
|
||||
expect(guidance).toContain('export PATH="$HOME/.local/bin:$PATH"');
|
||||
expect(guidance).toContain(
|
||||
"/workspace/project/agent-server-gui/README.md",
|
||||
);
|
||||
expect(guidance).toContain(
|
||||
"https://docs.astral.sh/uv/getting-started/installation/",
|
||||
);
|
||||
expect(guidance).toContain("npm run dev:frontend");
|
||||
expect(guidance).toContain("npm run dev:mock");
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildSafeDevConfig", () => {
|
||||
it("builds isolated default paths and ports", () => {
|
||||
const cwd = "/workspace/project/agent-server-gui";
|
||||
@@ -89,6 +114,14 @@ describe("dev-safe CLI startup", () => {
|
||||
expect(exitResult.timedOut).toBe(false);
|
||||
expect(exitResult.code).toBe(1);
|
||||
expect(output).toContain("Failed to start agent-server");
|
||||
expect(output).toContain(
|
||||
"uv tool install -U --with openhands-tools --with openhands-workspace openhands-agent-server",
|
||||
);
|
||||
expect(output).toContain(
|
||||
"https://docs.astral.sh/uv/getting-started/installation/",
|
||||
);
|
||||
expect(output).toContain("README.md");
|
||||
expect(output).toContain("npm run dev:mock");
|
||||
expect(output).toContain("spawn agent-server ENOENT");
|
||||
});
|
||||
});
|
||||
|
||||
+33
-1
@@ -8,6 +8,36 @@ import { pathToFileURL } from "node:url";
|
||||
const DEFAULT_BACKEND_PORT = 18000;
|
||||
const DEFAULT_WAIT_TIMEOUT_MS = 30_000;
|
||||
|
||||
function isEnoentError(error) {
|
||||
return Boolean(
|
||||
(error && typeof error === "object" && "code" in error && error.code === "ENOENT") ||
|
||||
/ENOENT/.test(String(error)),
|
||||
);
|
||||
}
|
||||
|
||||
export function formatMissingAgentServerGuidance(cwd = process.cwd()) {
|
||||
const readmePath = path.join(cwd, "README.md");
|
||||
|
||||
return [
|
||||
"Failed to start agent-server. Make sure it is installed and on your PATH.",
|
||||
"",
|
||||
"To fix this:",
|
||||
"1. Install the backend CLI:",
|
||||
" uv tool install -U --with openhands-tools --with openhands-workspace openhands-agent-server",
|
||||
"2. Make sure the uv tool bin dir is on your PATH:",
|
||||
' export PATH="$HOME/.local/bin:$PATH"',
|
||||
" command -v agent-server",
|
||||
"",
|
||||
"Need Windows or another install method? https://docs.astral.sh/uv/getting-started/installation/",
|
||||
`See the local Quickstart for details: ${readmePath}`,
|
||||
"- README > Quickstart > 2. Install OpenHands Agent Server",
|
||||
"",
|
||||
"Other options:",
|
||||
"- npm run dev:frontend # use an already running backend",
|
||||
"- npm run dev:mock # run the frontend with mock APIs",
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
function parsePort(value, fallback) {
|
||||
if (value == null || value === "") {
|
||||
return fallback;
|
||||
@@ -66,7 +96,9 @@ function spawnProcess(command, args, options) {
|
||||
const child = spawn(command, args, { stdio: "inherit", ...options });
|
||||
|
||||
child.once("error", (error) => {
|
||||
if ((error && "code" in error && error.code === "ENOENT") || /ENOENT/.test(String(error))) {
|
||||
if (isEnoentError(error) && command === "agent-server") {
|
||||
console.error(formatMissingAgentServerGuidance(options?.cwd));
|
||||
} else if (isEnoentError(error)) {
|
||||
console.error(`Failed to start ${command}. Make sure it is installed and on your PATH.`);
|
||||
} else {
|
||||
console.error(`Failed to start ${command}:`, error);
|
||||
|
||||
Reference in New Issue
Block a user