diff --git a/main.go b/main.go index f472f5f..91ab1b9 100644 --- a/main.go +++ b/main.go @@ -55,7 +55,7 @@ type commandResult struct { TimedOut bool } -const geminiTimeout = 5 * time.Minute +const cliTimeout = 5 * time.Minute var ( requestLogRoot = "/var/log/daiapi" @@ -67,6 +67,7 @@ func main() { mux.HandleFunc("/run", runCodexHandler) mux.HandleFunc("/runCodex", runCodexHandler) mux.HandleFunc("/runGemini", runGeminiHandler) + mux.HandleFunc("/runAgy", runAgyHandler) addr := ":8000" if port := os.Getenv("PORT"); port != "" { @@ -343,7 +344,7 @@ func runGeminiHandler(w http.ResponseWriter, r *http.Request) { return } - result := runCommand(r.Context(), geminiTimeout, "gemini", "-p", req.Prompt) + result := runCommand(r.Context(), cliTimeout, "gemini", "-p", req.Prompt) answer := result.Stdout resp := geminiResponse{ Success: result.Err == nil, @@ -352,7 +353,48 @@ func runGeminiHandler(w http.ResponseWriter, r *http.Request) { Stdout: result.Stdout, Stderr: result.Stderr, ExitCode: result.ExitCode, - Error: commandError(result), + Error: commandError("gemini", result), + } + + if result.Err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + + if encodeErr := json.NewEncoder(w).Encode(resp); encodeErr != nil { + http.Error(w, encodeErr.Error(), http.StatusInternalServerError) + } +} + +func runAgyHandler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + if r.Method != http.MethodPost { + writeAgyError(w, http.StatusMethodNotAllowed, "method not allowed") + return + } + + var req runRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + writeAgyError(w, http.StatusBadRequest, "invalid json body") + return + } + + prompt := strings.TrimSpace(req.Prompt) + if prompt == "" { + writeAgyError(w, http.StatusBadRequest, "prompt must not be empty") + return + } + + result := runCommand(r.Context(), cliTimeout, "agy", "-p", req.Prompt) + answer := result.Stdout + resp := geminiResponse{ + Success: result.Err == nil, + Answer: &answer, + Usage: nil, + Stdout: result.Stdout, + Stderr: result.Stderr, + ExitCode: result.ExitCode, + Error: commandError("agy", result), } if result.Err != nil { @@ -395,7 +437,7 @@ func runCommand(parent context.Context, timeout time.Duration, name string, args return result } -func commandError(result commandResult) string { +func commandError(commandName string, result commandResult) string { if result.TimedOut { return "process timed out" } @@ -403,17 +445,33 @@ func commandError(result commandResult) string { return "" } if errors.Is(result.Err, exec.ErrNotFound) { - return "gemini CLI not found in PATH" + return commandName + " CLI not found in PATH" } var execErr *exec.Error if errors.As(result.Err, &execErr) { - return "gemini CLI not found in PATH" + return commandName + " CLI not found in PATH" } return result.Err.Error() } +func writeAgyError(w http.ResponseWriter, status int, message string) { + w.WriteHeader(status) + resp := geminiResponse{ + Success: false, + Answer: nil, + Usage: nil, + Stdout: "", + Stderr: "", + ExitCode: -1, + Error: message, + } + if err := json.NewEncoder(w).Encode(resp); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + func writeGeminiError(w http.ResponseWriter, status int, message string) { w.WriteHeader(status) resp := geminiResponse{