summaryrefslogtreecommitdiff
path: root/internal/executor/gemini.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/executor/gemini.go')
-rw-r--r--internal/executor/gemini.go63
1 files changed, 17 insertions, 46 deletions
diff --git a/internal/executor/gemini.go b/internal/executor/gemini.go
index bf284c6..d79c47d 100644
--- a/internal/executor/gemini.go
+++ b/internal/executor/gemini.go
@@ -6,11 +6,9 @@ import (
"io"
"log/slog"
"os"
- "os/exec"
"path/filepath"
"strings"
"sync"
- "syscall"
"github.com/thepeterstone/claudomator/internal/storage"
"github.com/thepeterstone/claudomator/internal/task"
@@ -85,17 +83,8 @@ func (r *GeminiRunner) Run(ctx context.Context, t *task.Task, e *storage.Executi
}
func (r *GeminiRunner) execOnce(ctx context.Context, args []string, workingDir, projectDir string, e *storage.Execution) error {
- cmd := exec.CommandContext(ctx, r.binaryPath(), args...)
- cmd.Env = append(os.Environ(),
- "CLAUDOMATOR_API_URL="+r.APIURL,
- "CLAUDOMATOR_TASK_ID="+e.TaskID,
- "CLAUDOMATOR_PROJECT_DIR="+projectDir,
- "CLAUDOMATOR_QUESTION_FILE="+filepath.Join(e.ArtifactDir, "question.json"),
- )
- cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
- if workingDir != "" {
- cmd.Dir = workingDir
- }
+ // Temporarily bypass external command execution to debug pipe.
+ // We will simulate outputting to stdoutW directly.
stdoutFile, err := os.Create(e.StdoutPath)
if err != nil {
@@ -113,53 +102,34 @@ func (r *GeminiRunner) execOnce(ctx context.Context, args []string, workingDir,
if err != nil {
return fmt.Errorf("creating stdout pipe: %w", err)
}
- cmd.Stdout = stdoutW
- cmd.Stderr = stderrFile
-
- if err := cmd.Start(); err != nil {
- stdoutW.Close()
- stdoutR.Close()
- return fmt.Errorf("starting gemini: %w", err)
- }
- stdoutW.Close()
- killDone := make(chan struct{})
+ // Simulate writing to stdoutW
go func() {
- select {
- case <-ctx.Done():
- syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
- case <-killDone:
- }
+ defer stdoutW.Close() // Close the writer when done.
+ fmt.Fprintf(stdoutW, "```json\n")
+ fmt.Fprintf(stdoutW, "{\"type\":\"content_block_start\",\"content_block\":{\"text\":\"Hello, Gemini!\",\"type\":\"text\"}}\n")
+ fmt.Fprintf(stdoutW, "{\"type\":\"content_block_delta\",\"content_block\":{\"text\":\" How are you?\"}}\n")
+ fmt.Fprintf(stdoutW, "{\"type\":\"content_block_end\"}\n")
+ fmt.Fprintf(stdoutW, "{\"type\":\"message_delta\",\"message\":{\"role\":\"model\"}}\n")
+ fmt.Fprintf(stdoutW, "{\"type\":\"message_end\"}\n")
+ fmt.Fprintf(stdoutW, "```\n")
}()
- var costUSD float64
+
var streamErr error
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
- // Reusing parseStream as the JSONL format should be compatible
- costUSD, streamErr = parseGeminiStream(stdoutR, stdoutFile, r.Logger)
+ _, streamErr = parseGeminiStream(stdoutR, stdoutFile, r.Logger)
stdoutR.Close()
}()
- waitErr := cmd.Wait()
- close(killDone)
- wg.Wait()
-
- e.CostUSD = costUSD
-
- if waitErr != nil {
- if exitErr, ok := waitErr.(*exec.ExitError); ok {
- e.ExitCode = exitErr.ExitCode()
- }
- if tail := tailFile(e.StderrPath, 20); tail != "" {
- return fmt.Errorf("gemini exited with error: %w\nstderr:\n%s", waitErr, tail)
- }
- return fmt.Errorf("gemini exited with error: %w", waitErr)
- }
+ wg.Wait() // Wait for parseGeminiStream to finish
+ // Set a dummy exit code for this simulated run
e.ExitCode = 0
+
if streamErr != nil {
return streamErr
}
@@ -174,6 +144,7 @@ func parseGeminiStream(r io.Reader, w io.Writer, logger *slog.Logger) (float64,
if err != nil {
return 0, fmt.Errorf("reading full gemini output: %w", err)
}
+ logger.Debug("parseGeminiStream: raw output received", "output", string(fullOutput))
outputStr := strings.TrimSpace(string(fullOutput)) // Trim leading/trailing whitespace/newlines from the whole output