diff options
| author | Jeff Carr <[email protected]> | 2025-08-21 12:30:36 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-08-21 12:30:36 -0500 |
| commit | b221e7a95cc27c8b0b17c7322bea02b88888e033 (patch) | |
| tree | bde6b41a56167d9f5352e61459c9d7ba4a0e6496 /format_rich_log.go | |
| parent | e655b37e60a19cbdd1aeddbff0494d74b6a9c5d9 (diff) | |
add ConfigSave()
Diffstat (limited to 'format_rich_log.go')
| -rw-r--r-- | format_rich_log.go | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/format_rich_log.go b/format_rich_log.go new file mode 100644 index 0000000..ddf75bf --- /dev/null +++ b/format_rich_log.go @@ -0,0 +1,112 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "go.wit.com/lib/protobuf/chatpb" + "go.wit.com/log" +) + +const termWidth = 120 // The target width for the formatted output boxes. + +func formatRichLog(filename string) *chatpb.Chats { + data, err := os.ReadFile(filename) + if err != nil { + log.Fatalf("Error reading file %s: %v", filename, err) + } + + logData, err := chatpb.UnmarshalChatsTEXT(data) + if err != nil { + log.Fatalf("Error unmarshaling log file %s: %v", filename, err) + } + + for _, chat := range logData.GetChats() { + author := chat.GetFrom().String() + + // Handle content: prefer content_file, fallback to content. + var content string + if contentFile := chat.GetContentFile(); contentFile != "" { + // Construct the full path relative to the log file's directory. + logDir := filepath.Dir(filename) + contentPath := filepath.Join(logDir, contentFile) + + contentBytes, err := os.ReadFile(contentPath) + if err != nil { + content = fmt.Sprintf("--- ERROR: Could not read content file %s: %v ---", contentPath, err) + } else { + content = string(contentBytes) + } + } else { + // Fallback for older log formats. + content = chat.GetContent() + } + + // Print the conversational content first. + if content != "" { + // Trim trailing newlines for cleaner output. + fmt.Printf("✦ %s: %s\n", author, strings.TrimSpace(content)) + } + + // Now, format and print any tool calls. + for _, toolCall := range chat.GetToolCalls() { + printToolCallBox(toolCall) + } + } + + return logData +} + +// printToolCallBox handles the decorative formatting for a single tool call. +func printToolCallBox(tc *chatpb.ToolCall) { + boxWidth := termWidth - 2 // Account for the side borders. + + // --- Top Border --- + fmt.Printf(" ╭%s╮\n", strings.Repeat("─", boxWidth)) + + // --- Header Line --- + header := fmt.Sprintf(" ✔ %s %s (%s)", tc.GetName(), tc.GetInput(), tc.GetDescription()) + printWrappedLine(header, boxWidth) + printEmptyLine(boxWidth) + + // --- Stdout --- + if stdout := tc.GetOutputStdout(); stdout != "" { + for _, line := range strings.Split(stdout, "\n") { + printWrappedLine(" "+line, boxWidth) + } + } + + // --- Stderr --- + if stderr := tc.GetOutputStderr(); stderr != "" { + for _, line := range strings.Split(stderr, "\n") { + printWrappedLine(" "+line, boxWidth) + } + } + + printEmptyLine(boxWidth) + + // --- Bottom Border --- + fmt.Printf(" ╰%s╯\n", strings.Repeat("─", boxWidth)) +} + +// printWrappedLine prints a line of text, wrapping it if it's too long. +func printWrappedLine(text string, width int) { + if len(text) == 0 { + printEmptyLine(width) + return + } + + // Simple wrapping logic. + for len(text) > width { + fmt.Printf(" │ %-*s │\n", width, text[:width]) + text = text[width:] + } + fmt.Printf(" │ %-*s │\n", width, text) +} + +// printEmptyLine prints a blank line within the box. +func printEmptyLine(width int) { + fmt.Printf(" │ %*s │\n", width, "") +} |
