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
34 changes: 17 additions & 17 deletions openhands/wrapper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,20 @@ func cmdSetup() {
}
}

// 2. Run openhands login.
fmt.Fprintln(os.Stderr, "Starting OpenHands CLI login...")
fmt.Fprintln(os.Stderr, "If a browser window does not open, copy the URL from the output below.")
// 2. OpenHands requires interactive initial setup (API key, model config)
// before --headless mode works. The TUI doesn't render in a subprocess,
// so instruct the user to configure in a separate terminal.
fmt.Fprintln(os.Stderr, "OpenHands CLI found at:", openhandsPath)
fmt.Fprintln(os.Stderr)

cmd := exec.Command(openhandsPath, "login")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = os.Environ()

if err := cmd.Run(); err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
os.Exit(exitErr.ExitCode())
}
os.Exit(1)
}
fmt.Fprintln(os.Stderr, "To configure OpenHands, open a new terminal and run:")
fmt.Fprintln(os.Stderr)
fmt.Fprintln(os.Stderr, " openhands")
fmt.Fprintln(os.Stderr)
fmt.Fprintln(os.Stderr, "Complete the initial setup (API key, model selection), then exit.")
fmt.Fprintln(os.Stderr)
fmt.Fprint(os.Stderr, "Press Enter here when done...")
buf := make([]byte, 1)
os.Stdin.Read(buf)
}

// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -289,7 +286,10 @@ func cmdBuild(args []string) {
}

// Model via env var (OpenHands has no -m flag)
env := map[string]string{}
// TTY_INTERACTIVE suppresses Rich's non-interactive terminal warning.
env := map[string]string{
"TTY_INTERACTIVE": "1",
}
if model, ok := config["model"].(string); ok && model != "" {
env["LLM_MODEL"] = model
cmd = append(cmd, "--override-with-envs")
Expand Down
25 changes: 20 additions & 5 deletions openhands/wrapper/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,16 @@ func TestCmdBuild_MinimalArgs(t *testing.T) {
t.Error("instructions.md should not be created when no prompts given")
}

// No env key when no model
if _, ok := result["env"]; ok {
t.Error("env should not be present when no model configured")
// env should contain TTY_INTERACTIVE but not LLM_MODEL
envMap, ok := result["env"].(map[string]interface{})
if !ok {
t.Fatal("env should be present (TTY_INTERACTIVE)")
}
if envMap["TTY_INTERACTIVE"] != "1" {
t.Error("TTY_INTERACTIVE should be set to 1")
}
if _, hasModel := envMap["LLM_MODEL"]; hasModel {
t.Error("LLM_MODEL should not be present when no model configured")
}
}

Expand Down Expand Up @@ -191,8 +198,16 @@ func TestCmdBuild_NoModelNoEnv(t *testing.T) {
var result map[string]interface{}
json.Unmarshal(output, &result)

if _, ok := result["env"]; ok {
t.Error("env should not be present when no model configured")
// env should contain TTY_INTERACTIVE but not LLM_MODEL
envMap, ok := result["env"].(map[string]interface{})
if !ok {
t.Fatal("env should be present (TTY_INTERACTIVE)")
}
if envMap["TTY_INTERACTIVE"] != "1" {
t.Error("TTY_INTERACTIVE should be set to 1")
}
if _, hasModel := envMap["LLM_MODEL"]; hasModel {
t.Error("LLM_MODEL should not be present when no model configured")
}

cmd := result["cmd"].([]interface{})
Expand Down
Loading