Skip to content

Commit 475af7f

Browse files
committed
Fixed python PATh issue in autonomous
1 parent ec9b491 commit 475af7f

2 files changed

Lines changed: 125 additions & 3 deletions

File tree

internal/agentic/autonomous.go

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,34 @@ func (c *AutonomousCreator) doSetup() (string, error) {
159159
}
160160

161161
func (c *AutonomousCreator) doDependencies() (string, error) {
162+
// Detect Python binary if this is a Python project
163+
pythonBinary := detectPythonBinary()
164+
165+
// Build platform-appropriate examples
166+
var pythonExample string
167+
if runtime.GOOS == "windows" {
168+
if pythonBinary != "" {
169+
pythonExample = fmt.Sprintf("Example for Python: %s -m venv venv && venv\\Scripts\\activate && pip install fastapi uvicorn", pythonBinary)
170+
} else {
171+
pythonExample = "Example for Python: python -m venv venv && venv\\Scripts\\activate && pip install fastapi uvicorn"
172+
}
173+
} else {
174+
if pythonBinary != "" {
175+
pythonExample = fmt.Sprintf("Example for Python: %s -m venv venv && source venv/bin/activate && pip install fastapi uvicorn", pythonBinary)
176+
} else {
177+
pythonExample = "Example for Python: python3 -m venv venv && source venv/bin/activate && pip install fastapi uvicorn"
178+
}
179+
}
180+
162181
// Ask AI for the specific setup shell commands required.
163182
prompt := fmt.Sprintf(`Given the implementation plan:
164183
%s
165184
166185
What are the precise terminal commands to initialize the project dependencies?
167-
Return ONLY a bash script with the commands. No markdown formatting, no explanations. Just the raw commands.
186+
Return ONLY a script with the commands. No markdown formatting, no explanations. Just the raw commands.
168187
Example for Go: go mod init my-app && go mod tidy
169-
Example for Python: python3 -m venv venv && source venv/bin/activate && pip install fastapi uvicorn
170-
Assume we are already inside the project directory.`, c.Plan)
188+
%s
189+
Assume we are already inside the project directory.`, c.Plan, pythonExample)
171190

172191
cmdsStr, err := aicall(c.AIClient, c.Model, prompt)
173192
if err != nil {
@@ -179,6 +198,11 @@ Assume we are already inside the project directory.`, c.Plan)
179198
cmdsStr = strings.TrimSpace(strings.TrimPrefix(cmdsStr, "```"))
180199

181200
if cmdsStr != "" {
201+
// On Windows, convert Unix-style commands to Windows-compatible ones
202+
if runtime.GOOS == "windows" {
203+
cmdsStr = convertToWindowsCommands(cmdsStr, pythonBinary)
204+
}
205+
182206
// Prepare a shell script to execute
183207
scriptPath := filepath.Join(c.ProjectDir, "setup.sh")
184208
if runtime.GOOS == "windows" {
@@ -949,3 +973,41 @@ func (c *AutonomousCreator) attemptTestFix(projectType, testCmd, output string,
949973
// For other errors, just report and abort
950974
return "", fmt.Errorf("automated test failed: %v\nOutput: %s\n\nAborting autonomous creation.", testErr, output)
951975
}
976+
977+
// detectPythonBinary tries to find the correct Python binary on the system
978+
// Returns "python" or "python3" depending on what's available, or empty string if neither found
979+
func detectPythonBinary() string {
980+
// Try python first (common on Windows)
981+
if _, err := exec.LookPath("python"); err == nil {
982+
return "python"
983+
}
984+
985+
// Try python3 (common on Linux/Mac)
986+
if _, err := exec.LookPath("python3"); err == nil {
987+
return "python3"
988+
}
989+
990+
return ""
991+
}
992+
993+
// convertToWindowsCommands converts Unix-style shell commands to Windows batch commands
994+
func convertToWindowsCommands(cmds, pythonBinary string) string {
995+
// Replace python3 with detected binary or fallback to python
996+
if pythonBinary != "" {
997+
cmds = strings.ReplaceAll(cmds, "python3", pythonBinary)
998+
} else {
999+
cmds = strings.ReplaceAll(cmds, "python3", "python")
1000+
}
1001+
1002+
// Replace Unix venv activation with Windows activation
1003+
cmds = strings.ReplaceAll(cmds, "source venv/bin/activate", "venv\\Scripts\\activate")
1004+
cmds = strings.ReplaceAll(cmds, "source venv\\bin\\activate", "venv\\Scripts\\activate")
1005+
1006+
// Replace Unix path separators in venv paths
1007+
cmds = strings.ReplaceAll(cmds, "venv/bin/", "venv\\Scripts\\")
1008+
1009+
// Replace && with & for Windows batch (though && also works in cmd)
1010+
// Actually, && works fine in Windows batch, so we can leave it
1011+
1012+
return cmds
1013+
}

internal/agentic/autonomous_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,63 @@ func TestExtractProjectName(t *testing.T) {
366366
})
367367
}
368368
}
369+
370+
func TestDetectPythonBinary(t *testing.T) {
371+
// This test just verifies the function runs without error
372+
// The actual result depends on the system's Python installation
373+
binary := detectPythonBinary()
374+
375+
// Should return either "python", "python3", or empty string
376+
if binary != "" && binary != "python" && binary != "python3" {
377+
t.Errorf("detectPythonBinary returned unexpected value: %s", binary)
378+
}
379+
}
380+
381+
func TestConvertToWindowsCommands(t *testing.T) {
382+
tests := []struct {
383+
name string
384+
input string
385+
pythonBinary string
386+
expectedOutput string
387+
}{
388+
{
389+
name: "Replace python3 with detected binary",
390+
input: "python3 -m venv venv && source venv/bin/activate && pip install requests",
391+
pythonBinary: "python",
392+
expectedOutput: "python -m venv venv && venv\\Scripts\\activate && pip install requests",
393+
},
394+
{
395+
name: "Replace python3 with python when no binary detected",
396+
input: "python3 -m venv venv && source venv/bin/activate",
397+
pythonBinary: "",
398+
expectedOutput: "python -m venv venv && venv\\Scripts\\activate",
399+
},
400+
{
401+
name: "Replace Unix venv paths with Windows paths",
402+
input: "source venv/bin/activate && venv/bin/pip install flask",
403+
pythonBinary: "python",
404+
expectedOutput: "venv\\Scripts\\activate && venv\\Scripts\\pip install flask",
405+
},
406+
{
407+
name: "Handle backslash paths",
408+
input: "source venv\\bin\\activate",
409+
pythonBinary: "python",
410+
expectedOutput: "venv\\Scripts\\activate",
411+
},
412+
{
413+
name: "No changes needed for Go commands",
414+
input: "go mod init my-app && go mod tidy",
415+
pythonBinary: "",
416+
expectedOutput: "go mod init my-app && go mod tidy",
417+
},
418+
}
419+
420+
for _, tt := range tests {
421+
t.Run(tt.name, func(t *testing.T) {
422+
result := convertToWindowsCommands(tt.input, tt.pythonBinary)
423+
if result != tt.expectedOutput {
424+
t.Errorf("convertToWindowsCommands() = %q, want %q", result, tt.expectedOutput)
425+
}
426+
})
427+
}
428+
}

0 commit comments

Comments
 (0)