parseAgentLog parses agent logs and generates a markdown summary
(runDir string, engine workflow.CodingAgentEngine, verbose bool)
| 27 | |
| 28 | // parseAgentLog parses agent logs and generates a markdown summary |
| 29 | func parseAgentLog(runDir string, engine workflow.CodingAgentEngine, verbose bool) error { |
| 30 | logsParsingJsLog.Printf("Parsing agent logs in: %s", runDir) |
| 31 | // Determine which parser script to use based on the engine |
| 32 | if engine == nil { |
| 33 | logsParsingJsLog.Print("No engine detected, skipping log parsing") |
| 34 | fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("No engine detected in %s, skipping log parsing", filepath.Base(runDir)))) |
| 35 | return nil |
| 36 | } |
| 37 | |
| 38 | // Find the agent log file - use engine.GetLogFileForParsing() to determine location |
| 39 | agentLogPath, found := findAgentLogFile(runDir, engine) |
| 40 | if !found { |
| 41 | logsParsingJsLog.Print("No agent log file found") |
| 42 | fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("No agent logs found in %s, skipping log parsing", filepath.Base(runDir)))) |
| 43 | return nil |
| 44 | } |
| 45 | |
| 46 | logsParsingJsLog.Printf("Found agent log file: %s", agentLogPath) |
| 47 | |
| 48 | parserScriptName := engine.GetLogParserScriptId() |
| 49 | if parserScriptName == "" { |
| 50 | fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("No log parser available for engine %s in %s, skipping", engine.GetID(), filepath.Base(runDir)))) |
| 51 | return nil |
| 52 | } |
| 53 | |
| 54 | jsScript := workflow.GetLogParserScript(parserScriptName) |
| 55 | if jsScript == "" { |
| 56 | if verbose { |
| 57 | fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Failed to get log parser script "+parserScriptName)) |
| 58 | } |
| 59 | return nil |
| 60 | } |
| 61 | |
| 62 | // Read the log content |
| 63 | logContent, err := os.ReadFile(agentLogPath) |
| 64 | if err != nil { |
| 65 | return fmt.Errorf("failed to read agent log file: %w", err) |
| 66 | } |
| 67 | |
| 68 | // Create a temporary directory for running the parser |
| 69 | tempDir, err := os.MkdirTemp("", "log_parser") |
| 70 | if err != nil { |
| 71 | return fmt.Errorf("failed to create temp dir: %w", err) |
| 72 | } |
| 73 | defer os.RemoveAll(tempDir) |
| 74 | |
| 75 | // Write the log content to a temporary file |
| 76 | logFile := filepath.Join(tempDir, "agent.log") |
| 77 | if err := os.WriteFile(logFile, logContent, constants.FilePermPublic); err != nil { |
| 78 | return fmt.Errorf("failed to write log file: %w", err) |
| 79 | } |
| 80 | |
| 81 | // Write the bootstrap helper to the temp directory |
| 82 | bootstrapScript := workflow.GetLogParserBootstrap() |
| 83 | if bootstrapScript != "" { |
| 84 | bootstrapFile := filepath.Join(tempDir, "log_parser_bootstrap.cjs") |
| 85 | if err := os.WriteFile(bootstrapFile, []byte(bootstrapScript), constants.FilePermPublic); err != nil { |
| 86 | return fmt.Errorf("failed to write bootstrap file: %w", err) |