1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
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 parseRichLog(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() {
// 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()
}
chat.Content = content
}
return logData
}
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, "")
}
|