@@ -4,16 +4,33 @@ import (
44 "fmt"
55 "log/slog"
66 "os"
7+ // "path/filepath"
8+ "encoding/json"
9+ "runtime"
710 "runtime/debug"
11+ "sync"
812 "time"
913)
1014
15+func getCaller() string {
16+ var caller string
17+ if _, file, line, ok := runtime.Caller(2); ok {
18+ // caller = fmt.Sprintf("%s:%d", filepath.Base(file), line)
19+ caller = fmt.Sprintf("%s:%d", file, line)
20+ } else {
21+ caller = "unknown"
22+ }
23+ return caller
24+}
1125func Info(msg string, args ...any) {
12− slog.Info(msg, args...)
26+ source := getCaller()
27+ slog.Info(msg, append([]any{"source", source}, args...)...)
1328}
1429
1530func Debug(msg string, args ...any) {
16− slog.Debug(msg, args...)
31+ // slog.Debug(msg, args...)
32+ source := getCaller()
33+ slog.Debug(msg, append([]any{"source", source}, args...)...)
1734}
1835
1936func Warn(msg string, args ...any) {
@@ -76,3 +93,115 @@ func RecoverPanic(name string, cleanup func()) {
7693 }
7794 }
7895}
96+
97+// Message Logging for Debug
98+var MessageDir string
99+
100+func GetSessionPrefix(sessionId string) string {
101+ return sessionId[:8]
102+}
103+
104+var sessionLogMutex sync.Mutex
105+
106+func AppendToSessionLogFile(sessionId string, filename string, content string) string {
107+ if MessageDir == "" || sessionId == "" {
108+ return ""
109+ }
110+ sessionPrefix := GetSessionPrefix(sessionId)
111+
112+ sessionLogMutex.Lock()
113+ defer sessionLogMutex.Unlock()
114+
115+ sessionPath := fmt.Sprintf("%s/%s", MessageDir, sessionPrefix)
116+ if _, err := os.Stat(sessionPath); os.IsNotExist(err) {
117+ if err := os.MkdirAll(sessionPath, 0o766); err != nil {
118+ Error("Failed to create session directory", "dirpath", sessionPath, "error", err)
119+ return ""
120+ }
121+ }
122+
123+ filePath := fmt.Sprintf("%s/%s", sessionPath, filename)
124+
125+ f, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
126+ if err != nil {
127+ Error("Failed to open session log file", "filepath", filePath, "error", err)
128+ return ""
129+ }
130+ defer f.Close()
131+
132+ // Append chunk to file
133+ _, err = f.WriteString(content)
134+ if err != nil {
135+ Error("Failed to write chunk to session log file", "filepath", filePath, "error", err)
136+ return ""
137+ }
138+ return filePath
139+}
140+
141+func WriteRequestMessageJson(sessionId string, requestSeqId int, message any) string {
142+ if MessageDir == "" || sessionId == "" || requestSeqId <= 0 {
143+ return ""
144+ }
145+ msgJson, err := json.Marshal(message)
146+ if err != nil {
147+ Error("Failed to marshal message", "session_id", sessionId, "request_seq_id", requestSeqId, "error", err)
148+ return ""
149+ }
150+ return WriteRequestMessage(sessionId, requestSeqId, string(msgJson))
151+}
152+
153+func WriteRequestMessage(sessionId string, requestSeqId int, message string) string {
154+ if MessageDir == "" || sessionId == "" || requestSeqId <= 0 {
155+ return ""
156+ }
157+ filename := fmt.Sprintf("%d_request.json", requestSeqId)
158+
159+ return AppendToSessionLogFile(sessionId, filename, message)
160+}
161+
162+func AppendToStreamSessionLogJson(sessionId string, requestSeqId int, jsonableChunk any) string {
163+ if MessageDir == "" || sessionId == "" || requestSeqId <= 0 {
164+ return ""
165+ }
166+ chunkJson, err := json.Marshal(jsonableChunk)
167+ if err != nil {
168+ Error("Failed to marshal message", "session_id", sessionId, "request_seq_id", requestSeqId, "error", err)
169+ return ""
170+ }
171+ return AppendToStreamSessionLog(sessionId, requestSeqId, string(chunkJson))
172+}
173+
174+func AppendToStreamSessionLog(sessionId string, requestSeqId int, chunk string) string {
175+ if MessageDir == "" || sessionId == "" || requestSeqId <= 0 {
176+ return ""
177+ }
178+ filename := fmt.Sprintf("%d_response_stream.log", requestSeqId)
179+ return AppendToSessionLogFile(sessionId, filename, chunk)
180+}
181+
182+func WriteChatResponseJson(sessionId string, requestSeqId int, response any) string {
183+ if MessageDir == "" || sessionId == "" || requestSeqId <= 0 {
184+ return ""
185+ }
186+ responseJson, err := json.Marshal(response)
187+ if err != nil {
188+ Error("Failed to marshal response", "session_id", sessionId, "request_seq_id", requestSeqId, "error", err)
189+ return ""
190+ }
191+ filename := fmt.Sprintf("%d_response.json", requestSeqId)
192+
193+ return AppendToSessionLogFile(sessionId, filename, string(responseJson))
194+}
195+
196+func WriteToolResultsJson(sessionId string, requestSeqId int, toolResults any) string {
197+ if MessageDir == "" || sessionId == "" || requestSeqId <= 0 {
198+ return ""
199+ }
200+ toolResultsJson, err := json.Marshal(toolResults)
201+ if err != nil {
202+ Error("Failed to marshal tool results", "session_id", sessionId, "request_seq_id", requestSeqId, "error", err)
203+ return ""
204+ }
205+ filename := fmt.Sprintf("%d_tool_results.json", requestSeqId)
206+ return AppendToSessionLogFile(sessionId, filename, string(toolResultsJson))
207+}