@@ -3,7 +3,9 @@ package agent
33import (
44 "context"
55 "encoding/json"
6+ "fmt"
67 "io"
8+ "strings"
79 "sync"
810)
911
@@ -29,3 +31,66 @@ func (l *JSONLogger) LogTurn(ctx context.Context, event TurnEvent) {
2931 defer l .mu .Unlock ()
3032 _ , _ = l .w .Write (append (data , '\n' ))
3133}
34+
35+ type TerminalLogger struct {
36+ mu sync.Mutex
37+ w io.Writer
38+ color bool
39+ }
40+
41+ func NewTerminalLogger (w io.Writer , color bool ) * TerminalLogger {
42+ return & TerminalLogger {w : w , color : color }
43+ }
44+
45+ func (l * TerminalLogger ) LogTurn (ctx context.Context , event TurnEvent ) {
46+ if l == nil || l .w == nil {
47+ return
48+ }
49+
50+ line := terminalTurnLine (event )
51+ if l .color {
52+ line = colorizeTurnLine (event , line )
53+ }
54+
55+ l .mu .Lock ()
56+ defer l .mu .Unlock ()
57+ _ , _ = fmt .Fprintln (l .w , line )
58+ }
59+
60+ func terminalTurnLine (event TurnEvent ) string {
61+ parts := []string {
62+ fmt .Sprintf ("turn %s" , event .FinishReason ),
63+ fmt .Sprintf ("duration=%s" , event .Duration ),
64+ fmt .Sprintf ("iterations=%d" , event .Iterations ),
65+ }
66+ if event .InputTokens > 0 || event .OutputTokens > 0 {
67+ parts = append (parts , fmt .Sprintf ("tokens=%d/%d" , event .InputTokens , event .OutputTokens ))
68+ }
69+ if event .CacheReadTokens > 0 || event .CacheWriteTokens > 0 {
70+ parts = append (parts , fmt .Sprintf ("cache=%d/%d" , event .CacheReadTokens , event .CacheWriteTokens ))
71+ }
72+ if event .ReasoningTokens > 0 {
73+ parts = append (parts , fmt .Sprintf ("reasoning=%d" , event .ReasoningTokens ))
74+ }
75+ if len (event .Tools ) > 0 {
76+ parts = append (parts , "tools=" + strings .Join (event .Tools , "," ))
77+ }
78+ if event .Truncated {
79+ parts = append (parts , "truncated=true" )
80+ }
81+ if event .Error != "" {
82+ parts = append (parts , "error=" + event .Error )
83+ }
84+ return strings .Join (parts , " " )
85+ }
86+
87+ func colorizeTurnLine (event TurnEvent , line string ) string {
88+ switch event .FinishReason {
89+ case "stop" :
90+ return "\x1b [32m" + line + "\x1b [0m"
91+ case "error" , "max_iterations" :
92+ return "\x1b [31m" + line + "\x1b [0m"
93+ default :
94+ return "\x1b [36m" + line + "\x1b [0m"
95+ }
96+ }
0 commit comments